Créer une facture ou un devis

La création de facture passe par 4 étapes. La première est l'authentification qui permet de récupérer votre token pour pouvoir échanger avec l'API. Ensuite vient la récupération de votre application Sinao. Avec votre token et votre application ID, vous pourrez créer votre premier client, votre premier produit (facultatif), puis votre premier document (facture ou devis).

1. Authentification


2. Récupération de l'application Sinao


3. Créer et rechercher un client


4. Créer et rechercher un produit


5. Création de la facture


Pour créer une facture ou un devis on enverra les données à /apps/:appId/invoices pour les factures et à /apps/:appId/quotes pour les devis.

Les éléments les plus importants d'un document (factures et devis)

Explications et détails des paramètres

Options possible pour l'exemption de TVA

  • Options

    [
    	{
    		"reason": "micro",
    		"display": "Micro-entreprise",
    		"article": "TVA non applicable, art. 293 B du CGI"
    	},
    	{
    		"reason": "reversecharge",
    		"display": "Autoliquidation de la TVA en cas de sous-traitance",
    		"article": "Autoliquidation"
    	},
    	{
    		"reason": "intracommunity-service",
    		"display":
    			"Prestations de services immatérielles facturées à des clients situés dans l’UE",
    		"article":
    			"Autoliquidation - TVA due par le preneur en application de l’article 259 du CGI"
    	},
    	{
    		"reason": "intracommunity-product",
    		"display": "Livraisons intracommunautaires",
    		"article":
    			"Exonération de TVA en application de l’article 262 ter, I 1° du CGI - article 138 paragraphe 1 de la directive 2006/112/CE"
    	},
    	{
    		"reason": "no-eu-service",
    		"display":
    			"Prestations de services immatérielles facturées à des clients hors de l’UE",
    		"article": "Exonération de TVA en vertu de l’article 259 1° du CGI"
    	},
    	{
    		"reason": "export",
    		"display": "Exportations",
    		"article":
    			"Exonération de TVA en application de l’article 262 I, 1° du CGI – article 146, paragraphe 1, point a} de la directive 2006/112/CE"
    	},
    	{
    		"reason": "dom",
    		"display":
    			"Ventes depuis la France métropolitaine vers les DOM (Guadeloupe, Martinique, Réunion et Guyane}",
    		"article":
    			"Exonération de TVA en application des articles 262 I, 1° et 294 2} du CGI "
    	},
    	{
    		"reason": "triangular-operation",
    		"display":
    			"Livraisons réalisées dans le cadre d’opérations triangulaires simplifiées",
    		"article":
    			"Exonération de TVA en vertu de l’article 28 quater du CGI – article 141 de la directive 2006/112/CE "
    	},
    	{
    		"reason": "intracommunity-tangiblework",
    		"display":
    			"Travaux et expertises sur biens meubles corporels réalisés en France, puis réexpédiés vers un autre Etat membre de l’UE avec facturation à un client assujetti dans un autre pays de l’UE",
    		"article":
    			"Autoliquidation - TVA due par le preneur en application de l’article 259 A 4° bis du CGI – article 55 de la directive 2006/112/CE "
    	},
    	{
    		"reason": "intracommunity-tangibletransport",
    		"display": "Transports intracommunautaires de biens meubles corporels",
    		"article":
    			"Autoliquidation - TVA due par le preneur en application de l’article 259 A 3° du CGI – article 47, 1er et 2ème alinéas de la directive 2006/112/CE"
    	},
    	{
    		"reason": "intracommunity-tangibletransport-service",
    		"display":
    			"Prestations accessoires aux transports intracommunautaires de biens meubles corporels",
    		"article":
    			"Autoliquidation - TVA due par le preneur en application de l’article 259 A 5° du CGI – article 53 de la directive 2006/112/CE"
    	},
    	{
    		"reason": "intracommunity-vehicledelivery",
    		"display": "Livraison intracommunautaire d'un véhicule neuf",
    		"article":
    			"Exonération de TVA, article 298 sexies II du CGI – article 138 paragraphe 2, a de la directive 2006/112/CE"
    	},
    	{
    		"reason": "null",
    		"display": "Aucune mention",
    		"article": " "
    	}
    ]
    

Forcer la création d'un client sans identifiant

Si vous êtes certain que le client sur votre document est nouveau, pour vous éviter de faire deux requêtes, une pour la création du client et une autre pour la création du document. Vous disposez de la clé new dans l'objet contact_infos : un boolean qui vous permettra de forcer la création du client si vous lui affectez une valeur true.

  • Exemple

    // Pas besoin de l'ID, new créera un nouveau client pour vous.
    
    "contact_infos": {
    	"new": true,
    	"name": "SINAO",
    	"billing_name": "SINAO",
    	"type": "organization",
    	"location": "38100 Grenoble - France",
    	"address": "29 Chemin de l'Église"
    },
    

