{"openapi": "3.1.0", "info": {"title": "AEIG - API OPS", "version": "1.0.0", "description": "API de consultation des donnees OPS de l'AEIG.\n\n**Lecture seule.** Aucune route n'ecrit, ne modifie ni ne supprime.\n\nAuthentification : en-tete `Authorization: Bearer <cle>`. La cle est une cle API\nOdoo, generee depuis *Preferences > Securite du compte > Cles API* par le\ntitulaire du compte technique de l'API. Elle est nominative et expirable.\n\nLe compte porteur de la cle doit appartenir au groupe habilite a consommer\nl'API. Une cle emise sur un compte quelconque est refusee en `403` : c'est ce\nqui garantit que les lectures s'effectuent toujours avec des droits en lecture\nseule, et non avec ceux d'une personne.\n\nCette specification est generee depuis le registre du module `aeig_api` : elle\ndecrit l'etat reel des routes servies par ce serveur.", "license": {"name": "LGPL-3.0-or-later"}}, "servers": [{"url": "https://odoo.aeig.bj"}], "tags": [{"name": "electricity"}, {"name": "events"}, {"name": "fleet"}, {"name": "it"}, {"name": "purchase"}, {"name": "space"}, {"name": "stock"}, {"name": "travel"}], "paths": {"/api/v1/electricity/counters": {"get": {"tags": ["electricity"], "summary": "Compteurs electriques prepayes, avec solde et autonomie projetee.", "operationId": "list_electricity_counters", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : code asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, code, label, environment, current_kwh, last_reading_kwh, last_reading_date, days_since_reading, avg_daily_consumption, projected_autonomy_days, total_purchased_kwh, total_purchased_amount, currency, status"}, {"name": "status", "in": "query", "required": false, "schema": {"type": "string", "enum": ["ok", "warning", "critical", "no_data"]}, "description": "Statut d'alerte exact. (operateur applique : `=`). Valeurs : ok (OK), warning (Surveillance), critical (Critique), no_data (Aucune donnee)"}, {"name": "environment_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du site desservi. (operateur applique : `=`)"}, {"name": "code", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le code du compteur. (operateur applique : `ilike`)"}, {"name": "autonomy_below", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Compteurs dont l'autonomie projetee est inferieure ou egale a ce nombre de jours. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/ElectricityCounters"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/electricity/counters/{id}": {"get": {"tags": ["electricity"], "summary": "Compteurs electriques prepayes, avec solde et autonomie projetee. Enregistrement unique.", "operationId": "get_electricity_counters", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, code, label, environment, current_kwh, last_reading_kwh, last_reading_date, days_since_reading, avg_daily_consumption, projected_autonomy_days, total_purchased_kwh, total_purchased_amount, currency, status"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/ElectricityCounters"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/electricity/purchases": {"get": {"tags": ["electricity"], "summary": "Achats de credit electrique : kWh acquis, montant et prix unitaire.", "operationId": "list_electricity_purchases", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date_purchase desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, counter, counter_id, environment, date_purchase, purchased_kwh, amount, currency, price_per_kwh, state"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["active", "cancelled"]}, "description": "Etat exact de l'achat. (operateur applique : `=`). Valeurs : active (Actif), cancelled (Annule)"}, {"name": "counter_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du compteur credite. (operateur applique : `=`)"}, {"name": "environment_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du site desservi. (operateur applique : `=`)"}, {"name": "date_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Achats a partir de cette date (AAAA-MM-JJ). (operateur applique : `>=`)"}, {"name": "date_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Achats jusqu'a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/ElectricityPurchases"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/electricity/purchases/{id}": {"get": {"tags": ["electricity"], "summary": "Achats de credit electrique : kWh acquis, montant et prix unitaire. Enregistrement unique.", "operationId": "get_electricity_purchases", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, counter, counter_id, environment, date_purchase, purchased_kwh, amount, currency, price_per_kwh, state"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/ElectricityPurchases"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/electricity/readings": {"get": {"tags": ["electricity"], "summary": "Releves de compteur et consommation deduite entre deux releves.", "operationId": "list_electricity_readings", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date_reading desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, counter, counter_id, environment, date_reading, remaining_kwh, consumed_kwh, days_elapsed, daily_consumption, is_excluded_from_avg, note"}, {"name": "counter_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du compteur releve. (operateur applique : `=`)"}, {"name": "environment_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du site desservi. (operateur applique : `=`)"}, {"name": "date_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Releves a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "date_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Releves jusqu'a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/ElectricityReadings"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/electricity/readings/{id}": {"get": {"tags": ["electricity"], "summary": "Releves de compteur et consommation deduite entre deux releves. Enregistrement unique.", "operationId": "get_electricity_readings", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, counter, counter_id, environment, date_reading, remaining_kwh, consumed_kwh, days_elapsed, daily_consumption, is_excluded_from_avg, note"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/ElectricityReadings"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/events/events": {"get": {"tags": ["events"], "summary": "Evenements : dates, salle reservee, jauge et avancement de la checklist.", "operationId": "list_events_events", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date_begin desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, event_type, activity, stage, date_begin, date_end, is_ongoing, space, space_id, reservation_id, space_capacity, seats_max, seats_taken, seats_available, organizer, responsible, referent, origin, review_state, hidden_public, checklist_enabled, checklist_progress, company"}, {"name": "stage_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'etape du cycle de vie. (operateur applique : `=`)"}, {"name": "space_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'espace accueillant l'evenement. (operateur applique : `=`)"}, {"name": "review_state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["approved", "pending", "refused"]}, "description": "Etat exact de la revue. (operateur applique : `=`). Valeurs : approved (Approuve), pending (En attente), refused (Refuse)"}, {"name": "origin", "in": "query", "required": false, "schema": {"type": "string", "enum": ["internal", "public"]}, "description": "Canal d'origine exact. (operateur applique : `=`). Valeurs : internal (Interne), public (Formulaire public)"}, {"name": "hidden_public", "in": "query", "required": false, "schema": {"type": "boolean"}, "description": "Ne retenir que les evenements masques (true) ou visibles (false). (operateur applique : `=`)"}, {"name": "begin_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Evenements commencant a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "begin_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Evenements commencant au plus tard a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/EventsEvents"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/events/events/{id}": {"get": {"tags": ["events"], "summary": "Evenements : dates, salle reservee, jauge et avancement de la checklist. Enregistrement unique.", "operationId": "get_events_events", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, event_type, activity, stage, date_begin, date_end, is_ongoing, space, space_id, reservation_id, space_capacity, seats_max, seats_taken, seats_available, organizer, responsible, referent, origin, review_state, hidden_public, checklist_enabled, checklist_progress, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/EventsEvents"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/events/registrations": {"get": {"tags": ["events"], "summary": "Inscriptions aux evenements.", "operationId": "list_events_registrations", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : id desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, event_id, event, ticket, attendee, email, phone, booked_by, state, company"}, {"name": "event_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'evenement. (operateur applique : `=`)"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["draft", "open", "done", "cancel"]}, "description": "Etat exact : draft, open, done, cancel. (operateur applique : `=`). Valeurs : draft (Unconfirmed), open (Registered), done (Attended), cancel (Cancelled)"}, {"name": "partner_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du contact ayant reserve. (operateur applique : `=`)"}, {"name": "email", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur l'adresse electronique. (operateur applique : `ilike`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/EventsRegistrations"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/events/registrations/{id}": {"get": {"tags": ["events"], "summary": "Inscriptions aux evenements. Enregistrement unique.", "operationId": "get_events_registrations", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, event_id, event, ticket, attendee, email, phone, booked_by, state, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/EventsRegistrations"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/events/tasks": {"get": {"tags": ["events"], "summary": "Taches de la checklist de preparation d'un evenement.", "operationId": "list_events_tasks", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : event_id desc, sequence asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, event_id, event, name, done, assignee"}, {"name": "event_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'evenement. (operateur applique : `=`)"}, {"name": "done", "in": "query", "required": false, "schema": {"type": "boolean"}, "description": "Ne retenir que les taches accomplies (true) ou restantes (false). (operateur applique : `=`)"}, {"name": "assigned_user_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'utilisateur charge de la tache. (operateur applique : `=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/EventsTasks"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/events/tasks/{id}": {"get": {"tags": ["events"], "summary": "Taches de la checklist de preparation d'un evenement. Enregistrement unique.", "operationId": "get_events_tasks", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, event_id, event, name, done, assignee"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/EventsTasks"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/alerts": {"get": {"tags": ["fleet"], "summary": "Alertes d'echeance sur les vehicules : assurance, visite technique, permis.", "operationId": "list_fleet_alerts", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : due_date asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, vehicle, vehicle_id, type, due_date, state, handled_at, handled_by, reminder_days, company"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["pending", "handled", "late"]}, "description": "Etat exact de l'alerte. (operateur applique : `=`). Valeurs : pending (En attente), handled (Traitee), late (En retard)"}, {"name": "type", "in": "query", "required": false, "schema": {"type": "string", "enum": ["assurance", "controle_technique", "entretien_km", "permit", "custom"]}, "description": "Nature exacte de l'echeance. (operateur applique : `=`). Valeurs : assurance (Assurance), controle_technique (Controle technique), entretien_km (Entretien km), permit (Permis conducteur), custom (Personnalisee)"}, {"name": "vehicle_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du vehicule concerne. (operateur applique : `=`)"}, {"name": "due_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Alertes echeant au plus tard a cette date (AAAA-MM-JJ). (operateur applique : `<=`)"}, {"name": "due_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Alertes echeant a partir de cette date. (operateur applique : `>=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/FleetAlerts"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/alerts/{id}": {"get": {"tags": ["fleet"], "summary": "Alertes d'echeance sur les vehicules : assurance, visite technique, permis. Enregistrement unique.", "operationId": "get_fleet_alerts", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, vehicle, vehicle_id, type, due_date, state, handled_at, handled_by, reminder_days, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/FleetAlerts"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/fuel-logs": {"get": {"tags": ["fleet"], "summary": "Ravitaillements carburant, avec detection d'anomalie de consommation.", "operationId": "list_fleet_fuel_logs", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, vehicle, vehicle_id, driver, date, station, liters, price_per_liter, total_amount, currency, odometer, distance, consumption, is_anomaly, anomaly_severity, anomaly_reason, reviewed, company"}, {"name": "vehicle_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du vehicule ravitaille. (operateur applique : `=`)"}, {"name": "is_anomaly", "in": "query", "required": false, "schema": {"type": "boolean"}, "description": "Ne retenir que les pleins en anomalie (true) ou sains (false). (operateur applique : `=`)"}, {"name": "reviewed", "in": "query", "required": false, "schema": {"type": "boolean"}, "description": "Filtre sur le fait que l'anomalie ait ete revue. (operateur applique : `=`)"}, {"name": "date_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Pleins a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "date_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Pleins jusqu'a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/FleetFuelLogs"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/fuel-logs/{id}": {"get": {"tags": ["fleet"], "summary": "Ravitaillements carburant, avec detection d'anomalie de consommation. Enregistrement unique.", "operationId": "get_fleet_fuel_logs", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, vehicle, vehicle_id, driver, date, station, liters, price_per_liter, total_amount, currency, odometer, distance, consumption, is_anomaly, anomaly_severity, anomaly_reason, reviewed, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/FleetFuelLogs"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/incidents": {"get": {"tags": ["fleet"], "summary": "Incidents imputes aux conducteurs, avec gravite et cout d'impact.", "operationId": "list_fleet_incidents", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, vehicle, vehicle_id, driver, date, severity, cost, currency, company"}, {"name": "vehicle_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du vehicule concerne. (operateur applique : `=`)"}, {"name": "driver_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du conducteur mis en cause. (operateur applique : `=`)"}, {"name": "severity", "in": "query", "required": false, "schema": {"type": "string", "enum": ["minor", "moderate", "major", "critical"]}, "description": "Gravite exacte. (operateur applique : `=`). Valeurs : minor (Mineur), moderate (Modere), major (Majeur), critical (Critique)"}, {"name": "date_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Incidents a partir de cette date (AAAA-MM-JJ). (operateur applique : `>=`)"}, {"name": "date_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Incidents jusqu'a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/FleetIncidents"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/incidents/{id}": {"get": {"tags": ["fleet"], "summary": "Incidents imputes aux conducteurs, avec gravite et cout d'impact. Enregistrement unique.", "operationId": "get_fleet_incidents", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, vehicle, vehicle_id, driver, date, severity, cost, currency, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/FleetIncidents"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/locations": {"get": {"tags": ["fleet"], "summary": "Referentiel des lieux frequents utilises comme point de depart ou destination.", "operationId": "list_fleet_locations", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : sequence asc, name asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, code, address, city, country, latitude, longitude, is_default_pickup, company"}, {"name": "code", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Code court exact. (operateur applique : `=`)"}, {"name": "city", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur la ville. (operateur applique : `ilike`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/FleetLocations"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/locations/{id}": {"get": {"tags": ["fleet"], "summary": "Referentiel des lieux frequents utilises comme point de depart ou destination. Enregistrement unique.", "operationId": "get_fleet_locations", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, code, address, city, country, latitude, longitude, is_default_pickup, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/FleetLocations"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/reservations": {"get": {"tags": ["fleet"], "summary": "Demandes de reservation de vehicule et leur cycle de validation.", "operationId": "list_fleet_reservations", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : start desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, vehicle, vehicle_id, driver, requester, start, stop, duration, motive, pickup_location, destination, expected_km, attendees_count, origin, state, approver, approved_at, refusal_reason"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["draft", "pending", "approved", "in_progress", "done", "refused", "cancelled"]}, "description": "Etat exact : draft, pending, approved, in_progress, done, refused, cancelled. (operateur applique : `=`). Valeurs : draft (Brouillon), pending (En attente), approved (Approuvee), in_progress (En cours), done (Terminee), refused (Refusee), cancelled (Annulee)"}, {"name": "vehicle_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du vehicule reserve. (operateur applique : `=`)"}, {"name": "driver_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du conducteur designe. (operateur applique : `=`)"}, {"name": "start_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Reservations commencant a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "start_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Reservations commencant au plus tard a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/FleetReservations"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/reservations/{id}": {"get": {"tags": ["fleet"], "summary": "Demandes de reservation de vehicule et leur cycle de validation. Enregistrement unique.", "operationId": "get_fleet_reservations", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, vehicle, vehicle_id, driver, requester, start, stop, duration, motive, pickup_location, destination, expected_km, attendees_count, origin, state, approver, approved_at, refusal_reason"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/FleetReservations"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/services": {"get": {"tags": ["fleet"], "summary": "Entretiens et reparations des vehicules, avec leur cout.", "operationId": "list_fleet_services", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, vehicle, vehicle_id, date, description, service_type, service_kind, amount, total_cost, currency, odometer, next_service_odometer, vendor, invoice_ref, state, company"}, {"name": "vehicle_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du vehicule entretenu. (operateur applique : `=`)"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["new", "running", "done", "cancelled"]}, "description": "Etat exact de l'intervention. (operateur applique : `=`). Valeurs : new (New), running (Running), done (Done), cancelled (Cancelled)"}, {"name": "service_kind", "in": "query", "required": false, "schema": {"type": "string", "enum": ["preventive", "curative"]}, "description": "Categorie d'entretien exacte. (operateur applique : `=`). Valeurs : preventive (Preventif), curative (Curatif)"}, {"name": "date_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Interventions a partir de cette date (AAAA-MM-JJ). (operateur applique : `>=`)"}, {"name": "date_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Interventions jusqu'a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/FleetServices"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/services/{id}": {"get": {"tags": ["fleet"], "summary": "Entretiens et reparations des vehicules, avec leur cout. Enregistrement unique.", "operationId": "get_fleet_services", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, vehicle, vehicle_id, date, description, service_type, service_kind, amount, total_cost, currency, odometer, next_service_odometer, vendor, invoice_ref, state, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/FleetServices"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/trips": {"get": {"tags": ["fleet"], "summary": "Trajets realises : kilometrage reel, destination, imputation analytique.", "operationId": "list_fleet_trips", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, reservation_id, vehicle, vehicle_id, driver, date, date_start, date_end, odometer_start, odometer_end, distance, motive, destination, analytic_account, company"}, {"name": "vehicle_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du vehicule utilise. (operateur applique : `=`)"}, {"name": "driver_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du conducteur. (operateur applique : `=`)"}, {"name": "date_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Trajets a partir de cette date (AAAA-MM-JJ). (operateur applique : `>=`)"}, {"name": "date_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Trajets jusqu'a cette date (AAAA-MM-JJ). (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/FleetTrips"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/trips/{id}": {"get": {"tags": ["fleet"], "summary": "Trajets realises : kilometrage reel, destination, imputation analytique. Enregistrement unique.", "operationId": "get_fleet_trips", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, reservation_id, vehicle, vehicle_id, driver, date, date_start, date_end, odometer_start, odometer_end, distance, motive, destination, analytic_account, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/FleetTrips"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/vehicles": {"get": {"tags": ["fleet"], "summary": "Vehicules du parc automobile, avec leurs echeances reglementaires.", "operationId": "list_fleet_vehicles", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : license_plate asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, plate, model, vin, driver, seats, fuel_type, odometer, state, assignation_state, acquisition_date, insurance_expiry, technical_control_expiry, next_alert_date, avg_consumption, total_km_last_year, company"}, {"name": "assignation_state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["free", "assigned", "maintenance", "out_of_service", "sold"]}, "description": "Filtre sur l'etat d'affectation exact. (operateur applique : `=`). Valeurs : free (Disponible), assigned (Affecte), maintenance (En maintenance), out_of_service (Hors service), sold (Vendu)"}, {"name": "driver_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du conducteur affecte. (operateur applique : `=`)"}, {"name": "fuel_type", "in": "query", "required": false, "schema": {"type": "string", "enum": ["diesel", "gasoline", "full_hybrid", "plug_in_hybrid_diesel", "plug_in_hybrid_gasoline", "cng", "lpg", "hydrogen", "electric"]}, "description": "Type de carburant exact. (operateur applique : `=`). Valeurs : diesel (Diesel), gasoline (Gasoline), full_hybrid (Full Hybrid), plug_in_hybrid_diesel (Plug-in Hybrid Diesel), plug_in_hybrid_gasoline (Plug-in Hybrid Gasoline), cng (CNG), lpg (LPG), hydrogen (Hydrogen), electric (Electric)"}, {"name": "plate", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle, insensible a la casse, sur la plaque. (operateur applique : `ilike`)"}, {"name": "insurance_expiry_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Assurance expirant au plus tard a cette date (AAAA-MM-JJ). (operateur applique : `<=`)"}, {"name": "technical_control_expiry_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Visite technique expirant au plus tard a cette date (AAAA-MM-JJ). (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/FleetVehicles"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/fleet/vehicles/{id}": {"get": {"tags": ["fleet"], "summary": "Vehicules du parc automobile, avec leurs echeances reglementaires. Enregistrement unique.", "operationId": "get_fleet_vehicles", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, plate, model, vin, driver, seats, fuel_type, odometer, state, assignation_state, acquisition_date, insurance_expiry, technical_control_expiry, next_alert_date, avg_consumption, total_km_last_year, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/FleetVehicles"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/it/assets": {"get": {"tags": ["it"], "summary": "Materiels du parc informatique, identifies par numero de serie.", "operationId": "list_it_assets", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : name asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, serial, internal_ref, product, quantity, location, holder, lifecycle, company"}, {"name": "lifecycle", "in": "query", "required": false, "schema": {"type": "string", "enum": ["available", "assigned", "maintenance", "retired", "external"]}, "description": "Etape exacte du cycle de vie. (operateur applique : `=`). Valeurs : available (Disponible), assigned (Affecté), maintenance (Maintenance), retired (Réformé), external (Hors parc)"}, {"name": "holder_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de la personne detentrice. (operateur applique : `=`)"}, {"name": "serial", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le numero de serie. (operateur applique : `ilike`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/ItAssets"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/it/assets/{id}": {"get": {"tags": ["it"], "summary": "Materiels du parc informatique, identifies par numero de serie. Enregistrement unique.", "operationId": "get_it_assets", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, serial, internal_ref, product, quantity, location, holder, lifecycle, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/ItAssets"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/it/consumable-moves": {"get": {"tags": ["it"], "summary": "Sorties et retours de consommables informatiques.", "operationId": "list_it_consumable_moves", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, ticket_id, ticket_number, beneficiary, product, location, quantity, returned_quantity, remaining_quantity, state, date, handled_by"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["out", "partial", "returned"]}, "description": "Etat exact du mouvement. (operateur applique : `=`). Valeurs : out (Sortie), partial (Retour partiel), returned (Retournée)"}, {"name": "partner_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du beneficiaire. (operateur applique : `=`)"}, {"name": "product_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du consommable. (operateur applique : `=`)"}, {"name": "date_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Mouvements a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "date_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Mouvements jusqu'a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/ItConsumableMoves"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/it/consumable-moves/{id}": {"get": {"tags": ["it"], "summary": "Sorties et retours de consommables informatiques. Enregistrement unique.", "operationId": "get_it_consumable_moves", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, ticket_id, ticket_number, beneficiary, product, location, quantity, returned_quantity, remaining_quantity, state, date, handled_by"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/ItConsumableMoves"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/it/tickets": {"get": {"tags": ["it"], "summary": "Demandes adressees au service informatique et leur avancement.", "operationId": "list_it_tickets", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : id desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, number, name, category, type, stage, is_closed, team, assignee, requester, requester_email, priority, kanban_state, validation_state, assigned_date, closed_date, company"}, {"name": "is_closed", "in": "query", "required": false, "schema": {"type": "boolean"}, "description": "Ne retenir que les tickets clos (true) ou ouverts (false). (operateur applique : `=`)"}, {"name": "team_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'equipe en charge. (operateur applique : `=`)"}, {"name": "user_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du technicien assigne. (operateur applique : `=`)"}, {"name": "priority", "in": "query", "required": false, "schema": {"type": "string", "enum": ["0", "1", "2", "3"]}, "description": "Priorite exacte. (operateur applique : `=`). Valeurs : 0 (Basse), 1 (Normale), 2 (Haute), 3 (Critique)"}, {"name": "validation_state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["none", "to_validate", "validated", "rejected"]}, "description": "Etat exact de la validation hierarchique. (operateur applique : `=`). Valeurs : none (Non requise), to_validate (À valider), validated (Validée), rejected (Rejetée)"}, {"name": "number", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le numero de ticket. (operateur applique : `ilike`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/ItTickets"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/it/tickets/{id}": {"get": {"tags": ["it"], "summary": "Demandes adressees au service informatique et leur avancement. Enregistrement unique.", "operationId": "get_it_tickets", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, number, name, category, type, stage, is_closed, team, assignee, requester, requester_email, priority, kanban_state, validation_state, assigned_date, closed_date, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/ItTickets"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/purchase/order-lines": {"get": {"tags": ["purchase"], "summary": "Lignes de commande fournisseur : articles, quantites et prix unitaires.", "operationId": "list_purchase_order_lines", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : id desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, order_id, order_reference, description, product, product_id, quantity, uom, price_unit, price_subtotal, price_total, currency, qty_received, qty_invoiced, date_planned, state"}, {"name": "order_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de la commande. (operateur applique : `=`)"}, {"name": "product_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'article commande. (operateur applique : `=`)"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["draft", "sent", "to approve", "purchase", "cancel"]}, "description": "Etat exact de la commande. (operateur applique : `=`). Valeurs : draft (RFQ), sent (RFQ Sent), to approve (To Approve), purchase (Purchase Order), cancel (Cancelled)"}, {"name": "planned_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Lignes attendues a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "planned_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Lignes attendues jusqu'a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/PurchaseOrderLines"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/purchase/order-lines/{id}": {"get": {"tags": ["purchase"], "summary": "Lignes de commande fournisseur : articles, quantites et prix unitaires. Enregistrement unique.", "operationId": "get_purchase_order_lines", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, order_id, order_reference, description, product, product_id, quantity, uom, price_unit, price_subtotal, price_total, currency, qty_received, qty_invoiced, date_planned, state"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/PurchaseOrderLines"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/purchase/orders": {"get": {"tags": ["purchase"], "summary": "Commandes fournisseur : montants, echeances et etat de facturation.", "operationId": "list_purchase_orders", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date_order desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, vendor, vendor_id, vendor_reference, origin, date_order, date_approve, date_planned, amount_untaxed, amount_total, currency, state, invoice_status, buyer, company"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["draft", "sent", "to approve", "purchase", "cancel"]}, "description": "Etat exact : draft, sent, purchase, done, cancel. (operateur applique : `=`). Valeurs : draft (RFQ), sent (RFQ Sent), to approve (To Approve), purchase (Purchase Order), cancel (Cancelled)"}, {"name": "invoice_status", "in": "query", "required": false, "schema": {"type": "string", "enum": ["no", "to invoice", "invoiced"]}, "description": "Etat de facturation exact. (operateur applique : `=`). Valeurs : no (Nothing to Bill), to invoice (Waiting Bills), invoiced (Fully Billed)"}, {"name": "vendor_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du fournisseur. (operateur applique : `=`)"}, {"name": "user_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'acheteur en charge. (operateur applique : `=`)"}, {"name": "origin", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le document d'origine. (operateur applique : `ilike`)"}, {"name": "ordered_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Commandes a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "ordered_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Commandes jusqu'a cette date. (operateur applique : `<=`)"}, {"name": "amount_above", "in": "query", "required": false, "schema": {"type": "number"}, "description": "Commandes dont le montant TTC est superieur ou egal a cette valeur. (operateur applique : `>=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/PurchaseOrders"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/purchase/orders/{id}": {"get": {"tags": ["purchase"], "summary": "Commandes fournisseur : montants, echeances et etat de facturation. Enregistrement unique.", "operationId": "get_purchase_orders", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, vendor, vendor_id, vendor_reference, origin, date_order, date_approve, date_planned, amount_untaxed, amount_total, currency, state, invoice_status, buyer, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/PurchaseOrders"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/activities": {"get": {"tags": ["space"], "summary": "Referentiel des natures d'activite pouvant motiver une reservation.", "operationId": "list_space_activities", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : sequence asc, name asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, code, default_duration"}, {"name": "code", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Code court exact. (operateur applique : `=`)"}, {"name": "name", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le nom. (operateur applique : `ilike`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/SpaceActivities"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/activities/{id}": {"get": {"tags": ["space"], "summary": "Referentiel des natures d'activite pouvant motiver une reservation. Enregistrement unique.", "operationId": "get_space_activities", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, code, default_duration"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/SpaceActivities"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/categories": {"get": {"tags": ["space"], "summary": "Referentiel des categories d'espaces.", "operationId": "list_space_categories", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : sequence asc, name asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, description"}, {"name": "name", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le nom. (operateur applique : `ilike`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/SpaceCategories"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/categories/{id}": {"get": {"tags": ["space"], "summary": "Referentiel des categories d'espaces. Enregistrement unique.", "operationId": "get_space_categories", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, description"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/SpaceCategories"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/equipments": {"get": {"tags": ["space"], "summary": "Referentiel des equipements installables dans un espace.", "operationId": "list_space_equipments", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : name asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, code, category, description"}, {"name": "category_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de la categorie d'equipement. (operateur applique : `=`)"}, {"name": "name", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le nom. (operateur applique : `ilike`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/SpaceEquipments"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/equipments/{id}": {"get": {"tags": ["space"], "summary": "Referentiel des equipements installables dans un espace. Enregistrement unique.", "operationId": "get_space_equipments", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, code, category, description"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/SpaceEquipments"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/maintenances": {"get": {"tags": ["space"], "summary": "Operations de maintenance sur les espaces, bloquantes ou non.", "operationId": "list_space_maintenances", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : start desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, space, space_id, start, stop, state, category, technician, external_technician, blocks_reservations, check_progress, company"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["planned", "in_progress", "done", "cancelled"]}, "description": "Etat exact de l'operation. (operateur applique : `=`). Valeurs : planned (Planifiee), in_progress (En cours), done (Terminee), cancelled (Annulee)"}, {"name": "space_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'espace concerne. (operateur applique : `=`)"}, {"name": "category", "in": "query", "required": false, "schema": {"type": "string", "enum": ["preventive", "curative", "cleaning", "other"]}, "description": "Categorie de maintenance exacte. (operateur applique : `=`). Valeurs : preventive (Preventive), curative (Curative), cleaning (Nettoyage), other (Autre)"}, {"name": "blocks_reservations", "in": "query", "required": false, "schema": {"type": "boolean"}, "description": "Ne retenir que les operations bloquantes (true) ou non (false). (operateur applique : `=`)"}, {"name": "start_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Operations commencant a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "start_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Operations commencant au plus tard a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/SpaceMaintenances"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/maintenances/{id}": {"get": {"tags": ["space"], "summary": "Operations de maintenance sur les espaces, bloquantes ou non. Enregistrement unique.", "operationId": "get_space_maintenances", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, space, space_id, start, stop, state, category, technician, external_technician, blocks_reservations, check_progress, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/SpaceMaintenances"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/reservations": {"get": {"tags": ["space"], "summary": "Reservations d'espaces et leur cycle de validation.", "operationId": "list_space_reservations", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : start desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, space, space_id, activity, start, stop, duration, attendees_expected, attendees_actual, requester, origin, state, approver, approved_at, refusal_reason, cancellation_reason, check_in_at, check_out_at, company"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["pending", "approved", "refused", "cancelled", "done"]}, "description": "Etat exact de la reservation. (operateur applique : `=`). Valeurs : pending (En attente), approved (Approuvee), refused (Refusee), cancelled (Annulee), done (Terminee)"}, {"name": "space_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'espace reserve. (operateur applique : `=`)"}, {"name": "activity_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de la nature d'activite. (operateur applique : `=`)"}, {"name": "origin", "in": "query", "required": false, "schema": {"type": "string", "enum": ["internal", "public"]}, "description": "Canal d'origine exact. (operateur applique : `=`). Valeurs : internal (Interne), public (Public)"}, {"name": "start_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Reservations commencant a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "start_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Reservations commencant au plus tard a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/SpaceReservations"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/reservations/{id}": {"get": {"tags": ["space"], "summary": "Reservations d'espaces et leur cycle de validation. Enregistrement unique.", "operationId": "get_space_reservations", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, space, space_id, activity, start, stop, duration, attendees_expected, attendees_actual, requester, origin, state, approver, approved_at, refusal_reason, cancellation_reason, check_in_at, check_out_at, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/SpaceReservations"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/sites": {"get": {"tags": ["space"], "summary": "Sites hebergeant les espaces reservables, organises en arborescence.", "operationId": "list_space_sites", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : complete_name asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, complete_name, code, parent_id, address, company"}, {"name": "code", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Code court exact. (operateur applique : `=`)"}, {"name": "parent_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du site parent. (operateur applique : `=`)"}, {"name": "name", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le nom. (operateur applique : `ilike`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/SpaceSites"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/sites/{id}": {"get": {"tags": ["space"], "summary": "Sites hebergeant les espaces reservables, organises en arborescence. Enregistrement unique.", "operationId": "get_space_sites", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, complete_name, code, parent_id, address, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/SpaceSites"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/spaces": {"get": {"tags": ["space"], "summary": "Espaces reservables : salles, bureaux, capacites et tarifs.", "operationId": "list_space_spaces", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : sequence asc, name asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, code, site, site_id, state, location, floor, surface, capacity, hourly_price, currency, categories, public_visibility, approval_required, min_lead_hours, max_lead_days, cancel_deadline_hours, company"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["available", "restricted", "closed"]}, "description": "Etat exact de l'espace. (operateur applique : `=`). Valeurs : available (Disponible), restricted (Restreint), closed (Ferme)"}, {"name": "site_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du site hebergeant l'espace. (operateur applique : `=`)"}, {"name": "capacity_min", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Capacite d'accueil minimale requise. (operateur applique : `>=`)"}, {"name": "approval_required", "in": "query", "required": false, "schema": {"type": "boolean"}, "description": "Ne retenir que les espaces soumis (true) ou non (false) a approbation. (operateur applique : `=`)"}, {"name": "name", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le nom. (operateur applique : `ilike`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/SpaceSpaces"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/space/spaces/{id}": {"get": {"tags": ["space"], "summary": "Espaces reservables : salles, bureaux, capacites et tarifs. Enregistrement unique.", "operationId": "get_space_spaces", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, code, site, site_id, state, location, floor, surface, capacity, hourly_price, currency, categories, public_visibility, approval_required, min_lead_hours, max_lead_days, cancel_deadline_hours, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/SpaceSpaces"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/stock/pickings": {"get": {"tags": ["stock"], "summary": "Transferts de stock : receptions, livraisons et mouvements internes.", "operationId": "list_stock_pickings", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : scheduled_date desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, origin, picking_type, partner, source_location, destination_location, scheduled_date, date_done, priority, state, company"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["draft", "waiting", "confirmed", "assigned", "done", "cancel"]}, "description": "Etat exact : draft, waiting, confirmed, assigned, done, cancel. (operateur applique : `=`). Valeurs : draft (Draft), waiting (Waiting Another Operation), confirmed (Waiting), assigned (Ready), done (Done), cancel (Cancelled)"}, {"name": "partner_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du contact associe. (operateur applique : `=`)"}, {"name": "origin", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le document d'origine. (operateur applique : `ilike`)"}, {"name": "scheduled_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Transferts prevus a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "scheduled_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Transferts prevus jusqu'a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/StockPickings"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/stock/pickings/{id}": {"get": {"tags": ["stock"], "summary": "Transferts de stock : receptions, livraisons et mouvements internes. Enregistrement unique.", "operationId": "get_stock_pickings", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, origin, picking_type, partner, source_location, destination_location, scheduled_date, date_done, priority, state, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/StockPickings"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/perdiem-rates": {"get": {"tags": ["travel"], "summary": "Bareme des per diem par pays et par ville.", "operationId": "list_travel_perdiem_rates", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : id desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, country, country_id, city, daily_rate, currency, has_tiers, environment, note, company"}, {"name": "country_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du pays couvert. (operateur applique : `=`)"}, {"name": "city_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de la ville couverte. (operateur applique : `=`)"}, {"name": "environment_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'environnement de bareme. (operateur applique : `=`)"}, {"name": "has_tiers", "in": "query", "required": false, "schema": {"type": "boolean"}, "description": "Ne retenir que les baremes avec (true) ou sans (false) paliers. (operateur applique : `=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/TravelPerdiemRates"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/perdiem-rates/{id}": {"get": {"tags": ["travel"], "summary": "Bareme des per diem par pays et par ville. Enregistrement unique.", "operationId": "get_travel_perdiem_rates", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, country, country_id, city, daily_rate, currency, has_tiers, environment, note, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/TravelPerdiemRates"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/perdiem-requests": {"get": {"tags": ["travel"], "summary": "Demandes de per diem : bareme applique, abattements et montant du.", "operationId": "list_travel_perdiem_requests", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date_debut desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, name, state, trip_id, trip_reference, traveler, mission_object, country, city, date_start, date_end, duration_days, prorata_start, prorata_end, calc_model, daily_rate, rate_id, duration_abatement_pct, duration_abatement_amount, total_amount, financing_type, partner, partner_share_pct, amount_company, amount_partner, currency, environment, validator, submit_date, approve_date, reject_date, company"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["draft", "pending", "approved", "rejected", "cancelled"]}, "description": "Etat exact de la demande. (operateur applique : `=`). Valeurs : draft (Brouillon), pending (En attente), approved (Approuvée), rejected (Rejetée), cancelled (Annulée)"}, {"name": "trip_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de la mission rattachee. (operateur applique : `=`)"}, {"name": "traveler_user_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'utilisateur beneficiaire. (operateur applique : `=`)"}, {"name": "country_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du pays du sejour. (operateur applique : `=`)"}, {"name": "financing_type", "in": "query", "required": false, "schema": {"type": "string", "enum": ["aeig", "partner", "mixed"]}, "description": "Mode de financement exact. (operateur applique : `=`). Valeurs : aeig (AEIG uniquement), partner (Partenaire uniquement), mixed (Mixte AEIG / partenaire)"}, {"name": "start_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sejours commencant a partir de cette date (AAAA-MM-JJ). (operateur applique : `>=`)"}, {"name": "start_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sejours commencant au plus tard a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/TravelPerdiemRequests"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/perdiem-requests/{id}": {"get": {"tags": ["travel"], "summary": "Demandes de per diem : bareme applique, abattements et montant du. Enregistrement unique.", "operationId": "get_travel_perdiem_requests", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, name, state, trip_id, trip_reference, traveler, mission_object, country, city, date_start, date_end, duration_days, prorata_start, prorata_end, calc_model, daily_rate, rate_id, duration_abatement_pct, duration_abatement_amount, total_amount, financing_type, partner, partner_share_pct, amount_company, amount_partner, currency, environment, validator, submit_date, approve_date, reject_date, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/TravelPerdiemRequests"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/trip-expenses": {"get": {"tags": ["travel"], "summary": "Frais rattaches a une mission, hors per diem.", "operationId": "list_travel_trip_expenses", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : id desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, trip_id, trip_reference, cost, currency, notes"}, {"name": "trip_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de la mission rattachee. (operateur applique : `=`)"}, {"name": "cost_above", "in": "query", "required": false, "schema": {"type": "number"}, "description": "Frais dont le montant est superieur ou egal a cette valeur. (operateur applique : `>=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/TravelTripExpenses"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/trip-expenses/{id}": {"get": {"tags": ["travel"], "summary": "Frais rattaches a une mission, hors per diem. Enregistrement unique.", "operationId": "get_travel_trip_expenses", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, trip_id, trip_reference, cost, currency, notes"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/TravelTripExpenses"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/trip-stages": {"get": {"tags": ["travel"], "summary": "Etapes d'une mission : trajets successifs, aller et retour.", "operationId": "list_travel_trip_stages", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : trip_id desc, sequence asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, trip_id, trip_reference, position, is_return_leg, city_from, country_from, city_to, country_to, date_from, date_to, duration_days, has_transport"}, {"name": "trip_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de la mission. (operateur applique : `=`)"}, {"name": "is_return_leg", "in": "query", "required": false, "schema": {"type": "boolean"}, "description": "Ne retenir que les trajets retour (true) ou aller (false). (operateur applique : `=`)"}, {"name": "country_to_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du pays d'arrivee. (operateur applique : `=`)"}, {"name": "date_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Etapes commencant a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "date_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Etapes commencant au plus tard a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/TravelTripStages"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/trip-stages/{id}": {"get": {"tags": ["travel"], "summary": "Etapes d'une mission : trajets successifs, aller et retour. Enregistrement unique.", "operationId": "get_travel_trip_stages", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, trip_id, trip_reference, position, is_return_leg, city_from, country_from, city_to, country_to, date_from, date_to, duration_days, has_transport"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/TravelTripStages"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/trip-types": {"get": {"tags": ["travel"], "summary": "Referentiel des types de mission.", "operationId": "list_travel_trip_types", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : sequence asc, name asc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, code, description"}, {"name": "code", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Code court exact. (operateur applique : `=`)"}, {"name": "name", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Recherche partielle sur le nom. (operateur applique : `ilike`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/TravelTripTypes"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/trip-types/{id}": {"get": {"tags": ["travel"], "summary": "Referentiel des types de mission. Enregistrement unique.", "operationId": "get_travel_trip_types", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, name, code, description"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/TravelTripTypes"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/trips": {"get": {"tags": ["travel"], "summary": "Missions et deplacements : trajet, dates et cout complet.", "operationId": "list_travel_trips", "parameters": [{"name": "limit", "in": "query", "required": false, "schema": {"type": "integer", "default": 50, "maximum": 200, "minimum": 1}, "description": "Taille de page. Valeur par defaut 50, plafonnee a 200."}, {"name": "offset", "in": "query", "required": false, "schema": {"type": "integer", "default": 0, "minimum": 0}, "description": "Decalage pour la pagination. Se degrade en profondeur : preferez `since_id` pour balayer une ressource entiere."}, {"name": "since_id", "in": "query", "required": false, "schema": {"type": "integer", "minimum": 0}, "description": "Pagination par curseur : ne retourne que les enregistrements dont l'identifiant est superieur a cette valeur, tries par identifiant croissant. Cout constant quelle que soit la profondeur. La reponse renvoie `meta.next_since_id`, a repasser tel quel pour la page suivante ; il vaut `null` quand il n'y a plus rien. Ne se combine ni avec `offset` ni avec `order`."}, {"name": "total", "in": "query", "required": false, "schema": {"type": "boolean", "default": true}, "description": "Mettre a `false` pour omettre `meta.total`. Le comptage ignore `limit` et parcourt toute la table : le desactiver allege nettement un balayage complet."}, {"name": "order", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Tri, sous la forme `champ` ou `champ desc`. Seuls les champs exposes sont acceptes. Tri par defaut : date_start desc."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, name, state, traveler, traveler_name, traveler_email, trip_type, description, city_departure, country_departure, city_destination, country_destination, date_submission, date_start, date_end, duration_days, transport_cost, accommodation_cost_total, per_diem_total, insurance_premium, currency, has_per_diem, has_return_stage, company"}, {"name": "state", "in": "query", "required": false, "schema": {"type": "string", "enum": ["draft", "pending", "planned", "in_progress", "done", "cancelled"]}, "description": "Etat exact de la mission. (operateur applique : `=`). Valeurs : draft (Brouillon), pending (En attente validation), planned (Planifié), in_progress (En cours), done (Terminé), cancelled (Annulé)"}, {"name": "traveler_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant de l'utilisateur voyageur. (operateur applique : `=`)"}, {"name": "trip_type_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du type de mission. (operateur applique : `=`)"}, {"name": "country_destination_id", "in": "query", "required": false, "schema": {"type": "integer"}, "description": "Identifiant du pays de destination. (operateur applique : `=`)"}, {"name": "has_per_diem", "in": "query", "required": false, "schema": {"type": "boolean"}, "description": "Ne retenir que les missions avec (true) ou sans (false) per diem. (operateur applique : `=`)"}, {"name": "start_after", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Missions commencant a partir de cette date (AAAA-MM-JJ ou ISO 8601). (operateur applique : `>=`)"}, {"name": "start_before", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Missions commencant au plus tard a cette date. (operateur applique : `<=`)"}], "responses": {"200": {"description": "Liste paginee.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/TravelTrips"}}, "meta": {"$ref": "#/components/schemas/Meta"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Compte non membre du groupe autorise a consommer l'API, ou droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Ressource inconnue.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Valeur de filtre non exploitable.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}, "/api/v1/travel/trips/{id}": {"get": {"tags": ["travel"], "summary": "Missions et deplacements : trajet, dates et cout complet. Enregistrement unique.", "operationId": "get_travel_trips", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}, "description": "Identifiant technique Odoo de l'enregistrement."}, {"name": "fields", "in": "query", "required": false, "schema": {"type": "string"}, "description": "Sous-ensemble de champs a retourner, separes par des virgules. Par defaut, tous les champs listes. Champs disponibles : id, reference, name, state, traveler, traveler_name, traveler_email, trip_type, description, city_departure, country_departure, city_destination, country_destination, date_submission, date_start, date_end, duration_days, transport_cost, accommodation_cost_total, per_diem_total, insurance_premium, currency, has_per_diem, has_return_stage, company"}], "responses": {"200": {"description": "Enregistrement.", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/TravelTrips"}}}}}}, "401": {"description": "Cle API absente ou invalide.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Droits insuffisants sur le modele sous-jacent.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Enregistrement introuvable ou hors du perimetre expose.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}}}}, "components": {"securitySchemes": {"apiKey": {"type": "http", "scheme": "bearer", "description": "Cle API Odoo transmise en Bearer."}}, "schemas": {"Error": {"type": "object", "properties": {"error": {"type": "object", "properties": {"code": {"type": "string", "description": "Code d'erreur stable."}, "message": {"type": "string", "description": "Message lisible."}}, "required": ["code", "message"]}}, "required": ["error"]}, "Meta": {"type": "object", "description": "Metadonnees de pagination.", "properties": {"resource": {"type": "string", "description": "Nom de la ressource interrogee."}, "limit": {"type": "integer", "description": "Taille de page effectivement appliquee."}, "total": {"type": "integer", "description": "Nombre total d'enregistrements correspondant aux filtres. Absent si `total=false`."}, "offset": {"type": "integer", "description": "Decalage applique. Absent en pagination par curseur."}, "since_id": {"type": "integer", "description": "Curseur transmis par l'appelant. Present uniquement en pagination par curseur."}, "next_since_id": {"type": ["integer", "null"], "description": "Valeur a repasser en `since_id` pour la page suivante ; `null` quand il n'y a plus rien. Present uniquement en pagination par curseur."}}}, "ElectricityCounters": {"type": "object", "description": "Compteurs electriques prepayes, avec solde et autonomie projetee.", "properties": {"id": {"description": "Identifiant technique Odoo du compteur.", "type": ["integer", "null"]}, "code": {"description": "Code du compteur.", "type": ["string", "null"]}, "label": {"description": "Libelle du compteur.", "type": ["string", "null"]}, "environment": {"description": "Site ou environnement desservi.", "type": ["string", "null"]}, "current_kwh": {"description": "Solde courant estime, en kWh.", "type": ["number", "null"]}, "last_reading_kwh": {"description": "Solde au dernier releve, en kWh.", "type": ["number", "null"]}, "last_reading_date": {"description": "Date et heure du dernier releve.", "type": ["string", "null"], "format": "date-time"}, "days_since_reading": {"description": "Nombre de jours ecoules depuis le dernier releve.", "type": ["integer", "null"]}, "avg_daily_consumption": {"description": "Consommation journaliere moyenne, en kWh.", "type": ["number", "null"]}, "projected_autonomy_days": {"description": "Autonomie restante projetee, en jours.", "type": ["integer", "null"]}, "total_purchased_kwh": {"description": "Cumul des kWh achetes.", "type": ["number", "null"]}, "total_purchased_amount": {"description": "Cumul des montants achetes.", "type": ["number", "null"]}, "currency": {"description": "Devise des montants.", "type": ["string", "null"]}, "status": {"description": "Statut d'alerte du compteur selon l'autonomie restante. Valeurs : ok (OK), warning (Surveillance), critical (Critique), no_data (Aucune donnee)", "type": ["string", "null"], "enum": ["ok", "warning", "critical", "no_data", null]}}}, "ElectricityPurchases": {"type": "object", "description": "Achats de credit electrique : kWh acquis, montant et prix unitaire.", "properties": {"id": {"description": "Identifiant technique Odoo de l'achat.", "type": ["integer", "null"]}, "reference": {"description": "Reference de l'achat.", "type": ["string", "null"]}, "counter": {"description": "Code du compteur credite.", "type": ["string", "null"]}, "counter_id": {"description": "Identifiant du compteur credite.", "type": ["integer", "null"]}, "environment": {"description": "Site ou environnement desservi.", "type": ["string", "null"]}, "date_purchase": {"description": "Date de l'achat.", "type": ["string", "null"], "format": "date"}, "purchased_kwh": {"description": "Quantite de kWh achetee.", "type": ["number", "null"]}, "amount": {"description": "Montant paye.", "type": ["number", "null"]}, "currency": {"description": "Devise du montant.", "type": ["string", "null"]}, "price_per_kwh": {"description": "Prix unitaire au kWh.", "type": ["number", "null"]}, "state": {"description": "Etat de l'achat. Valeurs : active (Actif), cancelled (Annule)", "type": ["string", "null"], "enum": ["active", "cancelled", null]}}}, "ElectricityReadings": {"type": "object", "description": "Releves de compteur et consommation deduite entre deux releves.", "properties": {"id": {"description": "Identifiant technique Odoo du releve.", "type": ["integer", "null"]}, "counter": {"description": "Code du compteur releve.", "type": ["string", "null"]}, "counter_id": {"description": "Identifiant du compteur releve.", "type": ["integer", "null"]}, "environment": {"description": "Site ou environnement desservi.", "type": ["string", "null"]}, "date_reading": {"description": "Date et heure du releve.", "type": ["string", "null"], "format": "date-time"}, "remaining_kwh": {"description": "Solde restant releve, en kWh.", "type": ["number", "null"]}, "consumed_kwh": {"description": "Consommation depuis le releve precedent, en kWh.", "type": ["number", "null"]}, "days_elapsed": {"description": "Nombre de jours ecoules depuis le releve precedent.", "type": ["number", "null"]}, "daily_consumption": {"description": "Consommation journaliere moyenne sur l'intervalle, en kWh.", "type": ["number", "null"]}, "is_excluded_from_avg": {"description": "Vrai si le releve est exclu du calcul des moyennes.", "type": ["boolean", "null"]}, "note": {"description": "Note libre saisie lors du releve.", "type": ["string", "null"]}}}, "EventsEvents": {"type": "object", "description": "Evenements : dates, salle reservee, jauge et avancement de la checklist.", "properties": {"id": {"description": "Identifiant technique Odoo de l'evenement.", "type": ["integer", "null"]}, "name": {"description": "Intitule de l'evenement.", "type": ["string", "null"]}, "event_type": {"description": "Modele d'evenement applique.", "type": ["string", "null"]}, "activity": {"description": "Nature de l'evenement.", "type": ["string", "null"]}, "stage": {"description": "Etape du cycle de vie de l'evenement.", "type": ["string", "null"]}, "date_begin": {"description": "Debut de l'evenement.", "type": ["string", "null"], "format": "date-time"}, "date_end": {"description": "Fin de l'evenement.", "type": ["string", "null"], "format": "date-time"}, "is_ongoing": {"description": "Vrai si l'evenement est en cours a l'instant de la requete.", "type": ["boolean", "null"]}, "space": {"description": "Espace accueillant l'evenement.", "type": ["string", "null"]}, "space_id": {"description": "Identifiant de l'espace accueillant l'evenement.", "type": ["integer", "null"]}, "reservation_id": {"description": "Identifiant de la reservation d'espace associee.", "type": ["integer", "null"]}, "space_capacity": {"description": "Capacite de l'espace retenu.", "type": ["integer", "null"]}, "seats_max": {"description": "Jauge maximale de l'evenement.", "type": ["integer", "null"]}, "seats_taken": {"description": "Nombre de places deja prises.", "type": ["integer", "null"]}, "seats_available": {"description": "Nombre de places encore disponibles.", "type": ["integer", "null"]}, "organizer": {"description": "Organisateur de l'evenement.", "type": ["string", "null"]}, "responsible": {"description": "Utilisateur responsable.", "type": ["string", "null"]}, "referent": {"description": "Referent designe pour l'evenement.", "type": ["string", "null"]}, "origin": {"description": "Canal d'origine de la demande d'evenement. Valeurs : internal (Interne), public (Formulaire public)", "type": ["string", "null"], "enum": ["internal", "public", null]}, "review_state": {"description": "Etat de la revue de la demande. Valeurs : approved (Approuve), pending (En attente), refused (Refuse)", "type": ["string", "null"], "enum": ["approved", "pending", "refused", null]}, "hidden_public": {"description": "Vrai si l'evenement est masque sur le site public.", "type": ["boolean", "null"]}, "checklist_enabled": {"description": "Vrai si une checklist de preparation est activee.", "type": ["boolean", "null"]}, "checklist_progress": {"description": "Avancement de la checklist, en pourcentage.", "type": ["number", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "EventsRegistrations": {"type": "object", "description": "Inscriptions aux evenements.", "properties": {"id": {"description": "Identifiant technique Odoo de l'inscription.", "type": ["integer", "null"]}, "event_id": {"description": "Identifiant de l'evenement.", "type": ["integer", "null"]}, "event": {"description": "Intitule de l'evenement.", "type": ["string", "null"]}, "ticket": {"description": "Categorie de billet retenue.", "type": ["string", "null"]}, "attendee": {"description": "Nom du participant.", "type": ["string", "null"]}, "email": {"description": "Adresse electronique du participant.", "type": ["string", "null"]}, "phone": {"description": "Numero de telephone du participant.", "type": ["string", "null"]}, "booked_by": {"description": "Contact ayant effectue la reservation.", "type": ["string", "null"]}, "state": {"description": "Etat de l'inscription. Valeurs : draft (Unconfirmed), open (Registered), done (Attended), cancel (Cancelled)", "type": ["string", "null"], "enum": ["draft", "open", "done", "cancel", null]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "EventsTasks": {"type": "object", "description": "Taches de la checklist de preparation d'un evenement.", "properties": {"id": {"description": "Identifiant technique Odoo de la tache.", "type": ["integer", "null"]}, "event_id": {"description": "Identifiant de l'evenement.", "type": ["integer", "null"]}, "event": {"description": "Intitule de l'evenement.", "type": ["string", "null"]}, "name": {"description": "Intitule de la tache.", "type": ["string", "null"]}, "done": {"description": "Vrai si la tache est accomplie.", "type": ["boolean", "null"]}, "assignee": {"description": "Utilisateur charge de la tache.", "type": ["string", "null"]}}}, "FleetAlerts": {"type": "object", "description": "Alertes d'echeance sur les vehicules : assurance, visite technique, permis.", "properties": {"id": {"description": "Identifiant technique Odoo de l'alerte.", "type": ["integer", "null"]}, "name": {"description": "Intitule de l'alerte.", "type": ["string", "null"]}, "vehicle": {"description": "Vehicule concerne.", "type": ["string", "null"]}, "vehicle_id": {"description": "Identifiant du vehicule concerne.", "type": ["integer", "null"]}, "type": {"description": "Nature de l'echeance surveillee. Valeurs : assurance (Assurance), controle_technique (Controle technique), entretien_km (Entretien km), permit (Permis conducteur), custom (Personnalisee)", "type": ["string", "null"], "enum": ["assurance", "controle_technique", "entretien_km", "permit", "custom", null]}, "due_date": {"description": "Date d'echeance.", "type": ["string", "null"], "format": "date"}, "state": {"description": "Etat de traitement de l'alerte. Valeurs : pending (En attente), handled (Traitee), late (En retard)", "type": ["string", "null"], "enum": ["pending", "handled", "late", null]}, "handled_at": {"description": "Date et heure de prise en charge.", "type": ["string", "null"], "format": "date-time"}, "handled_by": {"description": "Utilisateur ayant traite l'alerte.", "type": ["string", "null"]}, "reminder_days": {"description": "Nombre de jours de preavis avant echeance.", "type": ["integer", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "FleetFuelLogs": {"type": "object", "description": "Ravitaillements carburant, avec detection d'anomalie de consommation.", "properties": {"id": {"description": "Identifiant technique Odoo du ravitaillement.", "type": ["integer", "null"]}, "reference": {"description": "Reference du ravitaillement.", "type": ["string", "null"]}, "vehicle": {"description": "Vehicule ravitaille.", "type": ["string", "null"]}, "vehicle_id": {"description": "Identifiant du vehicule ravitaille.", "type": ["integer", "null"]}, "driver": {"description": "Conducteur ayant effectue le plein.", "type": ["string", "null"]}, "date": {"description": "Date et heure du plein.", "type": ["string", "null"], "format": "date-time"}, "station": {"description": "Station ou lieu du ravitaillement.", "type": ["string", "null"]}, "liters": {"description": "Volume en litres.", "type": ["number", "null"]}, "price_per_liter": {"description": "Prix au litre.", "type": ["number", "null"]}, "total_amount": {"description": "Montant total du plein.", "type": ["number", "null"]}, "currency": {"description": "Devise du montant.", "type": ["string", "null"]}, "odometer": {"description": "Kilometrage au moment du plein.", "type": ["number", "null"]}, "distance": {"description": "Distance parcourue depuis le plein precedent, en km.", "type": ["number", "null"]}, "consumption": {"description": "Consommation constatee sur l'intervalle, en litres aux 100 km.", "type": ["number", "null"]}, "is_anomaly": {"description": "Vrai si la consommation s'ecarte anormalement de la moyenne du vehicule.", "type": ["boolean", "null"]}, "anomaly_severity": {"description": "Gravite de l'anomalie detectee. Valeurs : none (Aucune), low (Faible), medium (Moyenne), high (Elevee)", "type": ["string", "null"], "enum": ["none", "low", "medium", "high", null]}, "anomaly_reason": {"description": "Explication de l'anomalie detectee.", "type": ["string", "null"]}, "reviewed": {"description": "Vrai si l'anomalie a ete revue par un gestionnaire.", "type": ["boolean", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "FleetIncidents": {"type": "object", "description": "Incidents imputes aux conducteurs, avec gravite et cout d'impact.", "properties": {"id": {"description": "Identifiant technique Odoo de l'incident.", "type": ["integer", "null"]}, "name": {"description": "Intitule de l'incident.", "type": ["string", "null"]}, "vehicle": {"description": "Vehicule concerne.", "type": ["string", "null"]}, "vehicle_id": {"description": "Identifiant du vehicule concerne.", "type": ["integer", "null"]}, "driver": {"description": "Conducteur mis en cause.", "type": ["string", "null"]}, "date": {"description": "Date de l'incident.", "type": ["string", "null"], "format": "date"}, "severity": {"description": "Gravite de l'incident. Valeurs : minor (Mineur), moderate (Modere), major (Majeur), critical (Critique)", "type": ["string", "null"], "enum": ["minor", "moderate", "major", "critical", null]}, "cost": {"description": "Cout d'impact estime.", "type": ["number", "null"]}, "currency": {"description": "Devise du cout.", "type": ["string", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "FleetLocations": {"type": "object", "description": "Referentiel des lieux frequents utilises comme point de depart ou destination.", "properties": {"id": {"description": "Identifiant technique Odoo du lieu.", "type": ["integer", "null"]}, "name": {"description": "Nom du lieu.", "type": ["string", "null"]}, "code": {"description": "Code court, par exemple SIEGE ou AEROPORT.", "type": ["string", "null"]}, "address": {"description": "Adresse postale.", "type": ["string", "null"]}, "city": {"description": "Ville.", "type": ["string", "null"]}, "country": {"description": "Pays.", "type": ["string", "null"]}, "latitude": {"description": "Latitude en degres decimaux.", "type": ["number", "null"]}, "longitude": {"description": "Longitude en degres decimaux.", "type": ["number", "null"]}, "is_default_pickup": {"description": "Vrai si le lieu est le point de prise en charge par defaut.", "type": ["boolean", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "FleetReservations": {"type": "object", "description": "Demandes de reservation de vehicule et leur cycle de validation.", "properties": {"id": {"description": "Identifiant technique Odoo de la reservation.", "type": ["integer", "null"]}, "reference": {"description": "Reference de la reservation.", "type": ["string", "null"]}, "vehicle": {"description": "Vehicule reserve.", "type": ["string", "null"]}, "vehicle_id": {"description": "Identifiant du vehicule reserve.", "type": ["integer", "null"]}, "driver": {"description": "Conducteur designe pour la course.", "type": ["string", "null"]}, "requester": {"description": "Utilisateur a l'origine de la demande.", "type": ["string", "null"]}, "start": {"description": "Debut de la reservation.", "type": ["string", "null"], "format": "date-time"}, "stop": {"description": "Fin de la reservation.", "type": ["string", "null"], "format": "date-time"}, "duration": {"description": "Duree en heures.", "type": ["number", "null"]}, "motive": {"description": "Motif declare de la course.", "type": ["string", "null"]}, "pickup_location": {"description": "Lieu de prise en charge.", "type": ["string", "null"]}, "destination": {"description": "Destination declaree.", "type": ["string", "null"]}, "expected_km": {"description": "Distance previsionnelle en km.", "type": ["number", "null"]}, "attendees_count": {"description": "Nombre de passagers attendus.", "type": ["integer", "null"]}, "origin": {"description": "Canal d'origine de la demande. Valeurs : internal (Interne), public (Public)", "type": ["string", "null"], "enum": ["internal", "public", null]}, "state": {"description": "Etat du cycle de validation. Valeurs : draft (Brouillon), pending (En attente), approved (Approuvee), in_progress (En cours), done (Terminee), refused (Refusee), cancelled (Annulee)", "type": ["string", "null"], "enum": ["draft", "pending", "approved", "in_progress", "done", "refused", "cancelled", null]}, "approver": {"description": "Utilisateur ayant approuve la demande.", "type": ["string", "null"]}, "approved_at": {"description": "Date et heure de l'approbation.", "type": ["string", "null"], "format": "date-time"}, "refusal_reason": {"description": "Motif du refus, le cas echeant.", "type": ["string", "null"]}}}, "FleetServices": {"type": "object", "description": "Entretiens et reparations des vehicules, avec leur cout.", "properties": {"id": {"description": "Identifiant technique Odoo de l'entretien.", "type": ["integer", "null"]}, "vehicle": {"description": "Vehicule entretenu.", "type": ["string", "null"]}, "vehicle_id": {"description": "Identifiant du vehicule entretenu.", "type": ["integer", "null"]}, "date": {"description": "Date de l'intervention.", "type": ["string", "null"], "format": "date"}, "description": {"description": "Description de l'intervention.", "type": ["string", "null"]}, "service_type": {"description": "Nature de la prestation.", "type": ["string", "null"]}, "service_kind": {"description": "Categorie d'entretien : preventif, curatif, etc. Valeurs : preventive (Preventif), curative (Curatif)", "type": ["string", "null"], "enum": ["preventive", "curative", null]}, "amount": {"description": "Cout de l'intervention.", "type": ["number", "null"]}, "total_cost": {"description": "Cout total, lignes de detail incluses.", "type": ["number", "null"]}, "currency": {"description": "Devise des montants.", "type": ["string", "null"]}, "odometer": {"description": "Kilometrage au moment de l'intervention.", "type": ["number", "null"]}, "next_service_odometer": {"description": "Kilometrage prevu pour le prochain entretien.", "type": ["number", "null"]}, "vendor": {"description": "Prestataire ou garage.", "type": ["string", "null"]}, "invoice_ref": {"description": "Reference de la facture fournisseur.", "type": ["string", "null"]}, "state": {"description": "Etat de l'intervention. Valeurs : new (New), running (Running), done (Done), cancelled (Cancelled)", "type": ["string", "null"], "enum": ["new", "running", "done", "cancelled", null]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "FleetTrips": {"type": "object", "description": "Trajets realises : kilometrage reel, destination, imputation analytique.", "properties": {"id": {"description": "Identifiant technique Odoo du trajet.", "type": ["integer", "null"]}, "reference": {"description": "Reference du trajet.", "type": ["string", "null"]}, "reservation_id": {"description": "Identifiant de la reservation d'origine, si le trajet en decoule.", "type": ["integer", "null"]}, "vehicle": {"description": "Vehicule utilise.", "type": ["string", "null"]}, "vehicle_id": {"description": "Identifiant du vehicule utilise.", "type": ["integer", "null"]}, "driver": {"description": "Conducteur du trajet.", "type": ["string", "null"]}, "date": {"description": "Date du trajet.", "type": ["string", "null"], "format": "date"}, "date_start": {"description": "Heure de depart.", "type": ["string", "null"], "format": "date-time"}, "date_end": {"description": "Heure d'arrivee.", "type": ["string", "null"], "format": "date-time"}, "odometer_start": {"description": "Kilometrage au depart.", "type": ["number", "null"]}, "odometer_end": {"description": "Kilometrage a l'arrivee.", "type": ["number", "null"]}, "distance": {"description": "Distance parcourue en km.", "type": ["number", "null"]}, "motive": {"description": "Motif du deplacement.", "type": ["string", "null"]}, "destination": {"description": "Destination atteinte.", "type": ["string", "null"]}, "analytic_account": {"description": "Compte analytique impute.", "type": ["string", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "FleetVehicles": {"type": "object", "description": "Vehicules du parc automobile, avec leurs echeances reglementaires.", "properties": {"id": {"description": "Identifiant technique Odoo du vehicule.", "type": ["integer", "null"]}, "plate": {"description": "Plaque d'immatriculation.", "type": ["string", "null"]}, "model": {"description": "Marque et modele du vehicule.", "type": ["string", "null"]}, "vin": {"description": "Numero de chassis (VIN).", "type": ["string", "null"]}, "driver": {"description": "Conducteur actuellement affecte.", "type": ["string", "null"]}, "seats": {"description": "Nombre de places assises.", "type": ["integer", "null"]}, "fuel_type": {"description": "Type de carburant. Valeurs : diesel (Diesel), gasoline (Gasoline), full_hybrid (Full Hybrid), plug_in_hybrid_diesel (Plug-in Hybrid Diesel), plug_in_hybrid_gasoline (Plug-in Hybrid Gasoline), cng (CNG), lpg (LPG), hydrogen (Hydrogen), electric (Electric)", "type": ["string", "null"], "enum": ["diesel", "gasoline", "full_hybrid", "plug_in_hybrid_diesel", "plug_in_hybrid_gasoline", "cng", "lpg", "hydrogen", "electric", null]}, "odometer": {"description": "Dernier kilometrage releve.", "type": ["number", "null"]}, "state": {"description": "Etat du vehicule dans le cycle de vie du parc.", "type": ["string", "null"]}, "assignation_state": {"description": "Etat d'affectation : disponible, affecte, indisponible. Valeurs : free (Disponible), assigned (Affecte), maintenance (En maintenance), out_of_service (Hors service), sold (Vendu)", "type": ["string", "null"], "enum": ["free", "assigned", "maintenance", "out_of_service", "sold", null]}, "acquisition_date": {"description": "Date de mise en circulation.", "type": ["string", "null"], "format": "date"}, "insurance_expiry": {"description": "Date d'expiration de l'assurance.", "type": ["string", "null"], "format": "date"}, "technical_control_expiry": {"description": "Date d'expiration de la visite technique.", "type": ["string", "null"], "format": "date"}, "next_alert_date": {"description": "Prochaine echeance a traiter, toutes categories confondues.", "type": ["string", "null"], "format": "date"}, "avg_consumption": {"description": "Consommation moyenne constatee, en litres aux 100 km.", "type": ["number", "null"]}, "total_km_last_year": {"description": "Distance parcourue sur les douze derniers mois, en km.", "type": ["number", "null"]}, "company": {"description": "Societe proprietaire du vehicule.", "type": ["string", "null"]}}}, "ItAssets": {"type": "object", "description": "Materiels du parc informatique, identifies par numero de serie.", "properties": {"id": {"description": "Identifiant technique Odoo du materiel.", "type": ["integer", "null"]}, "serial": {"description": "Numero de serie du materiel.", "type": ["string", "null"]}, "internal_ref": {"description": "Reference interne, si differente du numero constructeur.", "type": ["string", "null"]}, "product": {"description": "Modele de materiel.", "type": ["string", "null"]}, "quantity": {"description": "Quantite en stock pour ce numero de serie.", "type": ["number", "null"]}, "location": {"description": "Emplacement de stockage courant.", "type": ["string", "null"]}, "holder": {"description": "Personne detentrice du materiel.", "type": ["string", "null"]}, "lifecycle": {"description": "Etape du cycle de vie du materiel. Valeurs : available (Disponible), assigned (Affecté), maintenance (Maintenance), retired (Réformé), external (Hors parc)", "type": ["string", "null"], "enum": ["available", "assigned", "maintenance", "retired", "external", null]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "ItConsumableMoves": {"type": "object", "description": "Sorties et retours de consommables informatiques.", "properties": {"id": {"description": "Identifiant technique Odoo du mouvement.", "type": ["integer", "null"]}, "ticket_id": {"description": "Identifiant du ticket a l'origine du mouvement.", "type": ["integer", "null"]}, "ticket_number": {"description": "Numero du ticket a l'origine du mouvement.", "type": ["string", "null"]}, "beneficiary": {"description": "Beneficiaire du consommable.", "type": ["string", "null"]}, "product": {"description": "Consommable concerne.", "type": ["string", "null"]}, "location": {"description": "Zone de stockage.", "type": ["string", "null"]}, "quantity": {"description": "Quantite sortie.", "type": ["number", "null"]}, "returned_quantity": {"description": "Quantite retournee.", "type": ["number", "null"]}, "remaining_quantity": {"description": "Quantite non retournee.", "type": ["number", "null"]}, "state": {"description": "Etat du mouvement. Valeurs : out (Sortie), partial (Retour partiel), returned (Retournée)", "type": ["string", "null"], "enum": ["out", "partial", "returned", null]}, "date": {"description": "Date et heure du mouvement.", "type": ["string", "null"], "format": "date-time"}, "handled_by": {"description": "Utilisateur ayant enregistre le mouvement.", "type": ["string", "null"]}}}, "ItTickets": {"type": "object", "description": "Demandes adressees au service informatique et leur avancement.", "properties": {"id": {"description": "Identifiant technique Odoo du ticket.", "type": ["integer", "null"]}, "number": {"description": "Numero du ticket, visible par le demandeur.", "type": ["string", "null"]}, "name": {"description": "Objet de la demande.", "type": ["string", "null"]}, "category": {"description": "Categorie de la demande.", "type": ["string", "null"]}, "type": {"description": "Type de demande au sein de la categorie.", "type": ["string", "null"]}, "stage": {"description": "Etape courante du traitement.", "type": ["string", "null"]}, "is_closed": {"description": "Vrai si l'etape courante est une etape de cloture.", "type": ["boolean", "null"]}, "team": {"description": "Equipe en charge du ticket.", "type": ["string", "null"]}, "assignee": {"description": "Technicien assigne.", "type": ["string", "null"]}, "requester": {"description": "Nom du demandeur.", "type": ["string", "null"]}, "requester_email": {"description": "Adresse electronique du demandeur.", "type": ["string", "null"]}, "priority": {"description": "Priorite du ticket. Valeurs : 0 (Basse), 1 (Normale), 2 (Haute), 3 (Critique)", "type": ["string", "null"], "enum": ["0", "1", "2", "3", null]}, "kanban_state": {"description": "Indicateur de blocage : en cours, bloque, pret. Valeurs : normal (En cours), done (Prêt), blocked (Bloqué)", "type": ["string", "null"], "enum": ["normal", "done", "blocked", null]}, "validation_state": {"description": "Etat de la validation hierarchique, si la demande en requiert une. Valeurs : none (Non requise), to_validate (À valider), validated (Validée), rejected (Rejetée)", "type": ["string", "null"], "enum": ["none", "to_validate", "validated", "rejected", null]}, "assigned_date": {"description": "Date et heure d'assignation.", "type": ["string", "null"], "format": "date-time"}, "closed_date": {"description": "Date et heure de cloture.", "type": ["string", "null"], "format": "date-time"}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "PurchaseOrderLines": {"type": "object", "description": "Lignes de commande fournisseur : articles, quantites et prix unitaires.", "properties": {"id": {"description": "Identifiant technique Odoo de la ligne.", "type": ["integer", "null"]}, "order_id": {"description": "Identifiant de la commande.", "type": ["integer", "null"]}, "order_reference": {"description": "Reference de la commande.", "type": ["string", "null"]}, "description": {"description": "Libelle de la ligne.", "type": ["string", "null"]}, "product": {"description": "Article commande.", "type": ["string", "null"]}, "product_id": {"description": "Identifiant de l'article commande.", "type": ["integer", "null"]}, "quantity": {"description": "Quantite commandee.", "type": ["number", "null"]}, "uom": {"description": "Unite de mesure.", "type": ["string", "null"]}, "price_unit": {"description": "Prix unitaire.", "type": ["number", "null"]}, "price_subtotal": {"description": "Sous-total hors taxes.", "type": ["number", "null"]}, "price_total": {"description": "Total toutes taxes comprises.", "type": ["number", "null"]}, "currency": {"description": "Devise des montants.", "type": ["string", "null"]}, "qty_received": {"description": "Quantite receptionnee.", "type": ["number", "null"]}, "qty_invoiced": {"description": "Quantite facturee.", "type": ["number", "null"]}, "date_planned": {"description": "Date de reception prevue pour la ligne.", "type": ["string", "null"], "format": "date-time"}, "state": {"description": "Etat de la commande dont la ligne depend. Valeurs : draft (RFQ), sent (RFQ Sent), to approve (To Approve), purchase (Purchase Order), cancel (Cancelled)", "type": ["string", "null"], "enum": ["draft", "sent", "to approve", "purchase", "cancel", null]}}}, "PurchaseOrders": {"type": "object", "description": "Commandes fournisseur : montants, echeances et etat de facturation.", "properties": {"id": {"description": "Identifiant technique Odoo de la commande.", "type": ["integer", "null"]}, "reference": {"description": "Reference de la commande.", "type": ["string", "null"]}, "vendor": {"description": "Fournisseur.", "type": ["string", "null"]}, "vendor_id": {"description": "Identifiant du fournisseur.", "type": ["integer", "null"]}, "vendor_reference": {"description": "Reference de la commande chez le fournisseur.", "type": ["string", "null"]}, "origin": {"description": "Document a l'origine de la commande.", "type": ["string", "null"]}, "date_order": {"description": "Date limite de commande.", "type": ["string", "null"], "format": "date-time"}, "date_approve": {"description": "Date de confirmation.", "type": ["string", "null"], "format": "date-time"}, "date_planned": {"description": "Date de reception prevue.", "type": ["string", "null"], "format": "date-time"}, "amount_untaxed": {"description": "Montant hors taxes.", "type": ["number", "null"]}, "amount_total": {"description": "Montant toutes taxes comprises.", "type": ["number", "null"]}, "currency": {"description": "Devise des montants.", "type": ["string", "null"]}, "state": {"description": "Etat de la commande. Valeurs : draft (RFQ), sent (RFQ Sent), to approve (To Approve), purchase (Purchase Order), cancel (Cancelled)", "type": ["string", "null"], "enum": ["draft", "sent", "to approve", "purchase", "cancel", null]}, "invoice_status": {"description": "Etat de facturation de la commande. Valeurs : no (Nothing to Bill), to invoice (Waiting Bills), invoiced (Fully Billed)", "type": ["string", "null"], "enum": ["no", "to invoice", "invoiced", null]}, "buyer": {"description": "Acheteur en charge.", "type": ["string", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "SpaceActivities": {"type": "object", "description": "Referentiel des natures d'activite pouvant motiver une reservation.", "properties": {"id": {"description": "Identifiant technique Odoo de l'activite.", "type": ["integer", "null"]}, "name": {"description": "Nom de l'activite.", "type": ["string", "null"]}, "code": {"description": "Code court de l'activite.", "type": ["string", "null"]}, "default_duration": {"description": "Duree par defaut proposee, en heures.", "type": ["number", "null"]}}}, "SpaceCategories": {"type": "object", "description": "Referentiel des categories d'espaces.", "properties": {"id": {"description": "Identifiant technique Odoo de la categorie.", "type": ["integer", "null"]}, "name": {"description": "Nom de la categorie.", "type": ["string", "null"]}, "description": {"description": "Description de la categorie.", "type": ["string", "null"]}}}, "SpaceEquipments": {"type": "object", "description": "Referentiel des equipements installables dans un espace.", "properties": {"id": {"description": "Identifiant technique Odoo de l'equipement.", "type": ["integer", "null"]}, "name": {"description": "Nom de l'equipement.", "type": ["string", "null"]}, "code": {"description": "Code court de l'equipement.", "type": ["string", "null"]}, "category": {"description": "Categorie d'equipement.", "type": ["string", "null"]}, "description": {"description": "Description de l'equipement.", "type": ["string", "null"]}}}, "SpaceMaintenances": {"type": "object", "description": "Operations de maintenance sur les espaces, bloquantes ou non.", "properties": {"id": {"description": "Identifiant technique Odoo de la maintenance.", "type": ["integer", "null"]}, "name": {"description": "Intitule de l'operation.", "type": ["string", "null"]}, "space": {"description": "Espace concerne.", "type": ["string", "null"]}, "space_id": {"description": "Identifiant de l'espace concerne.", "type": ["integer", "null"]}, "start": {"description": "Debut de l'operation.", "type": ["string", "null"], "format": "date-time"}, "stop": {"description": "Fin de l'operation.", "type": ["string", "null"], "format": "date-time"}, "state": {"description": "Etat d'avancement de l'operation. Valeurs : planned (Planifiee), in_progress (En cours), done (Terminee), cancelled (Annulee)", "type": ["string", "null"], "enum": ["planned", "in_progress", "done", "cancelled", null]}, "category": {"description": "Categorie de maintenance. Valeurs : preventive (Preventive), curative (Curative), cleaning (Nettoyage), other (Autre)", "type": ["string", "null"], "enum": ["preventive", "curative", "cleaning", "other", null]}, "technician": {"description": "Technicien interne en charge.", "type": ["string", "null"]}, "external_technician": {"description": "Prestataire externe en charge.", "type": ["string", "null"]}, "blocks_reservations": {"description": "Vrai si l'operation empeche toute reservation sur le creneau.", "type": ["boolean", "null"]}, "check_progress": {"description": "Avancement de la checklist, en pourcentage.", "type": ["number", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "SpaceReservations": {"type": "object", "description": "Reservations d'espaces et leur cycle de validation.", "properties": {"id": {"description": "Identifiant technique Odoo de la reservation.", "type": ["integer", "null"]}, "reference": {"description": "Reference de la reservation.", "type": ["string", "null"]}, "space": {"description": "Espace reserve.", "type": ["string", "null"]}, "space_id": {"description": "Identifiant de l'espace reserve.", "type": ["integer", "null"]}, "activity": {"description": "Nature de l'activite prevue.", "type": ["string", "null"]}, "start": {"description": "Debut de la reservation.", "type": ["string", "null"], "format": "date-time"}, "stop": {"description": "Fin de la reservation.", "type": ["string", "null"], "format": "date-time"}, "duration": {"description": "Duree en heures.", "type": ["number", "null"]}, "attendees_expected": {"description": "Nombre de participants attendus.", "type": ["integer", "null"]}, "attendees_actual": {"description": "Nombre de participants effectivement presents.", "type": ["integer", "null"]}, "requester": {"description": "Utilisateur a l'origine de la demande.", "type": ["string", "null"]}, "origin": {"description": "Canal d'origine de la demande. Valeurs : internal (Interne), public (Public)", "type": ["string", "null"], "enum": ["internal", "public", null]}, "state": {"description": "Etat du cycle de validation. Valeurs : pending (En attente), approved (Approuvee), refused (Refusee), cancelled (Annulee), done (Terminee)", "type": ["string", "null"], "enum": ["pending", "approved", "refused", "cancelled", "done", null]}, "approver": {"description": "Utilisateur ayant approuve la demande.", "type": ["string", "null"]}, "approved_at": {"description": "Date et heure de l'approbation.", "type": ["string", "null"], "format": "date-time"}, "refusal_reason": {"description": "Motif du refus, le cas echeant.", "type": ["string", "null"]}, "cancellation_reason": {"description": "Motif de l'annulation, le cas echeant.", "type": ["string", "null"]}, "check_in_at": {"description": "Heure d'arrivee constatee.", "type": ["string", "null"], "format": "date-time"}, "check_out_at": {"description": "Heure de depart constatee.", "type": ["string", "null"], "format": "date-time"}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "SpaceSites": {"type": "object", "description": "Sites hebergeant les espaces reservables, organises en arborescence.", "properties": {"id": {"description": "Identifiant technique Odoo du site.", "type": ["integer", "null"]}, "name": {"description": "Nom du site.", "type": ["string", "null"]}, "complete_name": {"description": "Nom complet, chemin hierarchique inclus.", "type": ["string", "null"]}, "code": {"description": "Code court du site.", "type": ["string", "null"]}, "parent_id": {"description": "Identifiant du site parent, si le site est un sous-ensemble.", "type": ["integer", "null"]}, "address": {"description": "Adresse postale du site.", "type": ["string", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "SpaceSpaces": {"type": "object", "description": "Espaces reservables : salles, bureaux, capacites et tarifs.", "properties": {"id": {"description": "Identifiant technique Odoo de l'espace.", "type": ["integer", "null"]}, "name": {"description": "Nom de l'espace.", "type": ["string", "null"]}, "code": {"description": "Code court de l'espace.", "type": ["string", "null"]}, "site": {"description": "Site hebergeant l'espace.", "type": ["string", "null"]}, "site_id": {"description": "Identifiant du site hebergeant l'espace.", "type": ["integer", "null"]}, "state": {"description": "Etat de l'espace : disponible, en travaux, ferme. Valeurs : available (Disponible), restricted (Restreint), closed (Ferme)", "type": ["string", "null"], "enum": ["available", "restricted", "closed", null]}, "location": {"description": "Localisation libre au sein du site.", "type": ["string", "null"]}, "floor": {"description": "Etage.", "type": ["string", "null"]}, "surface": {"description": "Surface en metres carres.", "type": ["number", "null"]}, "capacity": {"description": "Capacite d'accueil, en nombre de personnes.", "type": ["integer", "null"]}, "hourly_price": {"description": "Tarif horaire de reference.", "type": ["number", "null"]}, "currency": {"description": "Devise du tarif.", "type": ["string", "null"]}, "categories": {"description": "Categories auxquelles l'espace appartient.", "type": "array", "items": {"type": "object", "properties": {"id": {"type": "integer"}, "name": {"type": "string"}}}}, "public_visibility": {"description": "Niveau de visibilite de l'espace sur le portail public. Valeurs : private (Prive), internal (Interne), public (Public)", "type": ["string", "null"], "enum": ["private", "internal", "public", null]}, "approval_required": {"description": "Vrai si toute reservation doit etre approuvee.", "type": ["boolean", "null"]}, "min_lead_hours": {"description": "Delai minimal de reservation, en heures.", "type": ["integer", "null"]}, "max_lead_days": {"description": "Horizon maximal de reservation, en jours.", "type": ["integer", "null"]}, "cancel_deadline_hours": {"description": "Delai limite d'annulation, en heures avant le debut.", "type": ["integer", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "StockPickings": {"type": "object", "description": "Transferts de stock : receptions, livraisons et mouvements internes.", "properties": {"id": {"description": "Identifiant technique Odoo du transfert.", "type": ["integer", "null"]}, "reference": {"description": "Reference du transfert.", "type": ["string", "null"]}, "origin": {"description": "Document d'origine ayant genere le transfert.", "type": ["string", "null"]}, "picking_type": {"description": "Type d'operation : reception, livraison, transfert interne.", "type": ["string", "null"]}, "partner": {"description": "Contact associe au transfert.", "type": ["string", "null"]}, "source_location": {"description": "Emplacement source.", "type": ["string", "null"]}, "destination_location": {"description": "Emplacement de destination.", "type": ["string", "null"]}, "scheduled_date": {"description": "Date prevue du transfert.", "type": ["string", "null"], "format": "date-time"}, "date_done": {"description": "Date effective de realisation.", "type": ["string", "null"], "format": "date-time"}, "priority": {"description": "Priorite du transfert. Valeurs : 0 (Normal), 1 (Urgent)", "type": ["string", "null"], "enum": ["0", "1", null]}, "state": {"description": "Etat du transfert. Valeurs : draft (Draft), waiting (Waiting Another Operation), confirmed (Waiting), assigned (Ready), done (Done), cancel (Cancelled)", "type": ["string", "null"], "enum": ["draft", "waiting", "confirmed", "assigned", "done", "cancel", null]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "TravelPerdiemRates": {"type": "object", "description": "Bareme des per diem par pays et par ville.", "properties": {"id": {"description": "Identifiant technique Odoo du bareme.", "type": ["integer", "null"]}, "country": {"description": "Pays couvert par le bareme.", "type": ["string", "null"]}, "country_id": {"description": "Identifiant du pays couvert.", "type": ["integer", "null"]}, "city": {"description": "Ville couverte, si le bareme est specifique a une ville.", "type": ["string", "null"]}, "daily_rate": {"description": "Taux journalier de reference.", "type": ["number", "null"]}, "currency": {"description": "Devise du taux.", "type": ["string", "null"]}, "has_tiers": {"description": "Vrai si le bareme comporte des paliers de duree.", "type": ["boolean", "null"]}, "environment": {"description": "Environnement de bareme.", "type": ["string", "null"]}, "note": {"description": "Note explicative sur le bareme.", "type": ["string", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "TravelPerdiemRequests": {"type": "object", "description": "Demandes de per diem : bareme applique, abattements et montant du.", "properties": {"id": {"description": "Identifiant technique Odoo de la demande.", "type": ["integer", "null"]}, "reference": {"description": "Reference de la demande.", "type": ["string", "null"]}, "name": {"description": "Intitule de la demande.", "type": ["string", "null"]}, "state": {"description": "Etat du cycle de validation. Valeurs : draft (Brouillon), pending (En attente), approved (Approuvée), rejected (Rejetée), cancelled (Annulée)", "type": ["string", "null"], "enum": ["draft", "pending", "approved", "rejected", "cancelled", null]}, "trip_id": {"description": "Identifiant de la mission rattachee.", "type": ["integer", "null"]}, "trip_reference": {"description": "Reference de la mission rattachee.", "type": ["string", "null"]}, "traveler": {"description": "Utilisateur beneficiaire.", "type": ["string", "null"]}, "mission_object": {"description": "Objet de la mission.", "type": ["string", "null"]}, "country": {"description": "Pays du sejour.", "type": ["string", "null"]}, "city": {"description": "Ville du sejour.", "type": ["string", "null"]}, "date_start": {"description": "Debut du sejour.", "type": ["string", "null"], "format": "date"}, "date_end": {"description": "Fin du sejour.", "type": ["string", "null"], "format": "date"}, "duration_days": {"description": "Duree retenue pour le calcul, en jours.", "type": ["number", "null"]}, "prorata_start": {"description": "Regle de prorata appliquee au premier jour. Valeurs : full (Journée pleine), half (Demi-journée), none (Aucun)", "type": ["string", "null"], "enum": ["full", "half", "none", null]}, "prorata_end": {"description": "Regle de prorata appliquee au dernier jour. Valeurs : full (Journée pleine), half (Demi-journée), none (Aucun)", "type": ["string", "null"], "enum": ["full", "half", "none", null]}, "calc_model": {"description": "Modele de calcul retenu. Valeurs : flat_with_abatement (Taux + abattement), tiered (Grille à paliers)", "type": ["string", "null"], "enum": ["flat_with_abatement", "tiered", null]}, "daily_rate": {"description": "Taux journalier applique.", "type": ["number", "null"]}, "rate_id": {"description": "Identifiant du bareme applique.", "type": ["integer", "null"]}, "duration_abatement_pct": {"description": "Abattement de duree applique, en pourcentage.", "type": ["number", "null"]}, "duration_abatement_amount": {"description": "Montant de l'abattement de duree.", "type": ["number", "null"]}, "total_amount": {"description": "Montant total du.", "type": ["number", "null"]}, "financing_type": {"description": "Mode de financement de la demande. Valeurs : aeig (AEIG uniquement), partner (Partenaire uniquement), mixed (Mixte AEIG / partenaire)", "type": ["string", "null"], "enum": ["aeig", "partner", "mixed", null]}, "partner": {"description": "Partenaire cofinanceur, le cas echeant.", "type": ["string", "null"]}, "partner_share_pct": {"description": "Part du partenaire, en pourcentage.", "type": ["number", "null"]}, "amount_company": {"description": "Part a la charge de la societe.", "type": ["number", "null"]}, "amount_partner": {"description": "Part a la charge du partenaire.", "type": ["number", "null"]}, "currency": {"description": "Devise des montants.", "type": ["string", "null"]}, "environment": {"description": "Environnement de bareme applique.", "type": ["string", "null"]}, "validator": {"description": "Utilisateur validateur.", "type": ["string", "null"]}, "submit_date": {"description": "Date et heure de soumission.", "type": ["string", "null"], "format": "date-time"}, "approve_date": {"description": "Date et heure d'approbation.", "type": ["string", "null"], "format": "date-time"}, "reject_date": {"description": "Date et heure de rejet.", "type": ["string", "null"], "format": "date-time"}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}, "TravelTripExpenses": {"type": "object", "description": "Frais rattaches a une mission, hors per diem.", "properties": {"id": {"description": "Identifiant technique Odoo du frais.", "type": ["integer", "null"]}, "name": {"description": "Intitule du frais.", "type": ["string", "null"]}, "trip_id": {"description": "Identifiant de la mission rattachee.", "type": ["integer", "null"]}, "trip_reference": {"description": "Reference de la mission rattachee.", "type": ["string", "null"]}, "cost": {"description": "Montant du frais.", "type": ["number", "null"]}, "currency": {"description": "Devise du montant.", "type": ["string", "null"]}, "notes": {"description": "Note libre sur le frais.", "type": ["string", "null"]}}}, "TravelTripStages": {"type": "object", "description": "Etapes d'une mission : trajets successifs, aller et retour.", "properties": {"id": {"description": "Identifiant technique Odoo de l'etape.", "type": ["integer", "null"]}, "name": {"description": "Intitule de l'etape.", "type": ["string", "null"]}, "trip_id": {"description": "Identifiant de la mission a laquelle l'etape appartient.", "type": ["integer", "null"]}, "trip_reference": {"description": "Reference de la mission.", "type": ["string", "null"]}, "position": {"description": "Rang de l'etape dans la mission.", "type": ["integer", "null"]}, "is_return_leg": {"description": "Vrai si l'etape constitue le trajet de retour.", "type": ["boolean", "null"]}, "city_from": {"description": "Ville de depart de l'etape.", "type": ["string", "null"]}, "country_from": {"description": "Pays de depart de l'etape.", "type": ["string", "null"]}, "city_to": {"description": "Ville d'arrivee de l'etape.", "type": ["string", "null"]}, "country_to": {"description": "Pays d'arrivee de l'etape.", "type": ["string", "null"]}, "date_from": {"description": "Debut de l'etape.", "type": ["string", "null"], "format": "date-time"}, "date_to": {"description": "Fin de l'etape.", "type": ["string", "null"], "format": "date-time"}, "duration_days": {"description": "Duree de l'etape, en jours.", "type": ["integer", "null"]}, "has_transport": {"description": "Vrai si un transport est prevu sur cette etape.", "type": ["boolean", "null"]}}}, "TravelTripTypes": {"type": "object", "description": "Referentiel des types de mission.", "properties": {"id": {"description": "Identifiant technique Odoo du type.", "type": ["integer", "null"]}, "name": {"description": "Nom du type de mission.", "type": ["string", "null"]}, "code": {"description": "Code court du type.", "type": ["string", "null"]}, "description": {"description": "Description du type de mission.", "type": ["string", "null"]}}}, "TravelTrips": {"type": "object", "description": "Missions et deplacements : trajet, dates et cout complet.", "properties": {"id": {"description": "Identifiant technique Odoo de la mission.", "type": ["integer", "null"]}, "reference": {"description": "Reference de la mission.", "type": ["string", "null"]}, "name": {"description": "Intitule de la mission.", "type": ["string", "null"]}, "state": {"description": "Etat du cycle de validation. Valeurs : draft (Brouillon), pending (En attente validation), planned (Planifié), in_progress (En cours), done (Terminé), cancelled (Annulé)", "type": ["string", "null"], "enum": ["draft", "pending", "planned", "in_progress", "done", "cancelled", null]}, "traveler": {"description": "Utilisateur voyageur.", "type": ["string", "null"]}, "traveler_name": {"description": "Nom du voyageur tel que declare.", "type": ["string", "null"]}, "traveler_email": {"description": "Adresse electronique du voyageur.", "type": ["string", "null"]}, "trip_type": {"description": "Type de mission.", "type": ["string", "null"]}, "description": {"description": "Objet de la mission.", "type": ["string", "null"]}, "city_departure": {"description": "Ville de depart.", "type": ["string", "null"]}, "country_departure": {"description": "Pays de depart.", "type": ["string", "null"]}, "city_destination": {"description": "Ville de destination.", "type": ["string", "null"]}, "country_destination": {"description": "Pays de destination.", "type": ["string", "null"]}, "date_submission": {"description": "Date de soumission de la demande.", "type": ["string", "null"], "format": "date"}, "date_start": {"description": "Debut de la mission.", "type": ["string", "null"], "format": "date-time"}, "date_end": {"description": "Fin de la mission.", "type": ["string", "null"], "format": "date-time"}, "duration_days": {"description": "Duree de la mission, en jours.", "type": ["integer", "null"]}, "transport_cost": {"description": "Cout du transport.", "type": ["number", "null"]}, "accommodation_cost_total": {"description": "Cout total de l'hebergement.", "type": ["number", "null"]}, "per_diem_total": {"description": "Montant total des per diem.", "type": ["number", "null"]}, "insurance_premium": {"description": "Prime d'assurance voyage.", "type": ["number", "null"]}, "currency": {"description": "Devise des montants.", "type": ["string", "null"]}, "has_per_diem": {"description": "Vrai si la mission ouvre droit a un per diem.", "type": ["boolean", "null"]}, "has_return_stage": {"description": "Vrai si une etape de retour est prevue.", "type": ["boolean", "null"]}, "company": {"description": "Societe de rattachement.", "type": ["string", "null"]}}}}}, "security": [{"apiKey": []}]}