Complementary Attribut dans le module third-party

Bonjour,

Nous sommes en train de migrer d’une13.x à la 14.0.3.
Dans le module thirdpart nous avons en prod (13.x) une complementary attribut qui nous permet de récupérer le nombres de factures impayées pour chaque client quand nous affichons /dolibarr/societe/list.php :

($myfunc = function($obj) {     try     { 		require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php'; 		require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php'; 		require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/api_invoices.class.php'; 	$myInvoices = new Invoices();	$ret=$myInvoices->index('t.rowid','ASC',100,0,$obj->rowid,'unpaid',''); return count($ret);    }     catch (Exception $ex)     {         return 0;     } }) ? $myfunc($obj) : 0

Nous avons découvert en test (14.0.3) que le mot clef php functions n’est plus autorisé. Nous essayons de récrire notre expression comme suit :

((require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php') && 
 (require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php') &&
 (require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/api_invoices.class.php') && 
 ($myInvoices= new Invoices()) && 
($ret=$myInvoices -> index('t.rowid', 'ASC', 100, 0, $obj->rowid, 'unpaid', '')) 
) ? count($ret) : 666

Cela ne fonctionne pas : nous affichons les premiers champs du premier (dans l’ordre alphabétique) clients mais arrivé au complementary attribut, nous n’avons plus rien d’affiché et le reste des champs est vide ainsi que le reste de la table.

Il semble que l’appel à $myInvoices->index échoue.

Est-ce que quelqu’un a une solution autre que de modifier le code source afin de ré autoriser le mot clef functions ?

Merci

Bonjour,

Une possibilité serait de vous créer un module (minimaliste) pour remplacer cet attribut complémentaire. Le module (à mettre dans custom) aurait (en gros) les fichiers suivants :

  • core/modules/modvec.class.php → avec le tableau parts['hooks'] renseigné pour utiliser les hooks sur thirdpartylist
  • class/actions_vec.class.php → fichier des hooks définissant les méthodes suivantes :
    • printFieldListSelect()
    • printFieldListWhere()
    • printFieldPreListTitle(),
    • printFieldListOption(),
    • printFieldListTitle(),
    • printFieldListValue()
    • printFieldListFooter()

Merci pour votre suggestion.

Nous allons voir s’il y a d’autres propositions qui nous permettent d’utiliser pleinement ces complementary attributs, dans un premier temps.

@vec Il y a bien une possibilité de contourner l’interdiction sans modifier le code du cœur en ajoutant, par exemple, un espace avant la parenthèse ouvrante.

Le problème, c’est justement que ça contourne une limitation volontaire de la fonctionnalité (limitation motivée par des considérations de sécurité). Autrement dit : ça peut marcher, mais il faut s’attendre à ce que la prochaine mise à jour mineure rende cette « technique » inopérante.

Peut-être que d’autres membres auront une solution à base d’attribut complémentaire qui n’utilise aucune des fonctions interdites : ce serait très largement préférable.

@fmortgat :rofl: bien vu !
Cela m’a aidé à débuguer. Je pense que j’ai un souci de permission en fait. Je n’arrivais pas à le voir car je n’ai pas de try catch dans la nouvelle syntaxe.

Je plante dès le début de l’appel à la fonction Index. Mon utilisateur pourtant admin, n’aurait pas le droit en lecture sur les factures en passant par l’API ?

if (!DolibarrApiAccess::$user->rights->facture->lire) {
             throw new RestException(401);}

J’ai été explorer le setup du module API. Cela sent pas bon (ou plus si, d’un point de vue solution) : les URL indiquées pour explorer l’API ou s’identifier par exemple ont pour IP de base celle de notre ancienne instance dolibarr de prod sur laquelle est basée ce docker test… On devrait résoudre le soucis en corrigeant c’est URLs.

On devrait s’en sortir, merci beaucoup pour votre aide, on vous tient au courant.

Re,

En fait c’est plus un souci d’assignation que de droit. $user->rights->facture->lire vaut bien True pour user. Par contre après plusieurs tests, j’ai constaté que DolibarrApiAccess::$user n’est jamais assigné.

Ce n’était pas un problème en 13.x car la fonction index ne faisait pas de security check.

En nous servant de l’astuce (temporaire) de @fmortgat nous avons pu faire marcher notre ancien code légèrement modifié.

($myfunc = function ($obj, $usr) { try { 		require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php'; 		require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php'; 		require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/api_invoices.class.php'; 	DolibarrApiAccess::$user=$usr; $myInvoices = new Invoices();	 $ret=$myInvoices->index('t.rowid','ASC',100,0,$obj->rowid,'unpaid',''); return count($ret); } catch (Exception $ex) { return 0; } }) ? $myfunc($obj, $user) : 0

On a regardé pas-à-pas ce que l’on pouvait faire avec la notation classique sans injection.

((require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php') && 
 (require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php') &&
 (require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/api_invoices.class.php') && 
 ($myInvoices= new Invoices()) &&  
 (DolibarrApiAccess::$user=$user) 
) ? var_dump(!DolibarrApiAccess::$user->rights->facture->lire) : 666

renvoie bien des 1 sur chaque ligne : l’assignation fonctionne et j’ai bien les droits.

Si maintenant j’essaie de rajouter l’évaluation de index, je me retrouve comme au début de ce post:

((require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php') && 
 (require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php') &&
 (require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/api_invoices.class.php') && 
 ($myInvoices= new Invoices()) &&  
 (DolibarrApiAccess::$user=$user) &&
 ( $ret=$myInvoices->index('t.rowid','ASC',100,0,$obj->rowid,'unpaid','')) //appel à la fonction index
) ? var_dump(!DolibarrApiAccess::$user->rights->facture->lire) : 666

Déplacer l’assignation de DolibarrApiAccess::$user avant ou après l’initialisation de $myInvoices ne change rien.

@fmortgat si jamais vous passez par là (ou tout autre personne) nous sommes preneurs de vos conseils !

Merci

Bonjour à tous. Merci @vec pour ce post, mais dommage, je n’interviens pas pour vous aider pour régler votre souci, par contre je le fais pour vous demander votre astuce pour afficher la balance TTC sur la liste des clients ?
Merci d’avance

Bonjour @djaber,
reportez vous à mon premier post si vous êtes ave une version < à 14.x :

($myfunc = function($obj) {     try     { 		require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php'; 		require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php'; 		require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/api_invoices.class.php'; 	$myInvoices = new Invoices();	$ret=$myInvoices->index('t.rowid','ASC',100,0,$obj->rowid,'unpaid',''); return count($ret);    }     catch (Exception $ex)     {         return 0;     } }) ? $myfunc($obj) : 0

Si vous êtes avec une version > à 14.x voir ma dernière reply :

($myfunc = function ($obj, $usr) { try { 		require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php'; 		require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php'; 		require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/api_invoices.class.php'; 	DolibarrApiAccess::$user=$usr; $myInvoices = new Invoices();	 $ret=$myInvoices->index('t.rowid','ASC',100,0,$obj->rowid,'unpaid',''); return count($ret); } catch (Exception $ex) { return 0; } }) ? $myfunc($obj, $user) : 0

Ces formules sont à ajouter (l’une ou l’autre) dans un complementary attribut du type integer du module third party : dolibarr/societe/admin/societe_extrafields.php.

Merci

1 « J'aime »

Bonjour @vec merci pour votre code, il renvoi correctement le nombre de facture impayée sur une liste client, ce que je souhaite afficher avec la même méthode c’est la balance en TTC (l’encours client) comme illustre votre capture écran de votre premier post dans ce sujet

Faites un deuxième champs et parcourez les invoices ‹ unpaid › que vous savez récupérer maintenant.

$balanceTTC = 0; 		foreach($ret as $value) 		{ 			$balanceTTC = $balanceTTC + $value->total_ttc; 		} 		return $balanceTTC; 

Cdt

Je ne sais pas comment le faire. J’ai crée un deuxième attribut le résultat renvoi 0

Bonjour, le 2e champ est exactement comme le premier sauf qu’il est du type currency.
Il faut remplacer le compte des invoices par la somme de leur totaux respectifs. Je vous ai tout donné au dessus…
Il faut remplacer la chaîne (dans formule que vous utilisez suivant votre version)

return count($ret); 

par

$balanceTTC = 0; 		foreach($ret as $value) 		{ 			$balanceTTC = $balanceTTC + $value->total_ttc; 		} 		return $balanceTTC;

Cdt

1 « J'aime »

Bonjour @vec sincèrement vous faite mon bonheur et sûrement aussi celui de plusieurs comme moi dans ce forum, qui cherchent de l’aide fonctionnelle pour faire fonctionner un nouveau code.
Doli un outil puissant et utile pour la gestion d’entreprise mais dommage le savoir pour apprendre n’est pas partagé! encore une fois je vous remercier d’avoir partager votre savoir.

Un dernier souci l’encours affiché ne prend pas en charge le décimal float ou quelque chose comme ça dans le langage PHP et ne prend pas la forme d’un montant.

Cordialement,
Djaber

Au temps pour moi, nous avons utilisé un champ « Price ». Nous avons bien les décimales.
Cdt

Oui, ce champ renvoi bien les décimales. Mais le code de l’attribut renvoi le total TTC des factures et non la balance qui est (debit - credit) c’est le même cas pour vous ?

Le champ fait ce qu’on lui de faire :wink:
En l’occurence il renvoie le total des factures impayées pour chacun de nos clients. Ce qui correspond à notre besoin.

J’ai le même besoin que vous, (debit - credit) mais dans mon cas il renvoi le total TTC des impayés sans prendre en considération les paiements reçus, c’est à dire si une facture n’est pas totalement payée il affiche le montant total.

Oui cette approximation est suffisante pour nous. Il y normalement une fonction getRemainToPay() mais elle semble bugguée. Nous n’avons pas le temps d’investiguer plus à ce jour.
Merci

1 « J'aime »

Bonjour à tous,

Update : on teste la version 15 et @fmortgat avait bien senti la chose l’astuce de la dernière fois ne fonctionne plus.

Donc on doit re tenter la version classique des complementary attribut en utilisant une formule (avec des ‹ ? › et des ‹ : ›).

On est reparti sur la même base et visiblement quelque chose à été amélioré ça marche presque et la raison du non succès est décevante.

((require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php') &&
 (require_once DOL_DOCUMENT_ROOT.'/api/class/api_access.class.php') &&
 (require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/api_invoices.class.php') &&
 ($myInvoices= new Invoices()) &&
 (DolibarrApiAccess::$user=$user) &&
 ( $ret=$myInvoices->index('t.rowid','ASC',100,0,$obj->rowid,'unpaid','')) //appel à la fonction index
) ? sizeof($ret) : 666

me donne

Le code s’arrête car la fonction index de l’objet Invoices renvoie une exception quand il ne trouve pas d’invoice répondant aux critère passés en argument. Cela semble un peu exagéré :smiley: à mon goût.

Avez-vous idée de si c’est un bug ? où le remonter ?
Comment le contourner proprement (sans toucher au sources) ?
On a essayé de reloader l’objet Societe et d’utiliser la function getOuttandingBills et c’est pire : on y arrive pas.

Une idée les gens ? :slight_smile:

:slight_smile: Bon on a vaincu la doc…

pour la balance

(($reloadedobj = new Societe($db)) && ($reloadedobj->fetchNoCompute($obj->rowid)) && ( $ret=$reloadedobj->getOutStandingBills())
) ? $ret['opened']: 666

et pour le nombre de facture ouvertes

(($reloadedobj = new Societe($db)) && ($reloadedobj->fetchNoCompute($obj->rowid)) && ( $ret=$reloadedobj->getOutStandingBills())
) ? sizeof($ret['refsopened']): 666

Le piège c’est fetchNoCompute qui ne s’invente pas et qu’il faut appliquer bêtement en s’inspirant de l’exemple accessible via le :grey_question: au moment de l’édition du champ.

4 « J'aime »