Exemple de création de facture

  • Requête

    var myHeaders = new Headers();
    
    myHeaders.append("Authorization", "Bearer <token>");
    myHeaders.append("Content-Type", "application/json");
    
    var raw = JSON.stringify({
    	"status": "draft",
      "tags": [
        "facture",
        "produit"
      ],
      "contact_infos": {
        "id": 1, // L'ID du client
        "name": "SINAO",
        "billing_name": "SINAO",
        "type": "organization",
        "location": "38100 Grenoble - France",
        "address": "29 Chemin de l'Église"
      },
      "details": "Autres détails",
      "title": "Titre de la facture",
      "payment_period": 30,
      "legal_notice": "Mentions!",
      "columns": {
        "designation": "Designation", // designation sera affiché comme "Designation".
        "quantity": "Qte",
        "quantity_name": false, // quantity_name ne sera pas affiché
        "info_total_quantity": false,
        "amount": "P.U HT",
        "amount_with_taxes": false,
        "discount": false,
        "subtotal": "Total HT",
        "due": false,
        "vat_percent": false
      },
      "vat_exemption": {
        "exempted": false,
        "reason": "micro",
        "article": "TVA non applicable, art. 293 B du CGI"
      },
      "downpayment_request": {
        "amount": 0, // Montant * 100
        "percent": 1000 // Montant * 100
      },
      "content": [
        {
          "title": "Titre de la section 1",
          "lines": [
            {
              "detail": "Mon produit 1",
              "product_id": null, // ID du produit
              "account_id": 57, // ID de votre compte comptable
              "type": "product", // product ou service
              "action": "sell", // sell ou rent
              "quantity": 1,
              "amount_accurately": 500000000, // Prix * 100 * 1000
              "vat_percent": 2000, // Pourcentage de TVA * 100
              "discount": {
                "amount": 0, // Montant * 100
                "percent": 0 // Montant * 100
              },
              "unity": "",
              "total_quantity": 0
            },
            {
              "detail": "Mon produit 2",
              "product_id": null,
              "account_id": 57,
              "type": "product",
              "action": "sell",
              "quantity": 3,
              "amount_accurately": 30000000,
              "vat_percent": 2000,
              "discount": {
                "amount": 0,
                "percent": 0
              },
              "unity": "",
              "total_quantity": 0
            },
            {
              "type": "description",
              "detail": "Commentaire"
            }
          ]
        },
        {
          "title": "Titre de la section 2",
          "lines": [
            {
              "detail": "Mon produit 3",
              "product_id": null,
              "account_id": 57,
              "type": "product",
              "action": "sell",
              "quantity": 2,
              "amount_accurately": 9000000,
              "vat_percent": 2000,
              "discount": {
                "amount": 0,
                "percent": 0
              },
              "unity": "",
              "total_quantity": 0
            }
          ]
        }
      ],
    	"downpayments":[ 169, 168 ],
      "discount": {
        "name": "Remise spéciale",
        "amount": 20000 // Montant * 100
      },
      "written_at": "2021-05-12T12:33:03Z",
      "delivered_at": "2021-05-31T00:00:00Z",
      "commercialvalidity_deadline": "2021-05-31T00:00:00Z",
      "downpayments": [],
      "bank_details_id": 1
    });
    
    var requestOptions = {
    		method: 'POST',
    		headers: myHeaders,
    		body: raw,
    		redirect: 'follow'
    };
    
    fetch("https://api.sinao.app/v1/apps/:appId/invoices?expand[]=content", requestOptions)
    		.then(response => response.text())
    		.then(result => console.log(result))
    		.catch(error => console.log('error', error));
    

Transitions de l'état d'un document

Facture

Draft

Par défaut, une facture commence à l'état draft. Cet état signifie que la facture est un brouillon : elle est modifiable, supprimable, n'a pas de numéro de facture, pas de date fixée et n'est pas enregistrée en comptabilité. Ce statut sert principalement à sauvegarder une facture en cours de rédaction.

Final
Pour attribuer un numéro et une date à votre facture il vous faudra la passer à l'état "final" grâce au endpoint /apps/appId/invoices/id/finalize. Le passage a cet état nécessite qu'un client soit attribué à la facture, cet état attribuera également à votre facture une date d'écriture et ne sera plus modifiable. La date d'écriture doit toujours être postérieure à la date de la facture précédente pour que la suite des numéros de factures restent dans un ordre chronologique. Dans cet état, la facture ne sera plus modifiable ni supprimable.

  • Requête

    var myHeaders = new Headers();
    
    myHeaders.append("Authorization", "Bearer <token>");
    
    var requestOptions = {
    		method: 'POST',
    		headers: myHeaders,
    		redirect: 'follow'
    };
    
    fetch("https://api.sinao.app/v1/apps/:appId/invoices/:invoiceId/finalize", requestOptions)
    		.then(response => response.text())
    		.then(result => console.log(result))
    		.catch(error => console.log('error', error));
    

