Création facture fournisseur via API - partie 2

Bonjour à tous,

Je rouvre un message suite à mon sujet précédent.

Merci @defrance @Headstorm d’y avoir répondu.

Mon problème est le suivant.

Lorsque je crée une nouvelle facture fournisseur via API, j’ai une référence en (PROVxx). Je poste ma capture écran.

Mais par la suite je vais vouloir dans un deuxième temps ajouter des lignes de facturation.

Ce qui ne me plait pas, c’est que je ne peux pas créer ma référence de facture dès le départ (autre que PROVxx et contrairement à un import CSV) et donc, impossible d’utiliser la référence comme pivot pour ajouter mes lignes de facturation.

Dans le sujet précédent @Headstorm, tu indiques ceci
« il est nécessaire de créer la facture (fournisseur ou client), de la valider et ensuite de d’ajouter les lignes de facturation. »
Alors bien que cela soit factuellement incorrect, car il est possible de créer une facture fournisseur en PROVxx sans valider la facture puis on peut rajouter les lignes de facturation à partir du moment où l’on connait le supplierinvoice id.
Je comprends à présent mieux ta remarque, car en pratique ce n’est plus si évident.

Q1) @Headstorm peux-tu me réexpliquer ta remarque car en GUI, à partir du moment où tu as validé la facture, tu ne peux plus rajouter de lignes de facturation. Via API c’est possible ?
A première vue, il faudrait valider puis repasser en brouillon

Q2) Vu qu’en validant une facture fournisseur puis en la repassant en brouillon, on a plus une référence en PROVxx mais en QQchose1234, j’aurais souhaité pouvoir fixer cette référence dès le départ via API.
Afin que lors d’un deuxième tour (pas dans le même script) je puisse rajouter mes lignes de facturation en me basant sur la référence que j’ai fixée dès le départ QQchose1234 ou QQchose4567 (à l’image de ce qui peut être fait via import CSV)
Est-ce possible ?

Si je ne suis pas clair, dites le moi, je ferai toutes les captures écran.

Bonjour,

pourquoi ne pas utiliser le rowid comme « pivot »?
Dans les lignes de factures, la clé étrangère est une relation avec le rowid de llx_facturefournisseur. Et au moins ce champ là ne change pas lors du passage de brouillon à validé

Bonjour @cdeboudt,

Je crois que je n’ai pas été très clair dans mon explication voulant expliquer plus rapidement que nécessaire.

a) Dans le module fournisseur, j’ai configuré la règle de numérotation de mes factures en utilisant le modèle tulip
image

b) Puis lorsque je crée via API une facture fournisseur, j’envoie en paramètre une référence fournisseur (FSFOU2207009 avec un 9 à la fin) mais celle-ci n’est pas prise en compte
$facture_fournisseur = [
« ref » => $reference,
« status » => « 1 »,
« libelle » => $libelle,
« paid » => « 0 »,
« ref_supplier » => $reference_supplier,
« date » => $date_facturation,
« date_echeance » => $date_echeance,
« mode_reglement_id » => $mode_reglement,
« cond_reglement_id » => $condition_reglement,
];

La référence qui apparait avant validation est PROVxx
Si je valide la facture, elle a la référence FSFOU2207001 (avec un 1 à la fin et non un 9 comme je l’aurais souhaité).

Conclusion: Je ne peux pas determiner via API mon numéro de facture, c’est Dolibarr qui le choisi en utilisant la règle tulip définie en a)

c) Quand je valide une facture, je ne peux pas ajouter de lignes services dans cette facture validée. Il est possible de rajouter des lignes de services seulement si la facture est en brouillon.
Ce point n’est pas important pour comprendre mon problème c’est juste une observation.

d) Lorsque je dois ajouter des lignes de services dans ma facture, il faut que j’identifie ma facture. Par exemple:

  • Pour le mois de septembre je rajoute une ligne de frais bancaires relative à mon service « frais bancaires 2,5 » pour un montant de 2,5€
  • Pour le mois de septembre je rajoute une ligne de frais bancaires relative à mon service « frais bancaires 2,5 » pour un montant de 2,5€ et une autre ligne de service « chequier 4,5 » pour un montant de 4,5€

Donc, pour ajouter ma ligne de service frais bancaire ou chequier sur la bonne facture je dois identifier ma facture cible.
Et le problème est le suivant: c’est que mon numéro de facture n’a pas été fixé de manière deterministe mais par Dolibarr, soit en PROVxx soit via le modèle tulip

Ceci est en opposition avec un import CSV, où dans mon CSV je peux fixer le numéro de facture dès le départ.

Le rowid, n’est pas un paramètre que je peux passer via API et est généré de manière incrémentale.

J’execute mes deux actions: création de facture et ajout de lignes de facturation en deux temps.
J’essaie juste de faire un import car le module d’import CSV est incomplet.

Ma question est donc la suivante:
Comment puis-je identifier ma facture fournisseur afin que je puisse ajouter mes lignes de facturation service, sachant qu’à la première exécution de mon script je vais avoir du PROV001, PROV002… mais si je supprime et recrée N fois mes factures elles vont être du type PROVn01, PROVn02…
Impossible dans ces conditions d’identifier ma facture.

