{"openapi":"3.1.0","info":{"title":"PmlFiT API","version":"1.1.0","description":"API multi-tenant pour connecter Odoo, ERP et WMS au module PharmaML PmlFiT."},"servers":[{"url":"https://{tenant}.pmlfit.fr/api/v1","description":"Espace client PmlFiT","variables":{"tenant":{"default":"nomduclient","description":"Sous-domaine attribué à l’organisation"}}},{"url":"https://www.pmlfit.fr/api/v1","description":"URL canonique ou environnement de secours"}],"security":[{"bearerAuth":[]}],"paths":{"/products":{"get":{"summary":"Lister ou rechercher le catalogue","operationId":"listProducts","parameters":[{"name":"q","in":"query","schema":{"type":"string"}},{"name":"code","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200}},{"name":"offset","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Catalogue","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListResponse"}}}}}},"post":{"summary":"Créer ou synchroniser des produits","operationId":"upsertProducts","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/ProductInput"}}}}}}},"responses":{"200":{"description":"Produits synchronisés"},"422":{"$ref":"#/components/responses/ValidationError"}}}},"/availability":{"post":{"summary":"Calculer prix, disponibilité et quota sans consommer","operationId":"resolveAvailability","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailabilityRequest"}}}},"responses":{"200":{"description":"Disponibilités calculées"}}}},"/orders":{"get":{"summary":"Lister les commandes reçues des pharmacies","operationId":"listOrders","parameters":[{"name":"state","in":"query","schema":{"$ref":"#/components/schemas/OrderState"}},{"name":"updatedSince","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Commandes et lignes"}}}},"/orders/{id}":{"get":{"summary":"Lire une commande","operationId":"getOrder","parameters":[{"$ref":"#/components/parameters/OrderId"}],"responses":{"200":{"description":"Commande"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"summary":"Acquitter ou mettre à jour une commande depuis l’ERP/WMS","operationId":"updateOrder","parameters":[{"$ref":"#/components/parameters/OrderId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderUpdate"}}}},"responses":{"200":{"description":"Commande mise à jour"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/messages":{"get":{"summary":"Consulter le journal PharmaML","operationId":"listMessages","parameters":[{"name":"type","in":"query","schema":{"type":"string"}},{"name":"includeRaw","in":"query","description":"Nécessite le scope messages:raw","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Messages"}}}},"/delivery-notes":{"get":{"summary":"Lister les bons de livraison transmis","operationId":"listDeliveryNotes","parameters":[{"name":"updatedSince","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200}},{"name":"offset","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Bons de livraison et état de dépôt"}}},"post":{"summary":"Déposer un BLV depuis l’ERP/WMS","operationId":"createDeliveryNote","description":"Crée le BLV PharmaML et son message de dépôt FIFO. externalId garantit l’idempotence.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryNoteInput"}}}},"responses":{"200":{"description":"Rejeu idempotent"},"201":{"description":"BLV créé et placé au dépôt"},"409":{"description":"Conflit d’idempotence"},"422":{"$ref":"#/components/responses/ValidationError"}}}},"/outbox":{"get":{"summary":"Superviser le dépôt PharmaML","operationId":"listOutbox","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","delivered","acked","expired","cancelled"]}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200}},{"name":"offset","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Messages sortants, tentatives et acquittements"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"PmlFiT API key"}},"parameters":{"OrderId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}},"responses":{"ValidationError":{"description":"Données invalides","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"NotFound":{"description":"Ressource introuvable","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"schemas":{"ListResponse":{"type":"object","properties":{"data":{"type":"array","items":{}},"meta":{"type":"object"}}},"ProductInput":{"type":"object","required":["name","cip13"],"properties":{"name":{"type":"string"},"cip13":{"type":"string"},"gtin":{"type":["string","null"]},"internalReference":{"type":["string","null"]},"costPrice":{"type":["number","null"],"minimum":0},"salePrice":{"type":["number","null"],"minimum":0},"vatRate":{"type":"number","default":2.1},"availabilityCode":{"type":"string","pattern":"^000[0-8]$","default":"0000"},"active":{"type":"boolean","default":true}}},"AvailabilityRequest":{"type":"object","required":["lines"],"properties":{"pharmacyCode":{"type":"string"},"lines":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"object","required":["lineNumber","code","quantity"],"properties":{"lineNumber":{"type":"integer"},"code":{"type":"string"},"quantity":{"type":"integer","minimum":1}}}}}},"OrderState":{"type":"string","enum":["received","confirmed","preparing","done","cancelled","rejected"]},"OrderUpdate":{"type":"object","properties":{"state":{"$ref":"#/components/schemas/OrderState"},"distributorReference":{"type":"string"},"lines":{"type":"array","items":{"type":"object","required":["lineNumber","acceptedQuantity"],"properties":{"lineNumber":{"type":"integer"},"acceptedQuantity":{"type":"integer","minimum":0},"responseCode":{"type":"string","pattern":"^000[0-8]$"}}}}}},"DeliveryNoteInput":{"type":"object","required":["externalId","pharmacyCode","deliveryReference","deliveredAt","lines"],"properties":{"externalId":{"type":"string","description":"Identifiant stable et unique côté ERP/WMS"},"pharmacyCode":{"type":"string"},"orderId":{"type":["string","null"],"format":"uuid"},"orderReference":{"type":["string","null"]},"deliveryReference":{"type":"string"},"deliveredAt":{"type":"string","format":"date-time"},"currency":{"type":"string","const":"EUR","default":"EUR"},"metadata":{"type":"object","additionalProperties":true},"lines":{"type":"array","minItems":1,"maxItems":500,"items":{"$ref":"#/components/schemas/DeliveryNoteLineInput"}}}},"DeliveryNoteLineInput":{"type":"object","required":["lineNumber","productCode","deliveredQuantity"],"properties":{"lineNumber":{"type":"integer","minimum":1},"productCode":{"type":"string"},"productName":{"type":"string"},"deliveredQuantity":{"type":"integer","minimum":1},"orderedQuantity":{"type":["integer","null"],"minimum":0},"customerOrderReference":{"type":["string","null"]},"unitPriceExclTax":{"type":["number","null"],"minimum":0},"netPriceExclTax":{"type":["number","null"],"minimum":0},"vatRate":{"type":["number","null"],"minimum":0,"maximum":100},"lotNumber":{"type":["string","null"]},"expiryDate":{"type":["string","null"],"format":"date"}}},"Problem":{"type":"object","required":["type","title","status","detail"],"properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"}}}}}}