Réglée
Pour notifier votre facture comme réglée, plusieurs options existent :

  • Forcer le passage en "réglée" en modifiant le statut en paid
  • Rapprocher la facture avec une transaction bancaire en créant un Payment
  • Rapprocher la facture avec une entrée de caisse en créant un Payment avec pour type cashdesk_entry.

Devis

Par défaut un devis sera toujours modifiable et supprimable peu importe son status.

Draft

Par défaut, un devis commence à l'état draft. Cet état signifie que le devis est un brouillon : il est modifiable, supprimable, n'a pas de numéro de devis, pas de date fixée. Ce statut sert principalement à sauvegarder un devis en cours de rédaction.

Waiting
Pour attribuer un numéro et une date à votre devis il vous faudra la passer à l'état waiting.


Transformer un devis en facture

Pour transformer votre devis en facture vous devez le finaliser en faisant appel à l'endpoint /apps/appId/quotes/id/invoice avec votre application ID et votre quote ID, une copie de votre devis sera créée en tant que facture avec le status draft.

  • Requête

    var myHeaders = new Headers();
    
    myHeaders.append("Authorization", "Bearer <token>");
    
    var requestOptions = {
    		method: 'POST',
    		headers: myHeaders,
    		redirect: 'follow'
    };
    
    fetch("https://api.sinao.app/v1/apps/:appId/quotes/:quoteId/finalize", requestOptions)
    		.then(response => response.text())
    		.then(result => console.log(result))
    		.catch(error => console.log('error', error));
    

Configurer le numéro du document

Le numéro d'un document se compose d'un préfix, d'une longueur, et d'un format.

  • Le préfix sera la chaine de caractères qui sera ajoutée au début de chaque numéro de document.
  • La longueur définira le nombre de zéros à ajouter à votre numérotation, par exemple une longueur de 3 avec un numéro de démarrage à 1 ajoutera 001 au format de numérotation.
  • Le format se compose d'un séparateur, d'une année, d'un mois et d'un compteur de démarrage.
    • Vous pouvez choisir parmi les séparateurs suivants : "", "-", "/", "_", "*", "|", "#", "~"
    • Pour l'année il faut écrire : "Y"
    • Pour le mois il faut écrire : "m"
    • Pour le compteur il faut écrire : "x"

Exemple

Nous voulons définir le numéro de facture suivant : FACTURE#2021#5#00000003.

  • Votre préfix est : FACTURE

  • Votre longueur est : 8

  • Chiffre de démarrage du compteur : 3

  • Votre format est : #Y#m#x (Représenté par : #2021#5#00000003)

  • Requête

    var myHeaders = new Headers();
    
    myHeaders.append("Authorization", "Bearer  <token>");
    myHeaders.append("Content-Type", "application/json");
    
    var raw = JSON.stringify({
      "settings": {
        "accounting.piecenumbering.invoices.start": 2,
        "accounting.piecenumbering.invoices.format": "#Y#m#x",
        "accounting.piecenumbering.invoices.length": 8,
        "accounting.piecenumbering.invoices.prefix": "FACTURE"
      }
    });
    
    var requestOptions = {
    		method: 'POST',
    		headers: myHeaders,
    		body: raw,
    		redirect: 'follow'
    };
    
    fetch("https://api.sinao.app/v1/apps/:appId/settings", requestOptions)
    		.then(response => response.text())
    		.then(result => console.log(result))
    		.catch(error => console.log('error', error));
    

Prévisualisation du numéro du prochain document

Les numéros de vos documents sont séquentiels, pour pouvoir récupérer le prochain numéro de facture ou de devis il faut faire appel aux endpoints /apps/appId/invoices/nextnumber ou /apps/appId/quotes/nextnumber


Télécharger un document

PDF

Pour télécharger un document (facture ou devis) en PDF vous devez faire appel à l'endpoint /apps/appId/invoices/id/pdf ou /apps/appId/quotes/id/pdf

JPEG

Pour télécharger un document (facture ou devis) en JPEG vous devez faire appel à l'endpoint /apps/appId/invoices/id/preview.jpg ou /apps/appId/quotes/id/preview.jpg

6 - Confirmer une facture


7 - Envoyer une facture