{
  "openapi": "3.1.0",
  "info": {
    "title": "RezoSoft API",
    "description": "> ⚠️ **Activare modul**: Trebuie să activați acest modul de la **Configurare → Abonament RezoSoft** și apoi apăsați pe butonul \"Schimbă abonamentul\", și bifați și modulul de \"Acces API\".\n\n## Primii pași\n\n1. Activați modulul **Acces API** (vezi mai sus).\n2. Generați o cheie din **Setări → Integrări → Chei API**. Cheia se afișează o singură dată; păstrați-o pe server, niciodată în aplicații mobile sau în browser.\n3. Verificați conexiunea:\n\n```bash\ncurl https://api.rezosoft.ro/v2/external/connection -H \"x-api-key: CHEIA_DVS\"\n```\n\n4. Citiți ID-urile de care aveți nevoie: `GET /document-series/invoice` (seria), `GET /document-templates` (template-ul PDF), `GET /inventories` (gestiunea, dacă scădeți stoc).\n5. Emiteți o factură cu `POST /documents` și folosiți `pdf_url` din răspuns (sau `GET /documents/invoice/{id}/download-pdf`).\n\n```bash\ncurl -X POST https://api.rezosoft.ro/v2/external/documents \\\n  -H \"x-api-key: CHEIA_DVS\" -H \"Content-Type: application/json\" \\\n  -d '{\"document_type\":\"invoice\",\"document_series_id\":4,\"document_template_id\":1,\n       \"external_id\":\"COMANDA-1001\",\"idempotent\":true,\n       \"client\":{\"name\":\"Client Test SRL\",\"fiscal_code\":\"RO12345678\",\"country_code\":\"RO\"},\n       \"products\":[{\"name\":\"Serviciu\",\"quantity\":1,\"vat_percentage\":21,\"price_with_vat\":121}]}'\n```\n\nFiecare endpoint are exemple de cod generate automat (cURL, PHP, Node.js, Python și altele) în panoul din dreapta, de unde se poate și testa direct cu cheia dvs. Specificația OpenAPI (butonul **Descarcă specificația OpenAPI**) se poate importa în Postman / Insomnia sau într-un generator de clienți.\n\n**Pentru agenți AI / LLM:** [llms.txt](https://api.rezosoft.ro/llms.txt) (rezumat și reguli de implementare) și [llms-full.txt](https://api.rezosoft.ro/llms-full.txt) (toată documentația într-un singur fișier Markdown), generate din aceeași specificație.\n\n## Autentificare\n\nToate endpoint-urile necesită header-ul `x-api-key` cu o cheie API validă generată din **Setări → Integrări → Chei API**. O cheie lipsă sau greșită răspunde 401.\n\n## Limită de cereri\n\nMaximum **150 de cereri pe minut per adresă IP**, numărate pe toate endpoint-urile. Fiecare răspuns poartă `X-RateLimit-Limit` și `X-RateLimit-Remaining`. Peste limită răspunsul este **429** cu `Retry-After` (secunde) și `X-RateLimit-Reset`; așteptați cât indică `Retry-After` înainte de reîncercare. Pentru volume mari folosiți sincronizarea incrementală (mai jos) în locul citirii repetate a acelorași date.\n\n## Erori\n\n| Cod | Când | Corp |\n|-----|------|------|\n| 400 | Parametri invalizi (tip de document necunoscut, interval / cursor invalid) | `{\"status\": \"error\", \"message\": \"...\"}` |\n| 401 | Cheie API lipsă sau invalidă | `{\"status\": \"error\", \"message\": \"Unauthorized\"}` |\n| 403 | Utilizatorul cheii nu mai are acces la companie | `{\"status\": \"error\", \"message\": \"...\"}` |\n| 404 | Resursa nu există sau aparține altei companii | `{\"status\": \"error\", \"message\": \"...\"}` (`code: \"not_found\"` pe documente) |\n| 409 | Conflict: cerere cu același `external_id` deja în curs (`in_progress`, se reîncearcă identic) sau stare incompatibilă (`proform_converted`, `proform_inactive`, `invoice_inactive`) | `{\"status\": \"error\", \"code\": \"...\", \"message\": \"...\"}` |\n| 422 | Validare: `errors` are mesajele pe câmp; sau o regulă de business (`amount_too_high`, `currency_mismatch`, `generate_failed`, `no_bnr_rate`) | `{\"message\": \"...\", \"errors\": {\"camp\": [\"...\"]}}` sau `{\"status\": \"error\", \"code\": \"...\", \"message\": \"...\"}` |\n| 429 | Limita de cereri depășită | `{\"message\": \"Too Many Attempts.\"}` |\n| 5xx | Eroare internă; se poate reîncerca, de preferat cu `external_id` + `idempotent` | — |\n\nTratați `code` (când există) ca identificator stabil; `message` poate fi reformulat.\n\n## Reîncercări sigure (idempotență)\n\n`POST /documents` cu `external_id` și `\"idempotent\": true` emite documentul o singură dată: aceeași cerere trimisă din nou întoarce același `id`, `number` și `key`, cu `\"existing\": true`. Plățile pe factură (`POST /documents/invoice/{id}/payments`) și facturarea unei proforme (`POST /documents/proform/{id}/invoice`) sunt idempotente în același fel. Un 409 `in_progress` (o cerere cu același `external_id` încă rulează; a doua așteaptă până la 10 secunde înainte de a răspunde așa) sau o eroare de rețea se reîncearcă după câteva secunde cu exact aceeași cerere.\n\n## Facturi și e-Factura\n\nFacturile emise prin API se comportă ca cele emise din aplicație: dacă firma are activă trimiterea automată în e-Factura (Setări → e-Factura), factura se trimite la ANAF automat după întârzierea configurată (1–4 zile de la data facturii). Facturile către clienți din afara României nu se trimit. Data documentului este întotdeauna ziua curentă (ora României); nu se poate trimite altă dată. Pentru o comandă deja plătită trimiteți încasarea direct în `POST /documents` (`payment`), iar cu `update_stock` liniile legate de produse scad stocul (poate deveni negativ), cele fără produs găsit nu.\n\n## Sincronizare incrementală\n\nSe aplică endpoint-urilor `reports/pos/receipts`, `reports/pos/orders`, `reports/pos/cancelled-items`, `reports/pos/incomes`, `reports/pos/products`, `reports/pos/z` și `reports/stock/movements` (`updated_since` și pe `products`, `reports/pos/tables`, `recipes`).\n\n| Parametru | Descriere |\n|-----------|-----------|\n| `from`, `to` | Interval inclusiv, ora României (`Y-m-d H:i:s` sau ISO 8601). O dată fără oră înseamnă ziua întreagă (`to=2026-10-06` = până la 23:59:59). Au prioritate față de `period_from` / `period_to`. |\n| `day_start` | Doar `incomes` și `z`: ora la care începe ziua de activitate. `05:00` se aliniază cu datarea raportului Z. |\n| `after_id` | Cursor: rândurile cu `id > after_id`, crescător, `per_page` (max. 500) pe apel. Continuați cu `pagination.next_after_id` până devine `null`. |\n| `updated_since` | Rândurile modificate de la moment, inclusiv ștergerile (cu `deleted_at`). |\n\nFără interval explicit se folosește ziua de azi; cu `after_id` sau `updated_since` și fără `from`/`to`, nu se aplică niciun interval.\n\n**Rețeta recomandată:**\n\n1. Import inițial: parcurgeți tot istoricul cu `after_id` (pornind de la 0) până când `next_after_id` este `null`. Rețineți `server_time` din **primul** răspuns.\n2. Apoi, periodic: `updated_since=<server_time reținut>`, parcurs cu `after_id` / paginare; rețineți `server_time` din primul răspuns al rundei pentru runda următoare.\n3. Folosiți întotdeauna `server_time` (ceasul serverului), nu ceasul propriu: diferențele de oră ar pierde rânduri.\n4. Rândurile pot reapărea între runde; faceți upsert după `id`.\n\n**Limitări cunoscute:** starea de bucătărie este pe comandă, nu pe linie; modificările de cantitate și transferurile de masă nu sunt înregistrate de POS; închiderea de casă este pe terminal (raport Z), nu pe operator; liniile unei comenzi de bucătărie rămân disponibile 90 de zile după închiderea mesei; schimbarea ospătarului unei mese nu apare în `reports/pos/tables?updated_since` (citiți snapshot-ul complet); vânzările POS nu apar în mișcările de stoc (se citesc din `reports/pos/receipts`).\n\n## Versiuni\n\nVersiunea din antet urmează [SemVer](https://semver.org/lang/ro/): **major** = o schimbare care poate strica o integrare existentă (câmp sau endpoint eliminat ori redenumit, autentificare schimbată), **minor** = endpoint, parametru sau câmp nou, **patch** = doar corecturi ale documentației. Câmpurile noi pot apărea oricând în răspunsuri, deci ignorați câmpurile pe care nu le cunoașteți. Înainte de a fi eliminat, un câmp sau endpoint este marcat `deprecated` în această documentație și anunțat mai jos.\n\n## Istoric versiuni\n\n- **1.8.0** (2026-10-16) — Cod intern pe produse: câmpul `internal_code` în lista și detaliile produselor, acceptat la `POST /products`; căutarea din lista produselor îl include.\n- **1.7.0** (2026-10-07) — Evenimente webhook pentru produse: `product.created`, `product.updated`, `product.deleted`, `product.stock_changed`. Webhook-ul vechi `product-update` este marcat depreciat. Webhook-urile abonate la toate evenimentele (`*`) primesc și evenimentele de produs.\n- **1.6.0** (2026-10-07) — Webhook-uri semnate pentru POS: bonuri, comenzi de bucătărie, mese (`pos.*`), administrare prin `/webhooks` (creare, test, rotire secret, jurnal de livrări, retrimitere); o cheie restricționată vede și administrează doar webhook-urile limitate la gestiunile ei.\n- **1.5.2** (2026-10-07) — Documentat: trimiterea automată în e-Factura, stocul la emitere (linii fără produs, stoc negativ), încasarea la emitere pentru comenzi plătite, data documentului (azi) și durata unui 409 `in_progress`.\n- **1.5.1** (2026-10-07) — Versiuni pentru agenți AI: `llms.txt` și `llms-full.txt`, generate din specificație. Corectat: `vat_percentage` acceptă orice cotă a companiei (lista veche 19/9/5/0 era greșită); documentat comportamentul exact al reîncercării idempotente.\n- **1.5.0** (2026-10-07) — Documentate: detaliu document, modificare / anulare / facturare proformă, încasări pe factură. `POST /documents`: documentate `currency` și `idempotent`; `use_product_name_from_db` are implicit `true`. Documentate răspunsurile 409, 422 și 429; secțiuni noi: primii pași, limită de cereri, erori, idempotență, sincronizare incrementală. Documentația are o interfață nouă, cu exemple de cod generate pentru fiecare endpoint și testare directă; specificația se poate descărca din `openapi.json`.\n- **1.4.0** (2026-10-06) — POS: mese deschise (`reports/pos/tables`), istoric comenzi de bucătărie, linii anulate, câmpuri noi pe bonuri; mișcări de stoc, rețete; parametrii `from`, `to`, `day_start`, `after_id`, `updated_since`.\n- **1.3.0** (2026-08-27 – 09-02) — Creare produs și NIR, listare documente, e-Facturi primite.\n- **1.2.0** (2026-05-07) — Raport Z POS.\n- **1.1.0** (2026-04-27 – 04-29) — Note de recepție (listare, detaliu, PDF), rapoarte POS, plată la emiterea facturii. Câmpuri redenumite (ex. `vat_percent` → `vat_percentage` pe liniile bonurilor).\n- **1.0.0** (2026-02) — Conexiune, template-uri, serii, gestiuni, produse, emitere document, PDF, email, nomenclator județe / localități.\n\nVersiunile anterioare 1.5.0 au fost atribuite retroactiv, după istoricul modificărilor.",
    "version": "1.8.0",
    "contact": {
      "name": "RezoSoft",
      "url": "https://rezosoft.ro",
      "email": "contact@rezosoft.ro"
    }
  },
  "servers": [
    {
      "url": "https://api.rezosoft.ro/v2/external",
      "description": "Producție"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Conexiune",
      "description": "Test conexiune API"
    },
    {
      "name": "Resurse",
      "description": "Obținere resurse (template-uri, serii, gestiuni)"
    },
    {
      "name": "Produse",
      "description": "Interogare produse și stocuri"
    },
    {
      "name": "Documente",
      "description": "Creare și gestionare documente"
    },
    {
      "name": "Note de recepție (NIR)",
      "description": "Creare, listare, vizualizare și descărcare PDF pentru note de recepție (NIR)."
    },
    {
      "name": "e-Factura",
      "description": "Facturi primite prin SPV (e-Factura): listare, descărcare PDF și XML UBL."
    },
    {
      "name": "Rapoarte",
      "description": "Rapoarte POS (încasări, produse vândute, bonuri, raport Z, mese, comenzi, linii anulate), mișcări de stoc și rețete."
    },
    {
      "name": "Județe și localități",
      "description": "Județe și localități"
    },
    {
      "name": "Webhook-uri",
      "description": "Webhook-uri semnate pentru POS: RezoSoft trimite către URL-ul dvs. un eveniment (`pos.receipt.*`, `pos.order.*`, `pos.table.updated`, `product.*`) cu semnătură HMAC-SHA256, reîncercări automate și jurnal de livrări. Webhook-urile se administrează cu endpoint-urile `/webhooks` (creare, test, rotire secret, jurnal, retrimitere) sau din aplicație; evenimentele trimise sunt descrise mai jos.\n\n**Integrare veche:** webhook-ul de produs (`product-update`) trimite cereri cu header-ul `X-Security-Key` când se modifică un produs sau stocul. Rămâne disponibil pentru integrările existente (pluginul WooCommerce). Versiunea 1.5 a pluginului folosește webhook-urile semnate."
    }
  ],
  "paths": {
    "/connection": {
      "get": {
        "tags": [
          "Conexiune"
        ],
        "summary": "Test conexiune",
        "description": "Verifică validitatea cheii API",
        "operationId": "testConnection",
        "responses": {
          "200": {
            "description": "Conexiune reușită",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "message": {
                      "type": "string",
                      "example": "Connection successful"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/document-templates": {
      "get": {
        "tags": [
          "Resurse"
        ],
        "summary": "Lista template-uri documente",
        "description": "Returnează lista template-urilor de factură disponibile pentru companie",
        "operationId": "getDocumentTemplates",
        "responses": {
          "200": {
            "description": "Lista template-uri",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "templates": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DocumentTemplate"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/document-series/{documentType}": {
      "get": {
        "tags": [
          "Resurse"
        ],
        "summary": "Lista serii documente",
        "description": "Returnează seriile de documente pentru un anumit tip",
        "operationId": "getDocumentSeries",
        "parameters": [
          {
            "name": "documentType",
            "in": "path",
            "required": true,
            "description": "Tipul documentului",
            "schema": {
              "type": "string",
              "enum": [
                "invoice",
                "proform"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista serii",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "series": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DocumentSeries"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/inventories": {
      "get": {
        "tags": [
          "Resurse"
        ],
        "summary": "Lista gestiuni",
        "description": "Returnează gestiunile la care utilizatorul asociat cheii API are acces",
        "operationId": "getInventories",
        "responses": {
          "200": {
            "description": "Lista gestiuni",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "inventories": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Inventory"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/products": {
      "post": {
        "tags": [
          "Produse"
        ],
        "summary": "Creare produs",
        "description": "Creează un produs într-o gestiune. Câmpul `code` este folosit și drept cod de bare — dacă nu este trimis, este generat automat; trebuie să fie unic în gestiune. Prețul de vânzare poate fi trimis cu sau fără TVA, celălalt fiind calculat pe baza `vat_percent`. Produsul este sincronizat automat cu POS-urile companiei, la fel ca la crearea din aplicație.",
        "operationId": "createProduct",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProductRequest"
              },
              "example": {
                "inventory_id": 12,
                "name": "Produs Exemplu",
                "code": "5941234567890",
                "vat_percent": 21,
                "price_with_vat": 12.5,
                "unit": "buc",
                "type": "goods"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Produsul a fost creat",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "message": {
                      "type": "string",
                      "example": "Product created"
                    },
                    "product": {
                      "$ref": "#/components/schemas/ProductInfo"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "description": "Date invalide (ex: cod de produs deja existent în gestiune, cotă TVA inexistentă)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "error"
                    },
                    "message": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "object",
                      "description": "Erori de validare per câmp (opțional)"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "get": {
        "tags": [
          "Produse"
        ],
        "summary": "Lista produse",
        "description": "Returnează lista produselor dintr-o gestiune cu paginare și căutare opțională",
        "operationId": "getProducts",
        "parameters": [
          {
            "$ref": "#/components/parameters/UpdatedSince"
          },
          {
            "$ref": "#/components/parameters/CategoryId"
          },
          {
            "$ref": "#/components/parameters/DepartmentId"
          },
          {
            "name": "inventory_id",
            "in": "query",
            "required": true,
            "description": "ID-ul gestiunii",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "with_stock",
            "in": "query",
            "required": false,
            "description": "Trimite `true` pentru a include stocul curent",
            "schema": {
              "type": "string",
              "enum": [
                "true"
              ]
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Caută în numele, codul sau codul intern al produsului",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Numărul paginii",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "description": "Produse per pagină (maxim 1000)",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 1000
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista produse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "products": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ProductInfo"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/products/{value}": {
      "get": {
        "tags": [
          "Produse"
        ],
        "summary": "Detalii produs",
        "description": "Returnează informații despre un singur produs, căutat după ID sau cod (barcode)",
        "operationId": "getProduct",
        "parameters": [
          {
            "name": "value",
            "in": "path",
            "required": true,
            "description": "Valoarea de căutare (ID-ul sau codul produsului)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "field",
            "in": "query",
            "required": false,
            "description": "Câmpul de căutare",
            "schema": {
              "type": "string",
              "enum": [
                "id",
                "code"
              ],
              "default": "id"
            }
          },
          {
            "name": "with_stock",
            "in": "query",
            "required": false,
            "description": "Trimite `true` pentru a include stocul curent",
            "schema": {
              "type": "string",
              "enum": [
                "true"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Informații produs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "product": {
                      "$ref": "#/components/schemas/ProductInfo"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/documents": {
      "post": {
        "tags": [
          "Documente"
        ],
        "summary": "Creare document",
        "description": "Creează o factură sau o proformă",
        "operationId": "createDocument",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDocumentRequest"
              },
              "example": {
                "document_type": "invoice",
                "document_series_id": 4,
                "document_template_id": 1,
                "client": {
                  "name": "Test Client SRL",
                  "fiscal_code": "RO12345678",
                  "email": "client@example.com",
                  "phone": "+40700000000",
                  "address": "Strada Exemplu 123",
                  "county_code": "TM",
                  "city_text": "Timișoara",
                  "country_code": "RO"
                },
                "products": [
                  {
                    "name": "Serviciu consultanță",
                    "quantity": 2,
                    "vat_percentage": "21",
                    "price_with_vat": 121
                  }
                ],
                "save_client": false,
                "update_stock": false,
                "send_email_after_issue": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Document creat cu succes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateDocumentResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/documents/{documentType}": {
      "get": {
        "tags": [
          "Documente"
        ],
        "summary": "Listare documente emise",
        "description": "Returnează lista paginată a facturilor sau proformelor emise, cu datele clientului și totalurile. Ordonare: date_at descrescător, apoi id descrescător. Documentele șterse nu sunt incluse. Pentru PDF folosiți endpoint-ul de descărcare.",
        "operationId": "listDocuments",
        "parameters": [
          {
            "name": "documentType",
            "in": "path",
            "required": true,
            "description": "Tipul documentului",
            "schema": {
              "type": "string",
              "enum": [
                "invoice",
                "proform"
              ]
            }
          },
          {
            "name": "period_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Filtrează după date_at >= (YYYY-MM-DD)."
          },
          {
            "name": "period_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Filtrează după date_at <= (YYYY-MM-DD)."
          },
          {
            "name": "client_fiscal_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 20
            },
            "description": "Codul fiscal al clientului (potrivire exactă, insensibilă la majuscule)."
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Caută în numele clientului sau în numărul documentului (serie + număr)."
          },
          {
            "name": "payment_status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Doar pentru facturi: starea plății, aceeași valoare numerică folosită în aplicație."
          },
          {
            "name": "efactura_status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "not_sent",
                "processing",
                "success",
                "error",
                "not_company",
                "not_eu_company",
                "not_ro_company",
                "not_ro_person"
              ]
            },
            "description": "Doar pentru facturi: starea trimiterii în e-Factura."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Pagina."
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "description": "Documente per pagină (max 100)."
          }
        ],
        "responses": {
          "200": {
            "description": "Lista documentelor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentListResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/documents/{documentType}/{documentId}": {
      "get": {
        "tags": [
          "Documente"
        ],
        "summary": "Detalii document",
        "description": "Antetul, liniile și legăturile unei proforme sau facturi. Pentru factură include starea plății și încasările. Un `documentType` greșit sau un id nenumeric răspunde cu un 404 fără corp JSON.",
        "operationId": "showDocument",
        "parameters": [
          {
            "name": "documentType",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "proform",
                "invoice"
              ]
            }
          },
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul documentului"
          }
        ],
        "responses": {
          "200": {
            "description": "Documentul",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DocumentNotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/documents/{documentType}/{documentId}/download-pdf": {
      "get": {
        "tags": [
          "Documente"
        ],
        "summary": "Descărcare PDF",
        "description": "Returnează PDF-ul documentului codificat în base64",
        "operationId": "downloadPdf",
        "parameters": [
          {
            "name": "documentType",
            "in": "path",
            "required": true,
            "description": "Tipul documentului",
            "schema": {
              "type": "string",
              "enum": [
                "invoice",
                "proform"
              ]
            }
          },
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "description": "ID-ul documentului",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PDF generat cu succes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DownloadPdfResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/documents/{documentType}/{documentId}/send-email": {
      "post": {
        "tags": [
          "Documente"
        ],
        "summary": "Trimitere email",
        "description": "Trimite documentul pe email către client. Dacă nu este specificat `to_email`, se folosește email-ul clientului din document.",
        "operationId": "sendEmail",
        "parameters": [
          {
            "name": "documentType",
            "in": "path",
            "required": true,
            "description": "Tipul documentului",
            "schema": {
              "type": "string",
              "enum": [
                "invoice",
                "proform"
              ]
            }
          },
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "description": "ID-ul documentului",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendEmailRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email trimis cu succes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "message": {
                      "type": "string",
                      "example": "Email sent successfully"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/documents/invoice/{documentId}/payments": {
      "post": {
        "tags": [
          "Documente"
        ],
        "summary": "Încasare pe factură",
        "description": "Înregistrează o încasare. Același `external_id` întoarce încasarea existentă (200, `\"existing\": true`) fără a compara corpul cererii; altfel 201. Facturile în EUR sunt acceptate (încasarea preia cursul facturii).",
        "operationId": "addInvoicePayment",
        "parameters": [
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul documentului"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoicePaymentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Încasarea exista deja (`existing: true`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetail"
                }
              }
            }
          },
          "201": {
            "description": "Încasare înregistrată (`existing: false`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DocumentNotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/documents/proform/{documentId}": {
      "put": {
        "tags": [
          "Documente"
        ],
        "summary": "Modificare proformă",
        "description": "Înlocuiește clientul și liniile unei proforme active, nefacturate. Numărul, seria, data și `external_id` rămân. Fără `currency`, proforma își păstrează moneda; cursul BNR se recalculează pentru data proformei. O reducere la nivel de document (pusă din aplicație) se șterge. Fără `save_client`, legătura cu clientul din nomenclator rămâne doar dacă este același cumpărător (același cod fiscal; fără cod fiscal: același email).",
        "operationId": "updateProform",
        "parameters": [
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul documentului"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "client",
                  "products"
                ],
                "properties": {
                  "client": {
                    "$ref": "#/components/schemas/Client"
                  },
                  "products": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/components/schemas/Product"
                    }
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "RON",
                      "EUR"
                    ]
                  },
                  "observation": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "save_client": {
                    "type": "boolean",
                    "default": false
                  },
                  "use_product_name_from_db": {
                    "type": "boolean",
                    "default": true
                  },
                  "inventory_id": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Proforma modificată",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DocumentNotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/documents/proform/{documentId}/cancel": {
      "post": {
        "tags": [
          "Documente"
        ],
        "summary": "Anulare proformă",
        "description": "Dezactivează proforma (`active = false`). Repetarea nu schimbă nimic. 409 `proform_converted` dacă proforma are deja factură.",
        "operationId": "cancelProform",
        "parameters": [
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul documentului"
          }
        ],
        "responses": {
          "200": {
            "description": "Proforma anulată",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DocumentNotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/documents/proform/{documentId}/invoice": {
      "post": {
        "tags": [
          "Documente"
        ],
        "summary": "Factură din proformă",
        "description": "Generează factura o singură dată. Prima generare răspunde **201** cu `\"existing\": false`; un apel repetat întoarce aceeași factură (**200**, `\"existing\": true`) și înregistrează doar plățile care lipsesc. Factura primește `external_id`-ul proformei.\n\n- Când factura este creată de apel, plățile se verifică înainte de generare (moneda, suma lor față de totalul proformei + 1, `external_id` nefolosit pe alt document): o plată greșită oprește apelul înainte de a se crea factura sau a se mișca stocul. Conversia și plățile sunt atomice.\n- Când factura există deja, fiecare plată se înregistrează independent (idempotent după `external_id`).\n- Un `external_id` de plată folosit deja pe alt document dă 422 de validare pe `external_id`.",
        "operationId": "invoiceProform",
        "parameters": [
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul documentului"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "update_stock": {
                    "type": "boolean",
                    "default": false,
                    "description": "Scade stocul la generarea facturii"
                  },
                  "payments": {
                    "type": "array",
                    "maxItems": 10,
                    "items": {
                      "$ref": "#/components/schemas/InvoicePaymentRequest"
                    },
                    "description": "Încasări de înregistrat pe factură, cu `external_id` distincte"
                  }
                }
              },
              "example": {
                "update_stock": true,
                "payments": [
                  {
                    "external_id": "PAY-1001",
                    "type": "bank",
                    "date_at": "2026-10-07",
                    "amount": 242,
                    "currency": "RON"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Factura exista deja (`existing: true`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetail"
                }
              }
            }
          },
          "201": {
            "description": "Factura a fost generată (`existing: false`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/DocumentNotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/reception-notes": {
      "post": {
        "tags": [
          "Note de recepție (NIR)"
        ],
        "summary": "Creare notă de recepție (NIR)",
        "description": "Creează o notă de recepție. Furnizorul este identificat după cod fiscal (sau nume) și este creat automat dacă nu există. Produsele sunt identificate după product_id sau code în gestiunea indicată (câmpul code al produsului este folosit și drept cod de bare); cu create_missing_products=true produsele lipsă sunt create automat, altfel cererea este respinsă cu lista lor. Stocul este actualizat identic cu fluxul din aplicație (inclusiv sincronizare POS și proces-verbal de modificare preț la gestiunile cu amănuntul, dacă trimiteți un preț de vânzare diferit). Seria implicită este folosită dacă nu trimiteți document_series_id, iar numărul este alocat automat. Pentru gestiunile cu amănuntul (tip global) se recomandă trimiterea sale_price_with_vat pentru fiecare produs.",
        "operationId": "createReceptionNote",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReceptionNoteRequest"
              },
              "example": {
                "inventory_id": 12,
                "date_at": "2026-08-27",
                "supporting_document": "invoice",
                "supporting_document_number": "F-1234",
                "supporting_document_date": "2026-08-25",
                "supplier": {
                  "fiscal_code": "RO12345678",
                  "name": "Furnizor Exemplu SRL"
                },
                "create_missing_products": false,
                "products": [
                  {
                    "code": "P001",
                    "quantity": 10,
                    "price_without_vat": 5.5,
                    "vat_percent": 21
                  }
                ],
                "paid": {
                  "document": "receipt",
                  "number": "CH-1",
                  "date": "2026-08-27",
                  "value": 65.45
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Nota de recepție a fost creată",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateReceptionNoteResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "description": "Date invalide sau produse negăsite în gestiune (cu create_missing_products=false răspunsul include missing_products).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "error"
                    },
                    "message": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "object",
                      "description": "Erori de validare per câmp (opțional)"
                    },
                    "missing_products": {
                      "type": "array",
                      "description": "Produsele care nu au fost găsite în gestiune (opțional)",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer"
                          },
                          "product_id": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "code": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "get": {
        "tags": [
          "Note de recepție (NIR)"
        ],
        "summary": "Listare note de recepție",
        "description": "Returnează lista paginată a notelor de recepție (NIR), proiecție scurtă.",
        "operationId": "getReceptionNotes",
        "parameters": [
          {
            "name": "period_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Filtrează după date_at >= (YYYY-MM-DD)."
          },
          {
            "name": "period_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Filtrează după date_at <= (YYYY-MM-DD)."
          },
          {
            "name": "supplier_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "ID-ul furnizorului (din tabela suppliers)."
          },
          {
            "name": "supplier_fiscal_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 50
            },
            "description": "Cod fiscal furnizor (egalitate, case-insensitive)."
          },
          {
            "name": "inventory_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "ID-ul gestiunii."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Pagina curentă."
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "description": "Rezultate per pagină (max 100)."
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de note de recepție",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceptionNoteListResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/reception-notes/{id}": {
      "get": {
        "tags": [
          "Note de recepție (NIR)"
        ],
        "summary": "Vizualizare notă de recepție",
        "description": "Returnează detaliile complete ale unei note de recepție: antet, furnizor, gestiune, produse, plăți.",
        "operationId": "getReceptionNote",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID-ul notei de recepție",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Notă de recepție",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceptionNoteResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/reception-notes/{id}/download-pdf": {
      "get": {
        "tags": [
          "Note de recepție (NIR)"
        ],
        "summary": "Descărcare PDF notă de recepție",
        "description": "Returnează PDF-ul notei de recepție codificat în base64. Reutilizează schema DownloadPdfResponse.",
        "operationId": "downloadReceptionNotePdf",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID-ul notei de recepție",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PDF generat cu succes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DownloadPdfResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/efactura/received": {
      "get": {
        "tags": [
          "e-Factura"
        ],
        "summary": "Listare facturi primite (e-Factura)",
        "description": "Returnează lista paginată a documentelor primite prin SPV (facturi și note de credit de la furnizori). Ordonare: date_at descrescător, apoi index descrescător. Câmpurile has_pdf și has_xml indică dacă fișierul este deja stocat; PDF-ul poate fi generat din XML la cerere.",
        "operationId": "listEfacturaReceived",
        "parameters": [
          {
            "name": "period_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Filtrează după data documentului >= (YYYY-MM-DD)."
          },
          {
            "name": "period_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Filtrează după data documentului <= (YYYY-MM-DD)."
          },
          {
            "name": "supplier_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "ID-ul furnizorului."
          },
          {
            "name": "supplier_fiscal_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 50
            },
            "description": "Codul fiscal al furnizorului (potrivire exactă, insensibilă la majuscule)."
          },
          {
            "name": "document_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "invoice",
                "credit_note"
              ]
            },
            "description": "Tipul documentului."
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Caută în numărul documentului sau în numele furnizorului."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Pagina."
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "description": "Documente per pagină (max 100)."
          }
        ],
        "responses": {
          "200": {
            "description": "Lista documentelor primite",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EfacturaReceivedListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/efactura/received/{id}/download-pdf": {
      "get": {
        "tags": [
          "e-Factura"
        ],
        "summary": "Descărcare PDF factură primită",
        "description": "Returnează PDF-ul documentului primit, codificat în base64. Dacă PDF-ul nu este încă salvat, este generat din XML-ul UBL prin serviciul ANAF; dacă nu există nici XML, răspunsul este 404.",
        "operationId": "downloadEfacturaReceivedPdf",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID-ul documentului primit (din listare)",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PDF disponibil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DownloadPdfResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "502": {
            "description": "Generarea PDF din XML a eșuat (serviciul ANAF a răspuns cu eroare).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/efactura/received/{id}/download-xml": {
      "get": {
        "tags": [
          "e-Factura"
        ],
        "summary": "Descărcare XML UBL factură primită",
        "description": "Returnează XML-ul UBL al documentului primit, codificat în base64, așa cum a fost descărcat din SPV.",
        "operationId": "downloadEfacturaReceivedXml",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID-ul documentului primit (din listare)",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "XML disponibil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DownloadXmlResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/reports/pos/incomes": {
      "get": {
        "tags": [
          "Rapoarte"
        ],
        "summary": "Raport încasări POS",
        "description": "Returnează totalurile, defalcarea TVA și rândurile per zi pentru un interval de timp.",
        "operationId": "getPosIncomesReport",
        "parameters": [
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/DayStart"
          },
          {
            "name": "pos_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul POS-ului (user_id). Omiterea returnează toate POS-urile accesibile."
          },
          {
            "name": "period_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Data de început (YYYY-MM-DD). Default: azi."
          },
          {
            "name": "period_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Data de sfârșit (YYYY-MM-DD). Default: azi."
          }
        ],
        "responses": {
          "200": {
            "description": "Raport încasări",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PosIncomeReport"
                }
              }
            }
          },
          "400": {
            "description": "Parametru invalid"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Date POS indisponibile temporar"
          }
        }
      }
    },
    "/reports/pos/products": {
      "get": {
        "tags": [
          "Rapoarte"
        ],
        "summary": "Raport produse vândute POS",
        "description": "Returnează totalurile (cantitate + valoare) și lista produselor vândute în interval.",
        "operationId": "getPosProductsReport",
        "parameters": [
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "name": "pos_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul POS-ului (user_id). Omiterea returnează toate POS-urile accesibile."
          },
          {
            "name": "period_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Data de început (YYYY-MM-DD). Default: azi."
          },
          {
            "name": "period_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Data de sfârșit (YYYY-MM-DD). Default: azi."
          }
        ],
        "responses": {
          "200": {
            "description": "Raport produse",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PosProductReport"
                }
              }
            }
          },
          "400": {
            "description": "Parametru invalid"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Date POS indisponibile temporar"
          }
        }
      }
    },
    "/reports/pos/receipts": {
      "get": {
        "tags": [
          "Rapoarte"
        ],
        "summary": "Raport bonuri POS",
        "description": "Returnează bonurile POS paginate. Folosiți `include=products` pentru a încorpora produsele fiecărui bon.",
        "operationId": "getPosReceiptsReport",
        "parameters": [
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/ReceiptKind"
          },
          {
            "$ref": "#/components/parameters/AfterId"
          },
          {
            "$ref": "#/components/parameters/UpdatedSince"
          },
          {
            "name": "pos_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul POS-ului (user_id). Omiterea returnează toate POS-urile accesibile."
          },
          {
            "name": "period_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Data de început (YYYY-MM-DD). Default: azi."
          },
          {
            "name": "period_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Data de sfârșit (YYYY-MM-DD). Default: azi."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1
            },
            "description": "Pagina curentă."
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 500
            },
            "description": "Număr rezultate per pagină (1-500)."
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "products"
              ]
            },
            "description": "Setați la `products` pentru a include produsele bonului."
          }
        ],
        "responses": {
          "200": {
            "description": "Raport bonuri",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PosReceiptReport"
                }
              }
            }
          },
          "400": {
            "description": "Parametru invalid"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Date POS indisponibile temporar"
          }
        }
      }
    },
    "/reports/pos/z": {
      "get": {
        "tags": [
          "Rapoarte"
        ],
        "summary": "Raport Z POS",
        "description": "Totaluri zilnice tip Raport Z, defalcate per (zi, POS). Fiecare rând expune și `cash_book_operations.document_number` ca `z_number` atunci când Raportul Z a fost deja generat pentru gestiunea respectivă în acea zi.",
        "operationId": "getPosZReport",
        "parameters": [
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/DayStart"
          },
          {
            "name": "pos_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul POS-ului (user_id). Omiterea returnează toate POS-urile accesibile."
          },
          {
            "name": "period_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Data de început (YYYY-MM-DD). Default: azi."
          },
          {
            "name": "period_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Data de sfârșit (YYYY-MM-DD). Default: azi."
          }
        ],
        "responses": {
          "200": {
            "description": "Raport Z",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PosZReport"
                }
              }
            }
          },
          "400": {
            "description": "Parametru invalid"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Date POS indisponibile temporar"
          }
        }
      }
    },
    "/reports/pos/tables": {
      "get": {
        "tags": [
          "Rapoarte"
        ],
        "summary": "Mese deschise (live)",
        "description": "Snapshot live al meselor din gestiunile accesibile: liniile deschise, totalul mesei și, cu include=orders, comenzile de bucătărie ale șederii curente cu cronologia stărilor. Liniile și comenzile sunt cheiate pe (gestiune, id masă).",
        "operationId": "getPosTables",
        "parameters": [
          {
            "$ref": "#/components/parameters/InventoryIdFilter"
          },
          {
            "$ref": "#/components/parameters/PosId"
          },
          {
            "$ref": "#/components/parameters/UpdatedSince"
          },
          {
            "$ref": "#/components/parameters/IncludeOrders"
          },
          {
            "$ref": "#/components/parameters/OnlyOpen"
          }
        ],
        "responses": {
          "200": {
            "description": "Mese deschise (live)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PosTables"
                }
              }
            }
          },
          "400": {
            "description": "Parametru invalid"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Gestiune inaccesibilă"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Date POS indisponibile temporar"
          }
        }
      }
    },
    "/reports/pos/orders": {
      "get": {
        "tags": [
          "Rapoarte"
        ],
        "summary": "Istoric comenzi de bucătărie",
        "description": "Istoricul comenzilor trimise la bucătărie din evenimentele de stare: un rând per comandă cu cronologia (new, in_preparation, finalized, picked_up, deleted), ospătarul care a trimis-o și liniile (90 de zile după închiderea mesei). Intervalul se aplică pe new_at.",
        "operationId": "getPosOrders",
        "parameters": [
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/PeriodFrom"
          },
          {
            "$ref": "#/components/parameters/PeriodTo"
          },
          {
            "$ref": "#/components/parameters/PosId"
          },
          {
            "$ref": "#/components/parameters/InventoryIdFilter"
          },
          {
            "$ref": "#/components/parameters/TableId"
          },
          {
            "$ref": "#/components/parameters/WaiterId"
          },
          {
            "$ref": "#/components/parameters/DeliveryType"
          },
          {
            "$ref": "#/components/parameters/OrderStatus"
          },
          {
            "$ref": "#/components/parameters/AfterId"
          },
          {
            "$ref": "#/components/parameters/UpdatedSince"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PerPage"
          }
        ],
        "responses": {
          "200": {
            "description": "Istoric comenzi de bucătărie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PosOrders"
                }
              }
            }
          },
          "400": {
            "description": "Parametru invalid"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Gestiune inaccesibilă"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Date POS indisponibile temporar"
          }
        }
      }
    },
    "/reports/pos/cancelled-items": {
      "get": {
        "tags": [
          "Rapoarte"
        ],
        "summary": "Linii anulate",
        "description": "Liniile scoase de pe masă înainte de plată, așa cum le raportează POS-ul (operator și moment, fără legătură cu masa sau bonul). Păstrate un an. Fără updated_since: rândurile nu se modifică.",
        "operationId": "getPosCancelledItems",
        "parameters": [
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/PeriodFrom"
          },
          {
            "$ref": "#/components/parameters/PeriodTo"
          },
          {
            "$ref": "#/components/parameters/PosId"
          },
          {
            "$ref": "#/components/parameters/InventoryIdFilter"
          },
          {
            "$ref": "#/components/parameters/AfterId"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PerPage"
          }
        ],
        "responses": {
          "200": {
            "description": "Linii anulate",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PosCancelledItems"
                }
              }
            }
          },
          "400": {
            "description": "Parametru invalid"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Gestiune inaccesibilă"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Date POS indisponibile temporar"
          }
        }
      }
    },
    "/reports/stock/movements": {
      "get": {
        "tags": [
          "Rapoarte"
        ],
        "summary": "Mișcări de stoc",
        "description": "Jurnalul product_operations al gestiunilor accesibile, interval pe date_at. Vânzările POS nu sunt în jurnal (se citesc din reports/pos/receipts); consumul pe rețete se scrie la raportul Z.",
        "operationId": "getStockMovements",
        "parameters": [
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/PeriodFrom"
          },
          {
            "$ref": "#/components/parameters/PeriodTo"
          },
          {
            "$ref": "#/components/parameters/InventoryIdFilter"
          },
          {
            "$ref": "#/components/parameters/ProductId"
          },
          {
            "$ref": "#/components/parameters/DocumentType"
          },
          {
            "$ref": "#/components/parameters/AfterId"
          },
          {
            "$ref": "#/components/parameters/UpdatedSince"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PerPage"
          }
        ],
        "responses": {
          "200": {
            "description": "Mișcări de stoc",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockMovements"
                }
              }
            }
          },
          "400": {
            "description": "Parametru invalid"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Gestiune inaccesibilă"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Date POS indisponibile temporar"
          }
        }
      }
    },
    "/recipes": {
      "get": {
        "tags": [
          "Rapoarte"
        ],
        "summary": "Rețete",
        "description": "Rețeta fiecărui produs finit cu materialele ei; inventory_id se potrivește pe gestiunea sursă sau destinație a șablonului de producție. updated_since include rețetele șterse, cu deleted_at.",
        "operationId": "getRecipes",
        "parameters": [
          {
            "$ref": "#/components/parameters/ProductId"
          },
          {
            "$ref": "#/components/parameters/InventoryIdFilter"
          },
          {
            "$ref": "#/components/parameters/UpdatedSince"
          },
          {
            "$ref": "#/components/parameters/Page"
          },
          {
            "$ref": "#/components/parameters/PerPage"
          }
        ],
        "responses": {
          "200": {
            "description": "Rețete",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Recipes"
                }
              }
            }
          },
          "400": {
            "description": "Parametru invalid"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Gestiune inaccesibilă"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Date POS indisponibile temporar"
          }
        }
      }
    },
    "/map/counties": {
      "get": {
        "tags": [
          "Județe și localități"
        ],
        "summary": "Lista județe",
        "description": "Returnează toate județele disponibile cu id, nume și cod",
        "operationId": "mapCounties",
        "responses": {
          "200": {
            "description": "Lista județe",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "counties": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer",
                            "example": 35
                          },
                          "name": {
                            "type": "string",
                            "example": "Timiș"
                          },
                          "code": {
                            "type": "string",
                            "example": "TM"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/map/cities": {
      "get": {
        "tags": [
          "Județe și localități"
        ],
        "summary": "Lista localități per județ",
        "description": "Returnează localitățile dintr-un județ. Județul poate fi identificat prin county_id, county_code sau county_text (prioritate în această ordine).",
        "operationId": "mapCities",
        "parameters": [
          {
            "name": "county_id",
            "in": "query",
            "required": false,
            "description": "ID-ul județului (prioritate maximă)",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "county_code",
            "in": "query",
            "required": false,
            "description": "Codul județului (ex: TM, BV, CJ)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "county_text",
            "in": "query",
            "required": false,
            "description": "Numele județului (căutare parțială)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista localități",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "county": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 35
                        },
                        "name": {
                          "type": "string",
                          "example": "Timiș"
                        },
                        "code": {
                          "type": "string",
                          "example": "TM"
                        }
                      }
                    },
                    "cities": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer",
                            "example": 1
                          },
                          "name": {
                            "type": "string",
                            "example": "Timișoara"
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Tipul localității",
                            "example": "Municipiul"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/events": {
      "get": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Evenimente disponibile",
        "operationId": "listWebhookEvents",
        "description": "Catalogul tipurilor de evenimente la care se poate abona un webhook.",
        "responses": {
          "200": {
            "description": "Catalog",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          },
                          "group": {
                            "type": "string"
                          },
                          "group_label": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Listare webhook-uri",
        "operationId": "listWebhooks",
        "description": "Webhook-urile companiei cheii API, cele mai noi primele. O cheie restricționată la anumite gestiuni vede doar webhook-urile limitate la gestiunile ei (nu și pe cele pentru toate gestiunile). Secretul nu este returnat.",
        "responses": {
          "200": {
            "description": "Lista",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "webhooks": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpoint"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Creare webhook",
        "operationId": "createWebhook",
        "description": "Creează un webhook. Pentru o cheie restricționată la anumite gestiuni, `inventory_ids` trebuie să fie în interiorul lor (omis = toate gestiunile cheii). Secretul (`whsec_…`) se returnează o singură dată.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook creat",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "webhook": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    },
                    "secret": {
                      "type": "string",
                      "example": "whsec_…"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{id}": {
      "get": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Detaliu webhook",
        "operationId": "getWebhook",
        "description": "Un webhook al companiei. Pentru o cheie restricționată, un webhook care nu este limitat la gestiunile ei răspunde 404 aici și la toate operațiile de mai jos.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul webhook-ului."
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "webhook": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Modificare webhook",
        "operationId": "updateWebhook",
        "description": "Modifică numele, URL-ul, evenimentele sau gestiunile; câmpurile omise rămân neschimbate.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul webhook-ului."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook modificat",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "webhook": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Ștergere webhook",
        "operationId": "deleteWebhook",
        "description": "Șterge webhook-ul; nu se mai trimit evenimente.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul webhook-ului."
          }
        ],
        "responses": {
          "200": {
            "description": "Șters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{id}/pause": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Pauză webhook",
        "operationId": "pauseWebhook",
        "description": "Oprește trimiterea. Evenimentele care apar cât webhook-ul este în pauză nu se păstrează și nu se trimit după reluare; livrările aflate deja în așteptare pleacă după reluare. Recuperați perioada cu `updated_since` pe rapoartele POS.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul webhook-ului."
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook în pauză",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "webhook": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{id}/resume": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Reluare webhook",
        "operationId": "resumeWebhook",
        "description": "Reactivează un webhook în pauză sau dezactivat automat. Se trimit evenimentele apărute de la reactivare; cele apărute cât webhook-ul a fost în pauză sau dezactivat nu se păstrează (recuperați-le cu `updated_since` pe rapoartele POS). Livrările aflate deja în așteptare pleacă din nou; la reactivarea unui webhook dezactivat automat se reiau și livrările epuizate (`dead`) din ultimele 7 zile.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul webhook-ului."
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook activ",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "webhook": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{id}/rotate-secret": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Rotire secret",
        "operationId": "rotateWebhookSecret",
        "description": "Generează un secret nou; cel vechi rămâne valid 24 de ore. Secretul (`whsec_…`) se returnează o singură dată.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul webhook-ului."
          }
        ],
        "responses": {
          "200": {
            "description": "Secret nou",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "secret": {
                      "type": "string",
                      "example": "whsec_…"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{id}/test": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Trimitere test",
        "operationId": "testWebhook",
        "description": "Trimite imediat un eveniment `webhook.test` (`data`: `{\"ping\": true}`) și returnează rezultatul livrării. Nu contează la dezactivarea automată.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul webhook-ului."
          }
        ],
        "responses": {
          "200": {
            "description": "Rezultatul livrării",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "delivery": {
                      "$ref": "#/components/schemas/WebhookDelivery"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{id}/deliveries": {
      "get": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Jurnal livrări",
        "operationId": "listWebhookDeliveries",
        "description": "Livrările webhook-ului, cele mai noi primele.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul webhook-ului."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "delivering",
                "succeeded",
                "failed",
                "dead"
              ]
            },
            "description": "Filtru după starea livrării."
          },
          {
            "name": "event_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "pos.receipt.created",
                "pos.receipt.updated",
                "pos.receipt.voided",
                "pos.order.created",
                "pos.order.status_changed",
                "pos.table.updated",
                "product.created",
                "product.updated",
                "product.deleted",
                "product.stock_changed"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 25,
              "minimum": 1,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Livrări",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "deliveries": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "per_page": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "last_page": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{id}/deliveries/retry-failed": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Retrimite livrările eșuate",
        "operationId": "retryFailedWebhookDeliveries",
        "description": "Programează din nou toate livrările eșuate ale webhook-ului.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul webhook-ului."
          }
        ],
        "responses": {
          "200": {
            "description": "Număr livrări reprogramate",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{id}/deliveries/{deliveryId}/retry": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Retrimite o livrare",
        "operationId": "retryWebhookDelivery",
        "description": "Retrimite o singură livrare. O livrare în curs de trimitere (`delivering`) sau o trimitere de test (`webhook.test`) nu se poate retrimite (422).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "ID-ul webhook-ului."
          },
          {
            "name": "deliveryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Livrarea",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "delivery": {
                      "$ref": "#/components/schemas/WebhookDelivery"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    }
  },
  "webhooks": {
    "product-update": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Webhook: Actualizare produs",
        "description": "**Depreciat:** folosiți evenimentele `product.*`.\n\nAcest webhook este trimis automat de RezoSoft către URL-ul configurat atunci când se modifică un produs sau se actualizează stocul (ex: la emiterea unei facturi cu scădere de stoc).\n\n## Configurare\n\n1. În RezoSoft, mergeți la **Setări → Webhook-uri**\n2. Adăugați un webhook nou cu:\n   - **URL**: URL-ul aplicației dvs. care va primi notificările\n   - **Tip**: `product`\n   - **Cheie securitate**: O cheie secretă care va fi trimisă în header-ul `X-Security-Key`\n   - **Gestiune**: Selectați gestiunea pentru care doriți notificări\n\n## Autentificare\n\nWebhook-ul trimite header-ul `X-Security-Key` cu valoarea cheii de securitate configurate. Aplicația dvs. trebuie să verifice acest header.\n\n## Declanșare\n\nWebhook-ul este trimis automat când:\n- Se creează un produs nou (`action: create`)\n- Se modifică un produs sau se actualizează stocul (`action: update`)\n- Se șterge un produs (`action: delete`)\n\n## Note importante despre câmpuri\n\n- **`price`**: Conține `price_with_vat` dacă firma este plătitoare de TVA, sau `price_without_vat` în caz contrar\n- **`category`**: `null` dacă produsul nu are categorie asignată\n- **`vat`**: `null` dacă firma nu este plătitoare de TVA\n- **`stock`**: Calculat din operațiunile de inventar minus vânzările POS pentru gestiunea configurată\n\n## Exemplu integrare WooCommerce\n\nPentru pluginul **RezoSoft Facturare WooCommerce**, URL-ul webhook-ului este:\n```\nhttps://shop.example.com/wp-json/rezosoft/v1/webhook/product\n```\nCheie securitate se configurează din **WP Admin → Setări → RezoSoft Facturare → Configurare → Sincronizare stoc**.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookProductPayload"
              },
              "examples": {
                "creare_produs": {
                  "summary": "Creare produs nou",
                  "value": {
                    "action": "create",
                    "product": {
                      "id": 542,
                      "code": "PROD001",
                      "name": "Produs exemplu",
                      "description": "Descriere produs",
                      "price": 119,
                      "product_category_id": 5,
                      "vat_id": 1,
                      "category": {
                        "id": 5,
                        "name": "Categoria 1"
                      },
                      "vat": 19,
                      "stock": 0
                    }
                  }
                },
                "actualizare_produs": {
                  "summary": "Actualizare produs (modificare preț, stoc, etc.)",
                  "value": {
                    "action": "update",
                    "product": {
                      "id": 542,
                      "code": "PROD001",
                      "name": "Produs exemplu",
                      "description": "Descriere produs",
                      "price": 149,
                      "product_category_id": 5,
                      "vat_id": 1,
                      "category": {
                        "id": 5,
                        "name": "Categoria 1"
                      },
                      "vat": 19,
                      "stock": 48
                    }
                  }
                },
                "stergere_produs": {
                  "summary": "Ștergere produs",
                  "value": {
                    "action": "delete",
                    "product": {
                      "id": 542,
                      "code": "PROD001",
                      "name": "Produs exemplu",
                      "description": "Descriere produs",
                      "price": 149,
                      "product_category_id": 5,
                      "vat_id": 1,
                      "category": {
                        "id": 5,
                        "name": "Categoria 1"
                      },
                      "vat": 19,
                      "stock": 48
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook procesat cu succes"
          }
        },
        "operationId": "productUpdateWebhook",
        "deprecated": true
      }
    },
    "pos.receipt.created": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Eveniment: Bon creat",
        "operationId": "webhook_pos_receipt_created",
        "description": "Se trimite când apare un bon nou în POS.\n\nFiecare cerere este un `POST` JSON cu un singur eveniment (`WebhookEvent`) și header-ele `X-RezoSoft-Event-Id`, `X-RezoSoft-Event-Type`, `X-RezoSoft-Delivery-Id` și `X-RezoSoft-Signature`.\n\n## Verificarea semnăturii\n\nHeader-ul `X-RezoSoft-Signature` are forma `t=1759838531,v1=<hex>` (după rotirea secretului, timp de 24 de ore apar două valori `v1`). Calculați `HMAC-SHA256(secret, t + \".\" + corpul_brut)` și comparați cu oricare `v1`. Respingeți cererile cu `t` mai vechi de 5 minute.\n\n```php\n$raw = file_get_contents('php://input');\nparse_str(str_replace(',', '&', $_SERVER['HTTP_X_REZOSOFT_SIGNATURE']), $parts); // doar pentru t\npreg_match_all('/v1=([a-f0-9]{64})/', $_SERVER['HTTP_X_REZOSOFT_SIGNATURE'], $m);\n$expected = hash_hmac('sha256', $parts['t'] . '.' . $raw, $secret);\n$valid = abs(time() - (int) $parts['t']) <= 300 && array_filter($m[1], fn ($s) => hash_equals($expected, $s));\n```\n\n```js\nconst [, t] = header.match(/t=(\\d+)/);\nconst expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');\nconst valid = Math.abs(Date.now() / 1000 - t) <= 300 &&\n  [...header.matchAll(/v1=([a-f0-9]{64})/g)].some(([, s]) => crypto.timingSafeEqual(Buffer.from(s), Buffer.from(expected)));\n```\n\n## Livrare\n\n- Răspundeți cu 2xx în maximum 10 secunde; orice alt cod sau timeout se reîncearcă după 1 min, 5 min, 30 min, 2 h, 6 h, 24 h.\n- La prima încercare evenimentele aceluiași webhook sosesc în ordine; o livrare reîncercată poate sosi după evenimente mai noi. Ordonați după `occurred_at` și citiți starea curentă din `links.self`. Folosiți `X-RezoSoft-Event-Id` pentru a ignora duplicatele.\n- Corpul este un semnal: citiți starea curentă din `links.self`.\n- După 100 de eșecuri consecutive sau 3 zile fără nicio livrare reușită, webhook-ul se dezactivează și administratorii primesc un email.\n- Evenimentele care apar cât un webhook este în pauză sau dezactivat nu se păstrează; livrările aflate deja în așteptare pleacă după reactivare. Recuperați perioada cu `updated_since` pe rapoartele POS.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Orice răspuns 2xx confirmă livrarea."
          }
        }
      }
    },
    "pos.receipt.updated": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Eveniment: Bon modificat",
        "operationId": "webhook_pos_receipt_updated",
        "description": "Se trimite când un bon existent este modificat.\n\nHeader-ele, verificarea semnăturii și regulile de reîncercare sunt descrise la evenimentul „Bon creat” (`pos.receipt.created`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Orice răspuns 2xx confirmă livrarea."
          }
        }
      }
    },
    "pos.receipt.voided": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Eveniment: Bon anulat",
        "operationId": "webhook_pos_receipt_voided",
        "description": "Se trimite când un bon este anulat. `links.self` folosește forma de sincronizare (`updated_since`), pentru că bonurile anulate apar doar acolo.\n\nHeader-ele, verificarea semnăturii și regulile de reîncercare sunt descrise la evenimentul „Bon creat” (`pos.receipt.created`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Orice răspuns 2xx confirmă livrarea."
          }
        }
      }
    },
    "pos.order.created": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Eveniment: Comandă nouă",
        "operationId": "webhook_pos_order_created",
        "description": "Se trimite când o comandă nouă ajunge în bucătărie (`data.status = new`).\n\nHeader-ele, verificarea semnăturii și regulile de reîncercare sunt descrise la evenimentul „Bon creat” (`pos.receipt.created`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Orice răspuns 2xx confirmă livrarea."
          }
        }
      }
    },
    "pos.order.status_changed": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Eveniment: Comandă: status schimbat",
        "operationId": "webhook_pos_order_status_changed",
        "description": "Se trimite la fiecare schimbare de status a unei comenzi (`data.status`, `data.from`).\n\nHeader-ele, verificarea semnăturii și regulile de reîncercare sunt descrise la evenimentul „Bon creat” (`pos.receipt.created`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Orice răspuns 2xx confirmă livrarea."
          }
        }
      }
    },
    "pos.table.updated": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Eveniment: Masă modificată",
        "operationId": "webhook_pos_table_updated",
        "description": "Se trimite când o masă se modifică (`data.status`: `open` sau `free`).\n\nHeader-ele, verificarea semnăturii și regulile de reîncercare sunt descrise la evenimentul „Bon creat” (`pos.receipt.created`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Orice răspuns 2xx confirmă livrarea."
          }
        }
      }
    },
    "product.created": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Eveniment: Produs creat",
        "operationId": "webhook_product_created",
        "description": "Se trimite când produsul este creat (`data.product_id`). Citiți produsul cu stocul curent din `links.self`.\n\nHeader-ele, verificarea semnăturii și regulile de reîncercare sunt descrise la evenimentul „Bon creat” (`pos.receipt.created`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Orice răspuns 2xx confirmă livrarea."
          }
        }
      }
    },
    "product.updated": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Eveniment: Produs modificat",
        "operationId": "webhook_product_updated",
        "description": "Se trimite când produsul este modificat (`data.product_id`). Citiți produsul cu stocul curent din `links.self`. Intrările de stoc din NIR, transferuri și alte operații de gestiune sosesc ca `product.updated`; pentru a urmări stocul abonați-vă la ambele evenimente.\n\nHeader-ele, verificarea semnăturii și regulile de reîncercare sunt descrise la evenimentul „Bon creat” (`pos.receipt.created`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Orice răspuns 2xx confirmă livrarea."
          }
        }
      }
    },
    "product.deleted": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Eveniment: Produs șters",
        "operationId": "webhook_product_deleted",
        "description": "Se trimite când produsul este șters (`data.product_id`). Citiți produsul cu stocul curent din `links.self`. Pentru `product.deleted` linkul răspunde 404.\n\nHeader-ele, verificarea semnăturii și regulile de reîncercare sunt descrise la evenimentul „Bon creat” (`pos.receipt.created`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Orice răspuns 2xx confirmă livrarea."
          }
        }
      }
    },
    "product.stock_changed": {
      "post": {
        "tags": [
          "Webhook-uri"
        ],
        "summary": "Eveniment: Stoc modificat",
        "operationId": "webhook_product_stock_changed",
        "description": "Se trimite când stocul se modifică (`data.product_id`). Citiți produsul cu stocul curent din `links.self`. Intrările de stoc din NIR, transferuri și alte operații de gestiune sosesc ca `product.updated`; pentru a urmări stocul abonați-vă la ambele evenimente.\n\nHeader-ele, verificarea semnăturii și regulile de reîncercare sunt descrise la evenimentul „Bon creat” (`pos.receipt.created`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Orice răspuns 2xx confirmă livrarea."
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "From": {
        "name": "from",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Început interval (Y-m-d H:i:s sau ISO 8601, ora României). Are prioritate față de period_*. Doar from = fără limită superioară."
      },
      "To": {
        "name": "to",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Sfârșit interval, inclusiv. O dată fără oră înseamnă ziua întreagă (până la 23:59:59)."
      },
      "PeriodFrom": {
        "name": "period_from",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "format": "date"
        },
        "description": "Data de început (YYYY-MM-DD). Default: azi."
      },
      "PeriodTo": {
        "name": "period_to",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "format": "date"
        },
        "description": "Data de sfârșit (YYYY-MM-DD). Default: azi."
      },
      "DayStart": {
        "name": "day_start",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "example": "05:00"
        },
        "description": "Ora la care începe ziua de activitate (HH:MM). 05:00 se aliniază cu datarea raportului Z."
      },
      "AfterId": {
        "name": "after_id",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "Cursor: rândurile cu id > after_id, crescător, fără interval implicit. Răspunsul are pagination.next_after_id."
      },
      "UpdatedSince": {
        "name": "updated_since",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Rândurile modificate de la moment (inclusiv ștergeri, cu deleted_at). Folosiți server_time din răspunsul anterior."
      },
      "Page": {
        "name": "page",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "default": 1
        },
        "description": "Pagina curentă."
      },
      "PerPage": {
        "name": "per_page",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "default": 50,
          "minimum": 1,
          "maximum": 500
        },
        "description": "Rânduri per pagină (1-500)."
      },
      "PosId": {
        "name": "pos_id",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "ID-ul POS-ului (user_id). Omiterea returnează toate POS-urile accesibile."
      },
      "InventoryIdFilter": {
        "name": "inventory_id",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "Restrânge la o gestiune. 404 dacă nu este accesibilă."
      },
      "ProductId": {
        "name": "product_id",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "Doar un produs."
      },
      "CategoryId": {
        "name": "category_id",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "Doar produsele din categoria dată."
      },
      "DepartmentId": {
        "name": "department_id",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "Doar produsele din departamentul dat."
      },
      "TableId": {
        "name": "table_id",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "Id-ul mesei din POS (unic în cadrul gestiunii)."
      },
      "WaiterId": {
        "name": "waiter_id",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "Utilizatorul POS (ospătarul) care a trimis comanda."
      },
      "DeliveryType": {
        "name": "delivery_type",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Tipul de livrare al comenzii (ex. pickup, wolt)."
      },
      "OrderStatus": {
        "name": "status",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "enum": [
            "new",
            "in_preparation",
            "finalized",
            "picked_up",
            "deleted"
          ]
        },
        "description": "Ultima stare a comenzii."
      },
      "ReceiptKind": {
        "name": "kind",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "example": "sale"
        },
        "description": "sale (implicit), pending, scrap, return, protocol, all sau listă separată prin virgulă."
      },
      "DocumentType": {
        "name": "document_type",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "enum": [
            "reception_note",
            "invoice",
            "delivery_note",
            "import",
            "consumption_receipt",
            "transfer_receipt",
            "inventory_stock",
            "damage_report",
            "production",
            "transfer_note"
          ]
        },
        "description": "Tipul documentului sursă al mișcării."
      },
      "IncludeOrders": {
        "name": "include",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "enum": [
            "orders"
          ]
        },
        "description": "Setați la orders pentru comenzile de bucătărie ale șederii curente."
      },
      "OnlyOpen": {
        "name": "only_open",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "enum": [
            "0",
            "1"
          ],
          "default": "1"
        },
        "description": "1 = doar mesele deschise (cu linii, opened_at sau ospătar); 0 = toată sala."
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Cheie API generată din Setări → Integrări → Chei API"
      }
    },
    "schemas": {
      "DocumentTemplate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID-ul template-ului",
            "example": 1
          },
          "name": {
            "type": "string",
            "description": "Numele template-ului",
            "example": "Clasic"
          },
          "default": {
            "type": "integer",
            "description": "Template implicit (1 = da, 0 = nu)",
            "example": 1
          }
        }
      },
      "DocumentSeries": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID-ul seriei",
            "example": 4
          },
          "name": {
            "type": "string",
            "description": "Numele/Prefixul seriei",
            "example": "FF"
          },
          "delimiter": {
            "type": [
              "string",
              "null"
            ],
            "description": "Delimitator între prefix și număr",
            "example": null
          },
          "default": {
            "type": "integer",
            "description": "Serie implicită (1 = da, 0 = nu)",
            "example": 1
          }
        }
      },
      "Inventory": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID-ul gestiunii",
            "example": 1
          },
          "name": {
            "type": "string",
            "description": "Numele gestiunii",
            "example": "Depozit Principal"
          },
          "type": {
            "type": "string",
            "description": "Tipul gestiunii",
            "example": "global"
          },
          "branch_office_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "ID-ul punctului de lucru asociat",
            "example": null
          },
          "branch_office": {
            "type": [
              "object",
              "null"
            ],
            "description": "Informații punct de lucru"
          }
        }
      },
      "ProductInfo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID-ul produsului",
            "example": 1
          },
          "code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Codul produsului / barcode",
            "example": "PROD001"
          },
          "name": {
            "type": "string",
            "description": "Numele produsului",
            "example": "Produs Test"
          },
          "price_with_vat": {
            "type": [
              "number",
              "null"
            ],
            "description": "Preț cu TVA",
            "example": 119
          },
          "price_without_vat": {
            "type": [
              "number",
              "null"
            ],
            "description": "Preț fără TVA",
            "example": 100
          },
          "vat_percentage": {
            "type": [
              "number",
              "null"
            ],
            "description": "Procent TVA",
            "example": 19
          },
          "stock": {
            "type": [
              "number",
              "null"
            ],
            "description": "Stocul curent (inclus doar dacă with_stock=true)",
            "example": 25
          },
          "type": {
            "type": "string",
            "example": "goods"
          },
          "unit": {
            "type": "string",
            "example": "buc"
          },
          "internal_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Codul intern al produsului (cod propriu al firmei, separat de codul de bare)",
            "example": "SH-GLV-L"
          },
          "available_for_sale": {
            "type": "boolean"
          },
          "category": {
            "$ref": "#/components/schemas/CategoryRef"
          },
          "department": {
            "$ref": "#/components/schemas/Ref",
            "description": "Zona de preparare (ecranul de bucătărie se configurează pe departamente)"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "deleted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Doar în modul updated_since"
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer",
            "description": "Pagina curentă",
            "example": 1
          },
          "per_page": {
            "type": "integer",
            "description": "Produse per pagină",
            "example": 50
          },
          "total": {
            "type": "integer",
            "description": "Total produse",
            "example": 150
          },
          "last_page": {
            "type": "integer",
            "description": "Ultima pagină",
            "example": 3
          }
        }
      },
      "Client": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Numele clientului",
            "example": "Test Client SRL"
          },
          "fiscal_code": {
            "type": "string",
            "description": "Codul fiscal (CUI/CIF)",
            "example": "RO12345678"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Adresa de email",
            "example": "client@example.com"
          },
          "phone": {
            "type": "string",
            "description": "Număr de telefon",
            "example": "+40700000000"
          },
          "address": {
            "type": "string",
            "description": "Adresa",
            "example": "Strada Exemplu 123"
          },
          "county_id": {
            "type": "integer",
            "description": "ID-ul județului din baza de date (prioritate maximă)",
            "example": 40
          },
          "county_code": {
            "type": "string",
            "description": "Codul județului (ex: B, BV, CJ). Se caută în counties.code",
            "example": "TM"
          },
          "county_text": {
            "type": "string",
            "description": "Numele județului (căutare parțială). Se folosește doar dacă nu sunt furnizate county_id sau county_code",
            "example": "Timiș"
          },
          "city_id": {
            "type": "integer",
            "description": "ID-ul orașului din baza de date (prioritate maximă)",
            "example": 1
          },
          "city_text": {
            "type": "string",
            "description": "Numele orașului (căutare parțială). Se folosește doar dacă nu este furnizat city_id",
            "example": "Timișoara"
          },
          "country_code": {
            "type": "string",
            "description": "Codul țării (ISO 2 litere)",
            "example": "RO"
          }
        }
      },
      "Product": {
        "type": "object",
        "required": [
          "name",
          "quantity",
          "vat_percentage",
          "price_with_vat"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Codul / barcode-ul produsului, pentru legarea de un produs existent din gestiune. Dacă nu se găsește, linia se emite ca text liber și nu mișcă stocul.",
            "example": "PROD001"
          },
          "name": {
            "type": "string",
            "description": "Numele produsului",
            "example": "Serviciu consultanță"
          },
          "description": {
            "type": "string",
            "description": "Descrierea produsului",
            "example": "Consultanță IT"
          },
          "quantity": {
            "type": "number",
            "description": "Cantitatea",
            "example": 2
          },
          "vat_percentage": {
            "type": [
              "number",
              "string"
            ],
            "description": "Cota TVA în procente (ex. 21, 11, 0); se acceptă și \"21%\". Cota trebuie să existe în setările companiei, altfel 422.",
            "example": 21
          },
          "price_with_vat": {
            "type": "number",
            "description": "Preț unitar cu TVA",
            "example": 119
          },
          "price_without_vat": {
            "type": "number",
            "description": "Preț unitar fără TVA (calculat automat dacă nu e furnizat)",
            "example": 100
          },
          "measuring_unit": {
            "type": "string",
            "description": "Unitatea de măsură",
            "example": "buc"
          }
        }
      },
      "Payment": {
        "type": "object",
        "description": "Când este setat pe un document de tip `invoice`, factura este marcată ca încasată: se creează o încasare (Income) legată de factură, iar `anaf_payment_instrument` al facturii este setat în funcție de `type`. Ignorat pentru `proform`.",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Tipul încasării (folosit pentru a determina automat `anaf_payment_instrument`)",
            "enum": [
              "bank",
              "pos_receipt",
              "bank_card",
              "online_card",
              "post",
              "cec",
              "ticket_order",
              "repayment",
              "other_income"
            ],
            "example": "bank_card"
          },
          "value": {
            "type": "number",
            "description": "Opțional. Valoarea încasării. Dacă nu este furnizată, se folosește totalul facturii.",
            "example": 238
          },
          "number": {
            "type": "string",
            "description": "Opțional. Număr de referință (ex. OP, ID tranzacție), salvat pe încasare.",
            "example": "OP-1234"
          },
          "description": {
            "type": "string",
            "description": "Opțional. Descrierea încasării (câmpul `representing`). Dacă nu este furnizată, se folosește `<echivalent factura> <serie+număr>`.",
            "example": "Plată comandă online #ASD123"
          }
        }
      },
      "CreateDocumentRequest": {
        "type": "object",
        "required": [
          "document_type",
          "document_series_id",
          "document_template_id",
          "client",
          "products"
        ],
        "properties": {
          "document_type": {
            "type": "string",
            "description": "Tipul documentului",
            "enum": [
              "invoice",
              "proform"
            ],
            "example": "invoice"
          },
          "document_series_id": {
            "type": "integer",
            "description": "ID-ul seriei de documente",
            "example": 4
          },
          "document_template_id": {
            "type": "integer",
            "description": "ID-ul template-ului",
            "example": 1
          },
          "inventory_id": {
            "type": "integer",
            "description": "ID-ul gestiunii pentru scădere stoc",
            "example": 1
          },
          "observation": {
            "type": "string",
            "description": "Observații pe document",
            "example": "Comanda online: #ASD123"
          },
          "client": {
            "$ref": "#/components/schemas/Client"
          },
          "save_client": {
            "type": "boolean",
            "description": "Salvează clientul în baza de date",
            "default": false
          },
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Product"
            },
            "minItems": 1
          },
          "payment": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Payment"
              }
            ],
            "description": "Încasarea facturii, înregistrată în același apel. Recomandat pentru comenzi deja plătite (ex. magazin online cu plată cu cardul: `{\"type\": \"online_card\"}`): emiterea și încasarea rămân un singur apel idempotent. Pentru plăți ulterioare folosiți `POST /documents/invoice/{id}/payments`."
          },
          "use_product_name_from_db": {
            "type": "boolean",
            "description": "Folosește numele produsului din DB (după cod)",
            "default": true
          },
          "update_stock": {
            "type": "boolean",
            "description": "Scade stocul din gestiunea `inventory_id`. Fiecare linie se leagă de un produs după `product_id` sau `code`; o linie fără produs găsit se emite ca text liber și nu mișcă stocul. Stocul insuficient nu blochează emiterea: stocul poate deveni negativ.",
            "default": false
          },
          "send_email_after_issue": {
            "type": "boolean",
            "description": "Trimite documentul pe email după emitere",
            "default": false
          },
          "external_id": {
            "type": "string",
            "description": "ID extern pentru referință (max. 128). Obligatoriu cu `idempotent: true`.",
            "example": "ORDER123"
          },
          "currency": {
            "type": "string",
            "enum": [
              "RON",
              "EUR"
            ],
            "default": "RON",
            "description": "Moneda documentului. Pentru EUR se folosește cursul BNR al zilei."
          },
          "idempotent": {
            "type": "boolean",
            "default": false,
            "description": "Cu `true` (și `external_id` obligatoriu) documentul se emite o singură dată pe cheia (companie, tip document, `external_id`). O cerere repetată întoarce documentul existent cu `\"existing\": true`: corpul nou nu se compară cu primul și este ignorat, nu se scrie nimic și stocul nu se mai mișcă. Cheia nu expiră; după ștergerea documentului, același `external_id` emite unul nou."
          }
        }
      },
      "CreateDocumentResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "id": {
            "type": "integer",
            "description": "ID-ul documentului creat",
            "example": 128917
          },
          "key": {
            "type": "string",
            "description": "Cheia unică pentru acces public",
            "example": "v61RqgZAHY6LC8YGXdZGMRUBcGEaTc6z..."
          },
          "number": {
            "type": "string",
            "description": "Numărul complet al documentului",
            "example": "FF34"
          },
          "total": {
            "type": "number",
            "description": "Valoarea totală",
            "example": 238
          },
          "pdf_url": {
            "type": "string",
            "description": "URL pentru descărcare PDF publică",
            "example": "https://api.rezosoft.ro/doc-pdf/invoice/v61RqgZAHY6LC8YGXdZGMRUBcGEaTc6z..."
          },
          "currency": {
            "type": "string",
            "example": "RON"
          },
          "existing": {
            "type": "boolean",
            "description": "Doar cu `idempotent: true`: `false` la prima emitere, `true` când documentul exista deja pentru acest `external_id`."
          }
        }
      },
      "DownloadPdfResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "filename": {
            "type": "string",
            "description": "Numele fișierului PDF",
            "example": "FF34.pdf"
          },
          "content": {
            "type": "string",
            "description": "Conținutul PDF codificat în base64",
            "example": "JVBERi0xLjQKJ..."
          },
          "content_type": {
            "type": "string",
            "description": "Tipul MIME",
            "example": "application/pdf"
          }
        }
      },
      "DocumentClient": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "example": "Client SRL"
          },
          "fiscal_code": {
            "type": [
              "string",
              "null"
            ],
            "example": "RO12345678"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "example": "contact@client.ro"
          }
        }
      },
      "DocumentListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 1234
          },
          "type": {
            "type": "string",
            "enum": [
              "invoice",
              "proform"
            ]
          },
          "number": {
            "type": "string",
            "description": "Serie + delimitator + număr",
            "example": "GDC-0042"
          },
          "series_name": {
            "type": "string",
            "example": "GDC"
          },
          "series_number": {
            "type": "string",
            "example": "0042"
          },
          "date_at": {
            "type": "string",
            "format": "date",
            "example": "2026-08-14"
          },
          "client": {
            "$ref": "#/components/schemas/DocumentClient"
          },
          "currency": {
            "type": "string",
            "example": "RON"
          },
          "currency_rate": {
            "type": [
              "number",
              "null"
            ],
            "example": 1
          },
          "total_net": {
            "type": "number",
            "example": 1000
          },
          "total_vat": {
            "type": "number",
            "example": 210
          },
          "total": {
            "type": "number",
            "example": 1210
          },
          "active": {
            "type": "boolean",
            "example": true
          },
          "payment_status": {
            "type": "integer",
            "description": "Doar pentru facturi",
            "example": 1
          },
          "efactura_status": {
            "type": "string",
            "description": "Doar pentru facturi",
            "example": "success"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-14T10:22:31+03:00"
          }
        }
      },
      "DocumentListResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentListItem"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "EfacturaSupplier": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 77
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "example": "Furnizor SRL"
          },
          "fiscal_code": {
            "type": [
              "string",
              "null"
            ],
            "example": "RO87654321"
          }
        }
      },
      "EfacturaReceivedItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 98765
          },
          "document_index": {
            "type": "string",
            "description": "Indexul de încărcare ANAF",
            "example": "5012345678"
          },
          "download_index": {
            "type": [
              "string",
              "null"
            ],
            "description": "Indexul de descărcare ANAF",
            "example": "5012345679"
          },
          "document_type": {
            "type": "string",
            "enum": [
              "invoice",
              "credit_note"
            ]
          },
          "document_number": {
            "type": [
              "string",
              "null"
            ],
            "example": "FCT 1234"
          },
          "date_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-08-12"
          },
          "supplier": {
            "$ref": "#/components/schemas/EfacturaSupplier"
          },
          "total": {
            "type": [
              "number",
              "null"
            ],
            "example": 250.5
          },
          "currency": {
            "type": [
              "string",
              "null"
            ],
            "example": "RON"
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "example": "ok"
          },
          "reception_note_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "NIR-ul asociat, dacă există"
          },
          "has_pdf": {
            "type": "boolean",
            "example": true
          },
          "has_xml": {
            "type": "boolean",
            "example": true
          },
          "received_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Momentul preluării din SPV",
            "example": "2026-08-13T04:10:00+03:00"
          }
        }
      },
      "EfacturaReceivedListResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "efactura_documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EfacturaReceivedItem"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "DownloadXmlResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "filename": {
            "type": "string",
            "description": "Numele fișierului XML",
            "example": "5012345678.xml"
          },
          "content": {
            "type": "string",
            "description": "Conținutul XML codificat în base64",
            "example": "PD94bWwgdmVyc2lvbj0iMS4wIj8+..."
          },
          "content_type": {
            "type": "string",
            "description": "Tipul MIME",
            "example": "application/xml"
          }
        }
      },
      "ReceptionNoteListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 4521
          },
          "date_at": {
            "type": "string",
            "format": "date",
            "example": "2026-04-15"
          },
          "reception_number": {
            "type": "string",
            "example": "NIR-001234"
          },
          "document_series": {
            "type": "object",
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ],
                "example": "NIR"
              },
              "delimiter": {
                "type": [
                  "string",
                  "null"
                ],
                "example": "-"
              },
              "number": {
                "type": [
                  "integer",
                  "null"
                ],
                "example": 1234
              }
            }
          },
          "supporting_document": {
            "type": "object",
            "properties": {
              "type": {
                "type": [
                  "string",
                  "null"
                ],
                "example": "invoice"
              },
              "number": {
                "type": [
                  "string",
                  "null"
                ],
                "example": "F-9981"
              },
              "date_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date",
                "example": "2026-04-12"
              },
              "due_date_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date",
                "example": "2026-05-12"
              }
            }
          },
          "currency": {
            "type": "string",
            "example": "RON"
          },
          "total_invoice": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "example": 1190
          },
          "total_invoice_vat": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "example": 190
          },
          "total_acquisition": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "example": 1000
          },
          "total_sale": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "example": 1500
          },
          "inventory": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "integer",
                "example": 7
              },
              "name": {
                "type": "string",
                "example": "Magazin central"
              }
            }
          },
          "supplier": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": [
                  "integer",
                  "null"
                ],
                "example": 42
              },
              "name": {
                "type": "string",
                "example": "Acme SRL"
              },
              "fiscal_code": {
                "type": [
                  "string",
                  "null"
                ],
                "example": "RO12345678"
              }
            }
          }
        }
      },
      "ReceptionNoteListResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "reception_notes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceptionNoteListItem"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "ReceptionNoteSupplier": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "integer",
              "null"
            ],
            "example": 42
          },
          "name": {
            "type": "string",
            "example": "Acme SRL"
          },
          "fiscal_code": {
            "type": [
              "string",
              "null"
            ],
            "example": "RO12345678"
          },
          "trade_register_number": {
            "type": [
              "string",
              "null"
            ],
            "example": "J40/123/2020"
          },
          "address": {
            "type": [
              "string",
              "null"
            ],
            "example": "Strada Exemplu 1"
          },
          "city": {
            "type": [
              "string",
              "null"
            ],
            "example": "București"
          },
          "county": {
            "type": [
              "string",
              "null"
            ],
            "example": "București"
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "example": "Romania"
          }
        }
      },
      "ReceptionNoteProduct": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 99001
          },
          "name": {
            "type": "string",
            "example": "Produs test"
          },
          "code": {
            "type": [
              "string",
              "null"
            ],
            "example": "PRD-001"
          },
          "measuring_unit": {
            "type": [
              "string",
              "null"
            ],
            "example": "buc"
          },
          "quantity": {
            "type": "number",
            "format": "float",
            "example": 10
          },
          "acquisition_vat_percentage": {
            "type": "number",
            "format": "float",
            "example": 19
          },
          "sale_vat_percentage": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "example": 19
          },
          "acquisition_price_without_vat": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "example": 100
          },
          "acquisition_price_with_vat": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "example": 119
          },
          "sale_price_without_vat": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "example": 150
          },
          "sale_price_with_vat": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "example": 178.5
          },
          "series_name": {
            "type": [
              "string",
              "null"
            ],
            "example": null
          }
        }
      },
      "ReceptionNotePayment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 7001
          },
          "date_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "example": "2026-04-20"
          },
          "value": {
            "type": [
              "number",
              "null"
            ],
            "format": "float",
            "example": 500
          },
          "document": {
            "type": [
              "string",
              "null"
            ],
            "example": "Ordin de plată"
          },
          "document_number": {
            "type": [
              "string",
              "null"
            ],
            "example": "OP-7788"
          }
        }
      },
      "ReceptionNote": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ReceptionNoteListItem"
          },
          {
            "type": "object",
            "properties": {
              "currency_date": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date",
                "example": null
              },
              "currency_rate": {
                "type": [
                  "number",
                  "null"
                ],
                "format": "float",
                "example": null
              },
              "observation": {
                "type": [
                  "string",
                  "null"
                ],
                "example": null
              },
              "supplier": {
                "$ref": "#/components/schemas/ReceptionNoteSupplier"
              },
              "products": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ReceptionNoteProduct"
                }
              },
              "payments": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ReceptionNotePayment"
                }
              }
            }
          }
        ]
      },
      "ReceptionNoteResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "reception_note": {
            "$ref": "#/components/schemas/ReceptionNote"
          }
        }
      },
      "CreateProductRequest": {
        "type": "object",
        "required": [
          "inventory_id",
          "name",
          "vat_percent"
        ],
        "properties": {
          "inventory_id": {
            "type": "integer",
            "description": "ID-ul gestiunii în care se creează produsul",
            "example": 12
          },
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Numele produsului",
            "example": "Produs Exemplu"
          },
          "code": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 255,
            "description": "Codul produsului (folosit și drept cod de bare). Generat automat dacă lipsește. Trebuie să fie unic în gestiune.",
            "example": "5941234567890"
          },
          "type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Tipul produsului (implicit goods).",
            "enum": [
              "unspecified",
              "raw_material",
              "cash_advanced",
              "other_material",
              "finite_product",
              "pos_product",
              "goods",
              "inventory_item",
              "bought_services",
              "packing",
              "services",
              null
            ]
          },
          "unit": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 60,
            "description": "Unitatea de măsură (implicit buc).",
            "example": "buc"
          },
          "vat_percent": {
            "type": "number",
            "description": "Procent TVA — cota respectivă trebuie să existe pentru companie.",
            "example": 21
          },
          "price_with_vat": {
            "type": [
              "number",
              "null"
            ],
            "description": "Preț de vânzare cu TVA. Obligatoriu dacă lipsește price_without_vat.",
            "example": 12.5
          },
          "price_without_vat": {
            "type": [
              "number",
              "null"
            ],
            "description": "Preț de vânzare fără TVA. Obligatoriu dacă lipsește price_with_vat."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 5000,
            "description": "Descrierea produsului"
          },
          "min_stock": {
            "type": [
              "number",
              "null"
            ],
            "description": "Stoc minim pentru alerte"
          },
          "internal_code": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100,
            "description": "Codul intern al produsului (cod propriu al firmei, separat de codul de bare)"
          },
          "available_for_sale": {
            "type": "boolean",
            "description": "Disponibil pentru vânzare (implicit true)"
          }
        }
      },
      "CreateReceptionNoteRequest": {
        "type": "object",
        "required": [
          "inventory_id",
          "date_at",
          "supporting_document",
          "supporting_document_number",
          "supplier",
          "create_missing_products",
          "products"
        ],
        "properties": {
          "inventory_id": {
            "type": "integer",
            "description": "ID-ul gestiunii (vezi GET /inventories)."
          },
          "date_at": {
            "type": "string",
            "format": "date",
            "description": "Data notei de recepție."
          },
          "document_series_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Seria pentru NIR (opțional, implicit seria default). Numărul este alocat automat."
          },
          "supporting_document": {
            "type": "string",
            "enum": [
              "invoice",
              "delivery_note",
              "pos_receipt",
              "pos_receipt_with_fiscal_code",
              "trading_card",
              "reverse_taxation",
              "purchase_bill",
              "nontaxable_operation",
              "contract",
              "exception_from_amef",
              "simplified_invoice",
              "issued_behalf_supplier",
              "no_partial_deduction",
              "no_total_deduction",
              "article_311",
              "article_312",
              "production_receipt",
              "test_document"
            ],
            "description": "Tipul documentului însoțitor. Trimiteți cheia (ex: `invoice`, `delivery_note`), nu eticheta. Denumirea în română (ex: `Factura`, `Aviz`) este acceptată pentru compatibilitate, dar se salvează tot cheia.",
            "example": "invoice"
          },
          "supporting_document_number": {
            "type": "string",
            "description": "Numărul documentului însoțitor."
          },
          "supporting_document_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Data documentului însoțitor (implicit date_at)."
          },
          "supporting_document_due_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Scadența (opțional)."
          },
          "currency": {
            "type": "string",
            "default": "RON",
            "description": "Moneda (3 litere). Pentru altă monedă decât RON sunt obligatorii currency_date și currency_rate."
          },
          "currency_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "currency_rate": {
            "type": [
              "number",
              "null"
            ]
          },
          "vat_payer": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Documentul însoțitor are TVA. Implicit true dacă cel puțin un produs are cotă TVA > 0."
          },
          "reverse_vat_charge": {
            "type": "boolean",
            "default": false,
            "description": "Taxare inversă."
          },
          "observation": {
            "type": [
              "string",
              "null"
            ]
          },
          "supplier": {
            "type": "object",
            "description": "Furnizorul este căutat după cod fiscal (comparație doar pe cifre), apoi după nume; dacă nu există, este creat (name devine obligatoriu).",
            "properties": {
              "fiscal_code": {
                "type": [
                  "string",
                  "null"
                ],
                "example": "RO12345678"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Obligatoriu doar la crearea unui furnizor nou."
              },
              "trade_register_number": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "address": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "county": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Numele județului (pentru furnizori noi)."
              },
              "city": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Numele localității (pentru furnizori noi)."
              },
              "phone": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "create_missing_products": {
            "type": "boolean",
            "description": "true: produsele negăsite în gestiune sunt create automat (necesită name și vat_percent; fără code se generează automat un cod de bare EAN-13). false: cererea este respinsă cu lista missing_products."
          },
          "products": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": [
                "quantity"
              ],
              "properties": {
                "product_id": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "description": "Identificare după ID produs."
                },
                "code": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Identificare după cod produs."
                },
                "name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Numele produsului (obligatoriu la creare)."
                },
                "quantity": {
                  "type": "number",
                  "description": "Cantitatea recepționată (în unitatea principală a produsului)."
                },
                "price_without_vat": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "description": "Preț achiziție fără TVA (obligatoriu dacă lipsește price_with_vat)."
                },
                "price_with_vat": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "description": "Preț achiziție cu TVA (obligatoriu dacă lipsește price_without_vat)."
                },
                "vat_percent": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "description": "Cota TVA (ex: 21). Implicit cota produsului; obligatorie la crearea unui produs nou."
                },
                "sale_price_with_vat": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "description": "Preț de vânzare cu TVA. Recomandat pentru gestiunile cu amănuntul; dacă diferă de prețul curent, se generează proces-verbal de modificare preț."
                },
                "sale_price_without_vat": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "unit": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Unitatea de măsură la crearea unui produs nou (implicit buc)."
                },
                "type": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Tipul produsului la creare (implicit goods).",
                  "enum": [
                    "unspecified",
                    "raw_material",
                    "cash_advanced",
                    "other_material",
                    "finite_product",
                    "pos_product",
                    "goods",
                    "inventory_item",
                    "bought_services",
                    "packing",
                    "services",
                    null
                  ]
                }
              }
            }
          },
          "paid": {
            "type": [
              "object",
              "null"
            ],
            "description": "Plata documentului (opțional).",
            "properties": {
              "document": {
                "type": "string",
                "enum": [
                  "receipt",
                  "payment_order",
                  "pos_receipt",
                  "postal_mandate",
                  "card",
                  "cec",
                  "order_ticket"
                ]
              },
              "number": {
                "type": "string"
              },
              "date": {
                "type": "string",
                "format": "date",
                "description": "Implicit date_at."
              },
              "value": {
                "type": "number"
              }
            }
          }
        }
      },
      "CreateReceptionNoteResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "message": {
            "type": "string",
            "example": "Reception note created"
          },
          "reception_note": {
            "$ref": "#/components/schemas/ReceptionNote"
          }
        }
      },
      "SendEmailRequest": {
        "type": "object",
        "properties": {
          "to_email": {
            "type": "string",
            "format": "email",
            "description": "Adresa de email destinatar (opțional, implicit email client)",
            "example": "client@example.com"
          },
          "subject": {
            "type": "string",
            "description": "Subiect personalizat (opțional)",
            "example": "Factura FF34"
          },
          "message": {
            "type": "string",
            "description": "Mesaj personalizat (opțional)",
            "example": "Bună ziua, vă trimitem factura atașată."
          }
        }
      },
      "WebhookProductPayload": {
        "type": "object",
        "description": "Payload-ul trimis de webhook la actualizarea unui produs",
        "properties": {
          "action": {
            "type": "string",
            "description": "Tipul acțiunii",
            "enum": [
              "create",
              "update",
              "delete"
            ],
            "example": "update"
          },
          "product": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "description": "ID-ul produsului în RezoSoft",
                "example": 542
              },
              "code": {
                "type": "string",
                "description": "Codul produsului (SKU)",
                "example": "PROD001"
              },
              "name": {
                "type": "string",
                "description": "Numele produsului",
                "example": "Produs exemplu"
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Descrierea produsului",
                "example": "Descriere produs"
              },
              "price": {
                "type": "number",
                "description": "Prețul produsului (cu/fără TVA în funcție de platitor TVA)",
                "example": 119
              },
              "product_category_id": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "ID-ul categoriei (vezi și category)",
                "example": 5
              },
              "vat_id": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "ID-ul cotei TVA (vezi și vat)",
                "example": 1
              },
              "category": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "Categoria produsului",
                "properties": {
                  "id": {
                    "type": "integer",
                    "example": 5
                  },
                  "name": {
                    "type": "string",
                    "example": "Categoria 1"
                  }
                }
              },
              "vat": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Procent TVA (null dacă firma nu e plătitoare de TVA)",
                "example": 19
              },
              "stock": {
                "type": "number",
                "description": "Stocul curent al produsului (calculat din operațiuni inventar și vânzări POS)",
                "example": 48
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "error"
          },
          "message": {
            "type": "string",
            "example": "Error description"
          }
        }
      },
      "PosVatBreakdownRow": {
        "type": "object",
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "example": "2026-04-15"
          },
          "vat_percentage": {
            "type": "number",
            "example": 19
          },
          "total_sale": {
            "type": "number",
            "example": 199.5,
            "description": "Total vândut (cu TVA) pentru această cotă"
          },
          "vat_value": {
            "type": "number",
            "example": 31.85,
            "description": "Valoarea TVA inclusă în total_sale (calculată ca total_sale × vat_percentage / (100 + vat_percentage))"
          }
        }
      },
      "PosIncomeReport": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "totals": {
            "type": "object",
            "properties": {
              "receipts": {
                "type": "integer",
                "example": 42
              },
              "total": {
                "type": "number",
                "example": 1250.5
              },
              "cash": {
                "type": "number",
                "example": 800
              },
              "card": {
                "type": "number",
                "example": 350.5
              },
              "online": {
                "type": "number",
                "example": 100
              },
              "voucher": {
                "type": "number",
                "example": 0
              },
              "ticket": {
                "type": "number",
                "example": 0
              },
              "discount": {
                "type": "number",
                "example": 15
              },
              "tip_value": {
                "type": "number",
                "example": 0
              },
              "sgr_quantity": {
                "type": "number",
                "example": 0,
                "description": "Cantitate ambalaje SGR vândute"
              }
            }
          },
          "vat_breakdown": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PosVatBreakdownRow"
            }
          },
          "daily_rows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "day": {
                  "type": "string",
                  "format": "date"
                },
                "total": {
                  "type": "number"
                },
                "cash": {
                  "type": "number"
                },
                "card": {
                  "type": "number"
                },
                "online": {
                  "type": "number"
                },
                "voucher": {
                  "type": "number"
                }
              }
            }
          }
        }
      },
      "PosProductReport": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "totals": {
            "type": "object",
            "properties": {
              "quantity": {
                "type": "number",
                "example": 128
              },
              "total": {
                "type": "number",
                "example": 1250.5
              }
            }
          },
          "products": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "example": "5941234567890"
                },
                "name": {
                  "type": "string",
                  "example": "Product A"
                },
                "quantity": {
                  "type": "number",
                  "example": 5
                },
                "unit_price": {
                  "type": "number",
                  "example": 50
                },
                "total": {
                  "type": "number",
                  "example": 250
                }
              }
            }
          }
        }
      },
      "PosReceiptProduct": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "123"
          },
          "name": {
            "type": "string",
            "example": "Product A"
          },
          "quantity": {
            "type": "number",
            "example": 2
          },
          "unit_price": {
            "type": "number",
            "example": 12.5,
            "description": "Preț unitar efectiv (total / cantitate, după discount)"
          },
          "total": {
            "type": "number",
            "example": 25,
            "description": "Preț total linie (cantitate × preț unitar - discount)"
          },
          "vat_percentage": {
            "type": "number",
            "example": 19
          },
          "product_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "unit": {
            "type": [
              "string",
              "null"
            ],
            "example": "buc"
          },
          "list_price": {
            "type": "number",
            "example": 15,
            "description": "Prețul de listă din POS, înainte de discount"
          },
          "discount": {
            "type": "number",
            "example": 5
          },
          "discount_added_by": {
            "type": [
              "string",
              "null"
            ]
          },
          "vat_value": {
            "type": "number",
            "example": 3.97
          },
          "type": {
            "type": [
              "string",
              "null"
            ],
            "example": "goods"
          },
          "category": {
            "$ref": "#/components/schemas/CategoryRef"
          },
          "department": {
            "$ref": "#/components/schemas/Ref"
          }
        }
      },
      "PosReceiptReport": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "server_time": {
            "type": "string",
            "format": "date-time"
          },
          "receipts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer",
                  "example": 1234
                },
                "receipt_number": {
                  "type": "string",
                  "example": "789"
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time",
                  "example": "2026-04-15T14:30:00+00:00"
                },
                "total": {
                  "type": "number",
                  "example": 125.5
                },
                "cash": {
                  "type": "number",
                  "example": 125.5
                },
                "card": {
                  "type": "number",
                  "example": 0
                },
                "online": {
                  "type": "number",
                  "example": 0
                },
                "voucher": {
                  "type": "number",
                  "example": 0
                },
                "ticket": {
                  "type": "number",
                  "example": 0
                },
                "operator": {
                  "type": "string",
                  "example": "John Doe"
                },
                "fiscal_code": {
                  "type": "string",
                  "example": "RO12345678",
                  "description": "CIF-ul clientului (dacă a fost furnizat pe bon)"
                },
                "pos_name": {
                  "type": "string",
                  "example": "Shop Central",
                  "description": "Prezent doar când sunt mai multe POS-uri"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "sale",
                    "pending",
                    "scrap",
                    "return",
                    "protocol"
                  ],
                  "description": "După sent_to_cash_register: 1,2 sale; 0 pending; -1 scrap; -2 return; -3 protocol"
                },
                "pos_id": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "inventory_id": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "table": {
                  "$ref": "#/components/schemas/Ref"
                },
                "delivery_type": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "custom_payment_1": {
                  "type": "number"
                },
                "custom_payment_2": {
                  "type": "number"
                },
                "custom_payment_3": {
                  "type": "number"
                },
                "discount": {
                  "type": "object",
                  "properties": {
                    "general": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "general_value": {
                      "type": "number"
                    },
                    "items_value": {
                      "type": "number"
                    }
                  }
                },
                "tip": {
                  "type": "object",
                  "properties": {
                    "raw": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "value": {
                      "type": "number"
                    }
                  }
                },
                "vat_breakdown": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "vat_percentage": {
                        "type": "number"
                      },
                      "gross": {
                        "type": "number"
                      },
                      "vat_value": {
                        "type": "number"
                      }
                    }
                  }
                },
                "invoice": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "properties": {
                    "id": {
                      "type": "integer"
                    },
                    "number": {
                      "type": "string"
                    },
                    "date_at": {
                      "type": "string",
                      "format": "date"
                    },
                    "total": {
                      "type": "number"
                    }
                  }
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "Momentul sincronizării / ultimei modificări (server)"
                },
                "deleted_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "Doar în modul updated_since"
                },
                "products": {
                  "type": "array",
                  "description": "Prezent numai când include=products.",
                  "items": {
                    "$ref": "#/components/schemas/PosReceiptProduct"
                  }
                }
              }
            }
          },
          "pagination": {
            "type": "object",
            "properties": {
              "page": {
                "type": "integer",
                "example": 1
              },
              "per_page": {
                "type": "integer",
                "example": 50
              },
              "total": {
                "type": "integer",
                "example": 234
              },
              "last_page": {
                "type": "integer",
                "example": 5
              }
            }
          }
        }
      },
      "Ref": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "CategoryRef": {
        "type": [
          "object",
          "null"
        ],
        "description": "Categoria din POS; null când produsul nu are sau categoria a fost ștearsă.",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "parent_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "order_number": {
            "type": "integer"
          },
          "hidden": {
            "type": "boolean"
          }
        }
      },
      "CursorPagination": {
        "type": "object",
        "description": "Forma paginării în modul after_id.",
        "properties": {
          "per_page": {
            "type": "integer"
          },
          "count": {
            "type": "integer"
          },
          "next_after_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "null pe ultima pagină"
          }
        }
      },
      "ReceiptLine": {
        "type": "object",
        "properties": {
          "code": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "quantity": {
            "type": "number"
          },
          "unit_price": {
            "type": "number",
            "description": "Preț unitar efectiv (total / cantitate)"
          },
          "total": {
            "type": "number"
          },
          "vat_percentage": {
            "type": "number"
          },
          "product_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "list_price": {
            "type": "number",
            "description": "Prețul de listă din POS, înainte de discount"
          },
          "discount": {
            "type": "number"
          },
          "discount_added_by": {
            "type": [
              "string",
              "null"
            ]
          },
          "vat_value": {
            "type": "number"
          },
          "type": {
            "type": [
              "string",
              "null"
            ]
          },
          "category": {
            "$ref": "#/components/schemas/CategoryRef"
          },
          "department": {
            "$ref": "#/components/schemas/Ref"
          }
        }
      },
      "TableLine": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "product_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "code": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "quantity": {
            "type": "number"
          },
          "unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "list_price": {
            "type": "number"
          },
          "discount": {
            "type": [
              "string",
              "null"
            ],
            "description": "Valoarea brută din POS: sumă sau procent (ex. 10%)"
          },
          "discount_added_by": {
            "type": [
              "string",
              "null"
            ]
          },
          "total": {
            "type": "number"
          },
          "vat_percentage": {
            "type": "number"
          },
          "type": {
            "type": [
              "string",
              "null"
            ]
          },
          "category": {
            "$ref": "#/components/schemas/CategoryRef"
          },
          "department": {
            "$ref": "#/components/schemas/Ref"
          },
          "added_by": {
            "type": [
              "string",
              "null"
            ],
            "description": "qr_code pentru comenzile clientului"
          },
          "sgr_package": {
            "type": "integer"
          }
        }
      },
      "OrderLine": {
        "type": "object",
        "properties": {
          "table_item_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "product_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "code": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "quantity": {
            "type": "number"
          },
          "unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "list_price": {
            "type": "number"
          },
          "total": {
            "type": "number"
          },
          "vat_percentage": {
            "type": "number"
          },
          "category": {
            "$ref": "#/components/schemas/CategoryRef"
          },
          "department": {
            "$ref": "#/components/schemas/Ref"
          }
        }
      },
      "Timeline": {
        "type": "object",
        "description": "Primul moment în care comanda a atins fiecare stare; null când nu a atins-o.",
        "properties": {
          "new_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "in_preparation_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "finalized_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "picked_up_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "deleted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Scoasă de pe ecranul bucătăriei, de regulă la închiderea mesei"
          }
        }
      },
      "KitchenOrder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "order_number": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "in_preparation",
              "finalized",
              "picked_up"
            ]
          },
          "delivery_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "items_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "timeline": {
            "$ref": "#/components/schemas/Timeline"
          },
          "waiter": {
            "$ref": "#/components/schemas/Ref"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderLine"
            }
          }
        }
      },
      "PosTables": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "server_time": {
            "type": "string",
            "format": "date-time"
          },
          "totals": {
            "type": "object",
            "properties": {
              "open_tables": {
                "type": "integer"
              },
              "open_value": {
                "type": "number",
                "description": "Suma liniilor neîncasate"
              }
            }
          },
          "tables": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer",
                  "description": "Id-ul mesei din POS, unic în cadrul gestiunii"
                },
                "name": {
                  "type": "string"
                },
                "inventory_id": {
                  "type": "integer"
                },
                "pos_id": {
                  "type": "integer",
                  "description": "Contul POS care deține sala"
                },
                "floor": {
                  "$ref": "#/components/schemas/Ref"
                },
                "waiter": {
                  "$ref": "#/components/schemas/Ref"
                },
                "opened_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "general_discount": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "tip": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "fiscal_code": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "total": {
                  "type": "number"
                },
                "items": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TableLine"
                  }
                },
                "orders": {
                  "type": "array",
                  "description": "Doar cu include=orders",
                  "items": {
                    "$ref": "#/components/schemas/KitchenOrder"
                  }
                }
              }
            }
          }
        }
      },
      "PosOrders": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "server_time": {
            "type": "string",
            "format": "date-time"
          },
          "orders": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer"
                },
                "order_number": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "inventory_id": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "pos_id": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "table": {
                  "$ref": "#/components/schemas/Ref"
                },
                "waiter": {
                  "$ref": "#/components/schemas/Ref"
                },
                "delivery_type": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "items_count": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "new",
                    "in_preparation",
                    "finalized",
                    "picked_up",
                    "deleted"
                  ]
                },
                "timeline": {
                  "$ref": "#/components/schemas/Timeline"
                },
                "closed_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "Închiderea mesei"
                },
                "items": {
                  "type": [
                    "array",
                    "null"
                  ],
                  "description": "null după purjarea rândului (90 de zile de la închidere)",
                  "items": {
                    "$ref": "#/components/schemas/OrderLine"
                  }
                }
              }
            }
          },
          "pagination": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Pagination"
              },
              {
                "$ref": "#/components/schemas/CursorPagination"
              }
            ]
          }
        }
      },
      "PosCancelledItems": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "server_time": {
            "type": "string",
            "format": "date-time"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer"
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "pos_id": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "pos_name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "inventory_id": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "operator": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "product": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "code": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "name": {
                      "type": "string"
                    }
                  }
                },
                "quantity": {
                  "type": "number"
                },
                "unit": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "list_price": {
                  "type": "number"
                },
                "discount": {
                  "type": "number"
                },
                "total": {
                  "type": "number"
                },
                "vat_percentage": {
                  "type": "number"
                },
                "type": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "category": {
                  "$ref": "#/components/schemas/CategoryRef"
                },
                "department": {
                  "$ref": "#/components/schemas/Ref"
                }
              }
            }
          },
          "pagination": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Pagination"
              },
              {
                "$ref": "#/components/schemas/CursorPagination"
              }
            ]
          }
        }
      },
      "StockMovements": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "server_time": {
            "type": "string",
            "format": "date-time"
          },
          "movements": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer"
                },
                "date_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "in",
                    "out"
                  ]
                },
                "quantity": {
                  "type": "number"
                },
                "product": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer"
                    },
                    "code": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "name": {
                      "type": "string"
                    },
                    "unit": {
                      "type": "string"
                    },
                    "inventory_id": {
                      "type": "integer"
                    }
                  }
                },
                "document": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "id": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "number": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pentru documentele cu serie și pentru inventar"
                    }
                  }
                },
                "acquisition_price": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "sale_price": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "sale_price_without_vat": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                }
              }
            }
          },
          "pagination": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Pagination"
              },
              {
                "$ref": "#/components/schemas/CursorPagination"
              }
            ]
          }
        }
      },
      "Recipes": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "server_time": {
            "type": "string",
            "format": "date-time"
          },
          "recipes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer"
                },
                "product": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer"
                    },
                    "code": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "name": {
                      "type": "string"
                    }
                  }
                },
                "yield": {
                  "type": "object",
                  "properties": {
                    "quantity": {
                      "type": "number"
                    },
                    "unit": {
                      "type": "string"
                    }
                  }
                },
                "decimals": {
                  "type": "integer"
                },
                "template": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer"
                    },
                    "name": {
                      "type": "string"
                    },
                    "from_inventory_id": {
                      "type": "integer"
                    },
                    "to_inventory_id": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "auto_generate": {
                      "type": "string"
                    }
                  }
                },
                "materials": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "integer"
                      },
                      "kind": {
                        "type": "string",
                        "enum": [
                          "product",
                          "cost"
                        ]
                      },
                      "product_id": {
                        "type": [
                          "integer",
                          "null"
                        ]
                      },
                      "code": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "name": {
                        "type": "string"
                      },
                      "quantity": {
                        "type": "number"
                      },
                      "loss_quantity": {
                        "type": "number"
                      },
                      "loss_type": {
                        "type": "string",
                        "enum": [
                          "value",
                          "percent"
                        ]
                      },
                      "total_quantity": {
                        "type": "number"
                      },
                      "unit": {
                        "type": "string"
                      },
                      "price": {
                        "type": [
                          "number",
                          "null"
                        ]
                      }
                    }
                  }
                },
                "updated_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "deleted_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "Doar în modul updated_since"
                }
              }
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "PosZReport": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "days": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "day": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-05-01"
                },
                "pos_id": {
                  "type": "integer",
                  "example": 42
                },
                "pos_name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "example": "POS Centru"
                },
                "inventory_id": {
                  "type": [
                    "integer",
                    "null"
                  ],
                  "example": 7,
                  "description": "null când POS-ul nu are gestiune mapată sau gestiunea a fost ștearsă."
                },
                "inventory_name": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "example": "Magazin Centru"
                },
                "z_number": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "example": "153",
                  "description": "Preluat din `cash_book_operations.document_number` (name='z_report'). null pentru ziua curentă (Raportul Z se generează la trecerea zilei) și pentru zilele fără Raport Z."
                },
                "receipts": {
                  "type": "integer",
                  "example": 42
                },
                "total": {
                  "type": "number",
                  "example": 1234.5
                },
                "cash": {
                  "type": "number",
                  "example": 800
                },
                "card": {
                  "type": "number",
                  "example": 400
                },
                "online": {
                  "type": "number",
                  "example": 0
                },
                "voucher": {
                  "type": "number",
                  "example": 0
                },
                "ticket": {
                  "type": "number",
                  "example": 34.5
                },
                "discount": {
                  "type": "number",
                  "example": 25,
                  "description": "Suma `pos_receipts.general_discount_value` + `pos_receipt_items.discount`."
                },
                "tip_value": {
                  "type": "number",
                  "example": 12
                },
                "sgr_quantity": {
                  "type": "number",
                  "example": 18,
                  "description": "Cantitate ambalaje SGR vândute."
                },
                "sgr_value": {
                  "type": "number",
                  "example": 9,
                  "description": "Calculat ca `sgr_quantity * 0.5` (garanția SGR fixă)."
                }
              }
            }
          }
        }
      },
      "CodedError": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "error"
          },
          "code": {
            "type": "string",
            "description": "Identificator stabil al erorii",
            "example": "proform_converted"
          },
          "message": {
            "type": "string",
            "example": "The proforma was already invoiced"
          }
        }
      },
      "ValidationError": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "example": "The client.name field is required."
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "example": {
              "client.name": [
                "The client.name field is required."
              ]
            }
          }
        }
      },
      "DocumentLine": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "code": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string",
            "example": "Serviciu consultanță"
          },
          "measuring_unit": {
            "type": [
              "string",
              "null"
            ],
            "example": "buc"
          },
          "quantity": {
            "type": "string",
            "example": "2.0000",
            "description": "4 zecimale"
          },
          "price_without_vat": {
            "type": "string",
            "example": "100.0000",
            "description": "Preț unitar, 4 zecimale"
          },
          "vat_percentage": {
            "type": "string",
            "example": "21.00"
          },
          "total_without_vat": {
            "type": "string",
            "example": "200.00",
            "description": "Sumă cu 2 zecimale"
          },
          "total_vat": {
            "type": "string",
            "example": "42.00",
            "description": "Sumă cu 2 zecimale"
          },
          "total": {
            "type": "string",
            "example": "242.00",
            "description": "Sumă cu 2 zecimale"
          }
        }
      },
      "InvoicePaymentRow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "source": {
            "type": "string",
            "enum": [
              "income",
              "receipt"
            ]
          },
          "type": {
            "type": "string",
            "example": "bank"
          },
          "date_at": {
            "type": "string",
            "format": "date"
          },
          "amount": {
            "type": "string",
            "example": "242.00",
            "description": "Sumă cu 2 zecimale"
          },
          "currency": {
            "type": "string",
            "example": "RON"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "DocumentDetail": {
        "type": "object",
        "description": "Totalurile unei linii sunt după reducerea de pe linie, deci liniile adună totalul documentului (cu excepția unei reduceri la nivel de document, puse din aplicație).",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          },
          "id": {
            "type": "integer",
            "example": 128917
          },
          "type": {
            "type": "string",
            "enum": [
              "proform",
              "invoice"
            ]
          },
          "number": {
            "type": "string",
            "example": "FF34"
          },
          "series_name": {
            "type": "string",
            "example": "FF"
          },
          "series_number": {
            "type": "string",
            "example": "0034",
            "description": "Șirul brut, cu zerourile de la început"
          },
          "date_at": {
            "type": "string",
            "format": "date"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "active": {
            "type": "boolean",
            "description": "`false` = anulat"
          },
          "currency": {
            "type": "string",
            "example": "RON"
          },
          "currency_rate": {
            "type": [
              "number",
              "null"
            ],
            "description": "Doar pentru alte monede decât RON"
          },
          "client": {
            "type": "object",
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "fiscal_code": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "total_net": {
            "type": "string",
            "example": "200.00",
            "description": "Sumă cu 2 zecimale"
          },
          "total_vat": {
            "type": "string",
            "example": "42.00",
            "description": "Sumă cu 2 zecimale"
          },
          "total": {
            "type": "string",
            "example": "242.00",
            "description": "Sumă cu 2 zecimale"
          },
          "pdf_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "`null` când documentul nu are cheie publică"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentLine"
            }
          },
          "invoice": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "integer"
              },
              "number": {
                "type": "string",
                "example": "FF35"
              }
            },
            "description": "Doar proformă: factura generată din ea (nu storno, nu ștearsă)"
          },
          "proform": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "integer"
              },
              "number": {
                "type": "string",
                "example": "FF35"
              }
            },
            "description": "Doar factură: proforma din care provine"
          },
          "payment_status": {
            "type": "string",
            "enum": [
              "unpaid",
              "partial",
              "paid"
            ],
            "description": "Doar factură"
          },
          "amount_due": {
            "type": "string",
            "example": "0.00",
            "description": "Doar factură: rest de plată, în moneda facturii"
          },
          "paid_amount": {
            "type": "string",
            "example": "242.00",
            "description": "Doar factură: suma încasată, în moneda facturii"
          },
          "payments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvoicePaymentRow"
            },
            "description": "Doar factură, în ordinea datei"
          },
          "existing": {
            "type": "boolean",
            "description": "Doar la facturare proformă și încasare: `true` când rezultatul exista deja"
          }
        }
      },
      "InvoicePaymentRequest": {
        "type": "object",
        "required": [
          "external_id",
          "type",
          "date_at",
          "amount",
          "currency"
        ],
        "properties": {
          "external_id": {
            "type": "string",
            "maxLength": 128,
            "description": "Cheia de idempotență a încasării",
            "example": "PAY-1001"
          },
          "type": {
            "type": "string",
            "enum": [
              "bank",
              "pos_receipt",
              "bank_card",
              "online_card",
              "post",
              "cec",
              "ticket_order",
              "repayment",
              "other_income"
            ],
            "example": "bank"
          },
          "date_at": {
            "type": "string",
            "format": "date",
            "description": "Cel mult azi",
            "example": "2026-10-07"
          },
          "amount": {
            "type": "number",
            "exclusiveMinimum": 0,
            "description": "Max. 2 zecimale; cel mult restul de plată + 1",
            "example": 242
          },
          "currency": {
            "type": "string",
            "enum": [
              "RON",
              "EUR"
            ],
            "description": "Trebuie să fie moneda facturii"
          }
        }
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tipuri de evenimente sau tipare: `*`, `pos.receipt.*`, `pos.receipt.created`."
          },
          "inventory_ids": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "description": "`null` = toate gestiunile."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "disabled"
            ]
          },
          "consecutive_failures": {
            "type": "integer"
          },
          "last_success_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "last_failure_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "disabled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "disabled_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "secret_rotating_until": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Până când se acceptă și secretul vechi, după o rotire."
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "event_id": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "resource_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "resource_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "delivering",
              "succeeded",
              "failed",
              "dead"
            ],
            "description": "`failed` se reîncearcă; `dead` = reîncercările s-au epuizat."
          },
          "attempts": {
            "type": "integer"
          },
          "next_attempt_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "response_code": {
            "type": [
              "integer",
              "null"
            ]
          },
          "response_excerpt": {
            "type": [
              "string",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "duration_ms": {
            "type": [
              "integer",
              "null"
            ]
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "payload": {
            "$ref": "#/components/schemas/WebhookEvent"
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "description": "Corpul fiecărei cereri trimise către webhook: un singur eveniment, fără obiecte încorporate.",
        "properties": {
          "id": {
            "type": "string",
            "example": "evt_01JAB3C4D5E6F7G8H9JKMNPQRS"
          },
          "type": {
            "type": "string",
            "enum": [
              "pos.receipt.created",
              "pos.receipt.updated",
              "pos.receipt.voided",
              "pos.order.created",
              "pos.order.status_changed",
              "pos.table.updated",
              "product.created",
              "product.updated",
              "product.deleted",
              "product.stock_changed"
            ]
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-07T14:02:11+03:00"
          },
          "company_id": {
            "type": "integer"
          },
          "inventory_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "data": {
            "type": "object",
            "description": "Bon: `receipt_id`, `kind`, `pos_id`. Comandă: `order_id`, `table_id`, `status` (+ `from` la schimbare de status). Masă: `table_id`, `status`.",
            "additionalProperties": true
          },
          "links": {
            "type": "object",
            "properties": {
              "self": {
                "type": "string",
                "format": "uri",
                "description": "Cererea cu care citiți starea curentă."
              }
            }
          }
        },
        "example": {
          "id": "evt_01JAB3C4D5E6F7G8H9JKMNPQRS",
          "type": "pos.receipt.updated",
          "occurred_at": "2026-10-07T14:02:11+03:00",
          "company_id": 829,
          "inventory_id": 1203,
          "data": {
            "receipt_id": 48213,
            "kind": "sale",
            "pos_id": 77
          },
          "links": {
            "self": "https://api.rezosoft.ro/v2/external/reports/pos/receipts?after_id=48212&per_page=1&kind=all"
          }
        }
      },
      "WebhookEndpointInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "Doar `https`, adresă publică."
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            },
            "example": [
              "pos.receipt.*",
              "pos.order.created"
            ]
          },
          "inventory_ids": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "integer"
            },
            "description": "Gestiunile urmărite; omis sau `null` = toate gestiunile cheii."
          }
        },
        "required": [
          "name",
          "url",
          "events"
        ]
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Cheie API invalidă sau lipsă",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string",
                  "example": "error"
                },
                "message": {
                  "type": "string",
                  "example": "Unauthorized"
                }
              }
            }
          }
        }
      },
      "BadRequest": {
        "description": "Date invalide sau lipsă",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resursa nu a fost găsită",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string",
                  "example": "error"
                },
                "message": {
                  "type": "string",
                  "example": "Document not found"
                }
              }
            }
          }
        }
      },
      "ServerError": {
        "description": "Eroare internă server",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string",
                  "example": "error"
                },
                "message": {
                  "type": "string",
                  "example": "Failed to send email"
                }
              }
            }
          }
        }
      },
      "ValidationError": {
        "description": "Date invalide. Fie erori de validare pe câmp (`errors`), fie o regulă de business cu `code` (vezi secțiunea Erori).",
        "content": {
          "application/json": {
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/ValidationError"
                },
                {
                  "$ref": "#/components/schemas/CodedError"
                }
              ]
            }
          }
        }
      },
      "Conflict": {
        "description": "`in_progress` (aceeași cerere este deja în curs sau conflict de concurență; reîncercați identic) sau stare incompatibilă (`proform_converted`, `proform_inactive`, `invoice_inactive`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/CodedError"
            }
          }
        }
      },
      "DocumentNotFound": {
        "description": "Documentul nu există, este șters sau aparține altei companii.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/CodedError"
            },
            "example": {
              "status": "error",
              "code": "not_found",
              "message": "Document not found"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Limita de 150 de cereri pe minut per IP a fost depășită.",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/X-RateLimit-Limit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/X-RateLimit-Remaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/X-RateLimit-Reset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "message": {
                  "type": "string",
                  "example": "Too Many Attempts."
                }
              }
            }
          }
        }
      }
    },
    "headers": {
      "X-RateLimit-Limit": {
        "schema": {
          "type": "integer"
        },
        "description": "Cereri permise pe minut"
      },
      "X-RateLimit-Remaining": {
        "schema": {
          "type": "integer"
        },
        "description": "Cereri rămase în minutul curent"
      },
      "Retry-After": {
        "schema": {
          "type": "integer"
        },
        "description": "Secunde de așteptat înainte de reîncercare"
      },
      "X-RateLimit-Reset": {
        "schema": {
          "type": "integer"
        },
        "description": "Momentul (Unix) la care limita se resetează"
      }
    }
  }
}