L’idéal aurait été que dans le processus de création de mes factures (vierges) via API, je puisse lui fixer sa référence de facture (le champ ref - colonne 1 du screenshot ci-dessous)

PS: Désolé pour ma longue explication

Salut,
perso je préfère créé directement les factures avec les lignes, ça me parait plus simple à mettre en place. Tu prépare ton JSON à envoyer et tu poste ça directement. Pas besoin de faire ça en deux fois et donc de retrouver puis modifier les factures.
En python, avec la librairie Pandas pour préparer les données :

dict_invoice = {"socid": Fournisseur.item(),
                "date": date_fact.timestamp(),
                "ref_client": "%s-%s" % ('AR', date_fact.strftime("%d-%m-%Y")),
                "type": 0,
                "note_private": "import facture client le %s" % datetime.now().strftime("%A %d %B %Y %H:%M")}

dict_invoice["lines"] = []
for lignefact in lignes_fact.itertuples():
    dict_invoice["lines"].append({"desc": lignefact.Grp_article,
                                  "libelle": lignefact.Grp_article,
                                  "product_type": "0",
                                  "qty": 1,
                                  "subprice": lignefact.TTC/(1 + (ligne_AR.TxTVA/100)),
                                  "tva_tx": lignefact.TxTVA})

json_invoice = json.dumps(dict_invoice)
response_invoice = requests.post(factures_ventes_url, headers=header, data=json_invoice)

Merci pour cette approche.

Bonjour,

lorsque vous créez une facture avec l’API, la réponse renvoyée par l’API contient le rowid de cette facture. Vous utilisez ensuite ce rowid pour ajouter les lignes ou faire toute autre opération sur votre facture via l’API.

Bonjour @miky,

Désolé pour ce retour tardif, j’étais sur d’autres projets et ai délaissé un peu le forum ces derniers jours.

Pour répondre à tes questions :

Q1) @Headstorm peux-tu me réexpliquer ta remarque car en GUI, à partir du moment où tu as validé la facture, tu ne peux plus rajouter de lignes de facturation. Via API c’est possible ?
A première vue, il faudrait valider puis repasser en brouillon

il est effectivement nécessaire de la repasser en brouillon car une fois la facture validée on ne peut pas la modifier, donc voici un extrait du code que j’utilise dans un de mes projets pour la création d’une facture, ça te permettra peut-être de comprendre l’approche.

$type = 'invoices';
$lines = [];

// ajout des lignes de facture dans un tableau (exemple, 1 ligne de frais de port ici)

$lines[] = array(
            "rang" => 1,
            "desc" => "Frais de transport",
            "libelle" => "Frais de transport",
            "total_ht" => "29",
            "tva_tx" => $tva_tx,
            "total_tva" => "5.8",
            "total_ttc" => "34.8",
            "fk_product" => "73",
            "qty" => "1",
            "subprice" => "29",
            "ref" => "PORT",
            "product_type" => "1",   
        );

//création de la pièce 
 $d = array(
       "socid" => $id,
       "date" => $date,
       "remise_percent" => $remise_percent,
       "total_ht" => $total_ht,
       "total_tva" => $total_tva,
       "total_ttc" => $total_ttc,
       "lines" => $lines,
);
    
 $ret = createPiece($apiKey, $apiUrl, $type, $d); //endpoint POST /invoices
 // récupération du rowid
 $ret = json_decode($ret, true);

// validation ensuite de la pièce

$valid = validate($apiKey, $apiUrl, $ret, $type); // endpoint POST /invoices/{id}/validate

// une fois la pièce validée et le numéro de pièce incrémenté
//passage de la pièce en brouillon

$draft = settodraft($apiKey, $apiUrl, $ret, $type); //endpoint POST /invoices/{id}/settodraft

//tableau des modification
$ref = 'FSFOU2207009'; //référence que tu souhaites pour ta pièce
$d = array(
            "ref" => $ref,
            "lines" => $lines,
             (suite le la liste des modifs...)
        );

// envoi des modifications
$modif = modifyPiece($apiKey, $apiUrl, $ret, $d); // endpoint PUT /invoices/{id}

// validation ensuite de la pièce

$valid = validate($apiKey, $apiUrl, $ret, $type); // endpoint POST /invoices/{id}/validate

//on récupère les infos de la pièce

$p = getPiece($apiKey, $apiUrl, $type, $ret); //endpoint GET /invoices/{id}
$p = json_decode($p, true);

// on regénère le document pdf

$file = array(
         "modulepart" => $module, 
         "original_file" => $p['ref']."/".$p['ref'].".pdf", 
         "langcode" => "fr_FR"
);

$build = buildDocument($apiKey, $apiUrl, $file); //endpoint PUT /documents/builddoc


////////exemple de la fonction createPiece

function createPiece($apiKey, $apiUrl, $type, $data){

    $response = callApi('POST', $apiKey, $apiUrl.$type, json_encode($data));

    return $response;
}

Je suis dans la même logique que @Beers, on se base sur le rowid de la pièce (variable $ret dans mon code) pour manipuler les infos via l’api.

il est donc tout à fait possible d’effectuer toutes les manipulations que tu souhaites en 1 ou plusieurs traitements, il faut simplement penser a repasser la pièce en brouillon pour toute modification et regénérer le pdf ensuite pour la mise à jour.

j’espère que ca aide.

bon courage :slight_smile: