{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/lexio-rent/json-schema/lexio-rent-invoice-schema.json",
  "title": "Invoice",
  "x-generated": "2026-11-10",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/lexio-rent-paiements-api-openapi.yml#/components/schemas/Invoice",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Identifiant de la pièce."
    },
    "rentalId": {
      "type": "string",
      "format": "uuid",
      "description": "Location concernée (`GET /rentals/{rentalId}`)."
    },
    "number": {
      "type": "string",
      "description": "Numéro légal de la pièce, unique et séquentiel."
    },
    "type": {
      "type": "string",
      "enum": [
        "INVOICE",
        "CREDIT_NOTE"
      ],
      "description": "`INVOICE` : facture ; `CREDIT_NOTE` : avoir."
    },
    "status": {
      "type": "string",
      "enum": [
        "ISSUED",
        "PAID",
        "PARTIALLY_PAID",
        "CANCELLED"
      ],
      "description": "État de paiement : `ISSUED` émise, `PARTIALLY_PAID`, `PAID`, `CANCELLED` annulée par un avoir."
    },
    "creditedInvoiceId": {
      "anyOf": [
        {
          "type": "string",
          "format": "uuid"
        },
        {
          "type": "null"
        }
      ],
      "description": "Avoir : facture créditée. Facture : null."
    },
    "creditNoteReason": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "CANCELLATION",
            "ERROR",
            "COMMERCIAL"
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "Motif de l’avoir ; null pour une facture."
    },
    "issueDate": {
      "anyOf": [
        {
          "type": "string",
          "format": "date"
        },
        {
          "type": "null"
        }
      ],
      "description": "Jour d’émission, fuseau du loueur ; null pour une pièce ancienne non datée."
    },
    "dueDate": {
      "anyOf": [
        {
          "type": "string",
          "format": "date"
        },
        {
          "type": "null"
        }
      ],
      "description": "Jour d’échéance du paiement ; null si aucun."
    },
    "totalHT": {
      "type": "number",
      "description": "Total HT ; négatif pour un avoir."
    },
    "vatAmount": {
      "type": "number",
      "description": "Montant de TVA : `totalTTC` − `totalHT`."
    },
    "totalTTC": {
      "type": "number",
      "description": "Total TTC ; négatif pour un avoir."
    },
    "paidAmount": {
      "type": "number",
      "minimum": 0,
      "description": "Montant TTC déjà réglé."
    },
    "dueAmount": {
      "type": "number",
      "minimum": 0,
      "description": "Montant TTC restant à régler."
    },
    "vatPercent": {
      "type": "number",
      "minimum": 0,
      "maximum": 100,
      "description": "Taux de TVA de la pièce, en %."
    },
    "isVatReverseCharge": {
      "type": "boolean",
      "description": "true : facturée en autoliquidation, la TVA est due par le client."
    },
    "currency": {
      "type": "string",
      "enum": [
        "EUR",
        "XPF",
        "CHF",
        "CAD",
        "GBP",
        "USD",
        "XOF"
      ],
      "description": "Devise de la pièce (ISO 4217)."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time",
      "description": "Création, heure du loueur avec décalage."
    },
    "document": {
      "anyOf": [
        {
          "$ref": "#/$defs/SignedDocument"
        },
        {
          "type": "null"
        }
      ],
      "description": "PDF de la pièce, URL signée valable une heure, à ne pas stocker ; null tant que le PDF n’est pas généré."
    }
  },
  "required": [
    "id",
    "rentalId",
    "number",
    "type",
    "status",
    "creditedInvoiceId",
    "creditNoteReason",
    "issueDate",
    "dueDate",
    "totalHT",
    "vatAmount",
    "totalTTC",
    "paidAmount",
    "dueAmount",
    "vatPercent",
    "isVatReverseCharge",
    "currency",
    "createdAt",
    "document"
  ],
  "$defs": {
    "SignedDocument": {
      "type": "object",
      "properties": {
        "url": {
          "type": "string",
          "format": "uri",
          "description": "Adresse signée et temporaire du fichier : ne la conservez pas, relisez la ressource pour en obtenir une nouvelle."
        },
        "expiresAt": {
          "type": "string",
          "format": "date-time",
          "description": "Instant où l’adresse cesse d’être valable."
        }
      },
      "required": [
        "url",
        "expiresAt"
      ],
      "description": "Fichier téléchargeable par une adresse signée et temporaire."
    }
  }
}