A complete tutorial to learn how to develop with ERP5
('jp jp',)
ERP5 Developer Tutorial (in French)
text/html
GFDL
None
Kevin
en
None
2005-04-07 07:58:12
2005-04-07 07:57:52
()
0
Tut o r i e l N e x e d i ERP5
Dveloppez votre propre Dveloppez ERP grce aux Business Templates ERP5
page 1/64
Tut o r i e l N e x e d i ERP5
page 2/64
Tut o r i e l N e x e d i ERP5
Sommaire
1. Introduction.............................................................................4 2. ERP5: un ERP pour tous............................................................5
2.1. ERP5 sans installation.......................................... .................................5 2.2. Installer un systme ERP5....................................................................5 2.3. Etendre ERP5 avec les Business Templates........................................10
3. Crons notre propre Business Template !.................................16
3.1. Conception de la structure de donnes..............................................16 3.2. Le variantage par catgories..............................................................20 3.3. Intgrons notre structure de donnes dans ERP5...............................21 3.4. Web Dveloppement rapide avec portal_classes................................22 3.5. Structure d'une classe Document dans ERP5......................................24 3.6. Crer un Module dans EPR5................................. ...............................27 3.7. Intgrer les classes, donnes, menus et prsentation : l'outil portal_types............................................................ ...................................29 3.8. L'interface utilisateur avec ERP5Form........................................ .........30 3.9. Les scripts python de calcul....................................... .........................43 3.10. Le reporting..................................... .................................................50 3.11. La cration du business template.....................................................60 3.12. Le point sur la catalogage................................................ .................62
4. Conclusion..............................................................................63 5. TODO.....................................................................................64
page 3/64
Tut o r i e l N e x e d i ERP5
1. Introduction
Cet article est destin aux dveloppeurs qui veulent s'approprier ERP5 et ses mcanismes pour en faire un outil de gestion d'entreprise qui rpond exactement leurs besoins. Avec ERP5, ce n'est plus l'entreprise qui se conforme la logique ERP, c'est l'ERP qui s'adapte la culture de l'entreprise, ses mthodes et ses habitudes de travail. ERP5 dispose sous forme de framework de tous les outils ncessaires pour atteindre cet objectif. Cela passe la plupart du temps par la ralisation ou la modification d'un module de l'ERP sous la forme d'un paquetage fonctionnel ou mtier appel "Business Template". Cet article vous apprendra installer rapidement une plate-forme ERP5 grce aux Business Template avant de vous accompagner dans la ralisation d'un module simple de gestion de feuilles de paie. Cette seconde partie de l'article sera l'occasion idale d'aborder toutes les techniques de conception au sein d'ERP5 pour que vous puissiez par la suite crer vos propres Business Template de faon autonome.
Support Commercial ERP5 ERP5 est un ERP libre en licence GPL dvelopp et dit par la socit Nexedi. Nexedi coordonne un rseau de partenaires certifis pour le dploiement de solutions ERP5 en entreprise. Nexedi et ses partenaires assurent travers leurs quipes d'ingnieurs et leurs consultants l'assistance, la formation et le transfert des comptences ncessaires la matrise d'ERP5 sur le terrain. http://www.erp5.org/sections/documentation/evangelism/enterprise/ Tel. +33 662 05 76 14 Mel. info@nexedi.com
page 4/64
Tut o r i e l N e x e d i ERP5
2. ERP5: un ERP pour tous
2.1. ERP5 sans installation
Si vous souhaitez utiliser ERP5 srieusement et sans perdre du temps dans des problmatiques d'installation sans valeur ajoute, nous vous recommandons d'utiliser le LiveCD d'ERP5 (et d'y contribuer). Le LiveCD ERP5 a t conu comme un outil de dveloppement et de production, et pas seulement comme un dmonstrateur. Il peut tre tlcharg sur: http://livecd.erp5.org. Son principe est simple :
On inserre un CD dans un PC standard, on appuye sur dmarrer puis, aprs quelques minutes, on installe des Business Template que l'on peut utiliser, paramtrer et tendre.
2.2. Installer un systme ERP5
Si l'usage d'un LiveCD ne vous convient pas, il est cependant possible d'installer ERP5 de faon traditionnelle. Il faut compter entre quelques dizaines de minutes (si vous utilisez une distribution comme Mandrakelinux pour laquelle tous les paquetages et leurs dpendances ont t crs) et quelques jours (si vous utilisez une distribution sans paquetages ERP5).
page 5/64
Tut o r i e l N e x e d i ERP5
Pour fonctionner, ERP5 a besoin du serveur d'applications Zope sur lequel il se fonde et ainsi qu'un nombre consquent de produits Zope. Nous avons aussi besoin d'installer MySQL-max (une version de la plus populaire des bases de donnes libres qui supporte les transactions). MySQL-max est utilis par le moteur de recherche de Zope via le produit ZSQLcatalog. Pour un systme complet, il nous faut donc :
un serveur Zope (et toutes ses dpendances li Python) comportant les optimisations dveloppes par Nexedi en matire de mta-programmation1 les produits Zope BTreeFolder, Base18, CMF, CMFActivity, CMFCategory, CMFMailIn, CMFPhoto, CMFReportTool, ERP5, ERP5Catalog, ERP5Compatibility, ERP5Form, ERP5SyncML, ERP5Type, ExtFile, Formulator, Localizer, Photo, TranslationService, ZMailIn, ZMySQLDA et ZSQLCatalog.
MySQL-max
Pour mener bien cette mission, il faudra compter sur les paquetages de votre distribution Linux. Vous pouvez aussi partir des sources et installer Zope par un traditionnel ./configure, make, make install. Quand aux produits Zope, ils sont trs faciles et rapide installer puisqu'il s'agit en fait d'archives dcompresser dans le rpertoire Products de Zope (gnralement /var/lib/zope/Products ou / usr/lib/zope/lib/python/Products) et de quelques extensions (zsqlbrain.py et InventoryBrain.py) ajouter dans le rpertoire Extensions de Zope (gnralement /var/lib/zope/Extensions ou /usr/lib/zope/lib/python/Extensions). Vous trouverez sans trop de difficults des didacticiels et de la documentation sur le net pour l'installation et la configuration globale de Zope. Les heureux utilisateurs de Mandrake peuvent se contenter d'un simple urpmi ERP5 mysql-max, aprs avoir ajout les sources main, contrib et nexedi2 leur gestionnaire de paquetages. Notons que l'ensemble des manipulations dcrites dans cet article ont t ralises sur une Mandrake 10.0 et devraient tre quivalentes avec une Mandrake 10.1. Une fois l'installation le des paquetages termine, utilisons la console d'administration de Zope, zopectl, pour changer le mot de passe par dfaut de l'administrateur (le login par dfaut tant admin). L'ajout d'un utilisateur ne peut se faire que si le serveur Zope est arrt. Il se peut trs bien que la procdure d'installation ait dmarr le serveur, nous l' arrterons donc avant la manipulation. Ensuite seulement nous pourrons dmarrer MySQL-max et Zope :
[root@localhost /]# /etc/init.d/zope stop Arrt de zope : . daemon process stopped
1 Le code source de ces optimisations est tlchargeable l'URL http://www.nexedi.org/static/Mandrake/10.1/SRPMS/zope2.7.2rc1 1nxd.src.rpm 2 http://www.nexedi.org/static/Mandrake/10.1/RPMS ou http://www.nexedi.org/static/Mandrake/10.0/RPMS page 6/64
Tut o r i e l N e x e d i ERP5
[root@localhost /]# zopectl program: /usr/bin/runzope daemon manager not running zopectl> help adduser adduser <name> <password> -- add a Zope management user zopectl> adduser admin admin [root@localhost /]# /etc/init.d/mysql-max start Lancement du serveur MySQL [root@localhost /]# zopectl program: /usr/bin/runzope daemon manager not running zopectl> start daemon process started, pid=7944 [ OK ]
Il nous reste plus qu' vrifier le fonctionnement de Zope en accdant la ZMI, l'interface web de gestion de Zope, o l'on s'identifiera avec le mot de passe de l'utilisateur admin que l'on vient d'ajouter :
http://localhost:9080/manage
Illustration 1: L'accs la Z MI ncessite une authentification
page 7/64
Tut o r i e l N e x e d i ERP5
Illustration 2: ZMI, l'interface web de gestion de Zope
Le serveur Zope tant dsormais oprationnel et accessible, nous allons crer une instance d'ERP5 en slectionnant le type ERP5 Site dans la liste droulante en haut droite :
Une page de proprits est affiche dans la ZMI et nous la remplirons comme sur la capture d'cran :
page 8/64
Tut o r i e l N e x e d i ERP5
La validation de ce formulaire conduit cet cran en cas de succs :
Mais il est frquent de voir apparatre l'erreur suivante ce moment prcis :
Site Error An error was encountered while publishing this resource. Error Type: DatabaseError Error Value: z0_catalog_object is not connected to a database
Cette erreur signifie simplement que le serveur MySQL-max n'est pas dmarr. Un redmarrage de ce dernier suffit pour que tout rentre dans l'ordre. On peut maintenant se rendre sur la page de garde d'ERP5 via l'url :
page 9/64
Tut o r i e l N e x e d i ERP5
http://localhost:9080/erp5/
ERP5 est maintenant oprationnel sur votre machine et se suffit lui mme pour commencer l'initiation. Je conseillerais cependant aux plus courageux de mettre jour ERP5 depuis le CVS d'ERP53, pour pouvoir profiter des dernires volutions et corrections de bugs. Mise en garde : bien que ERP5 soit maintenant install et utilisable sur votre machine ou sur votre serveur, il n'est pas conseill de l'utiliser "tel quel" en production. Une configuration fine (cluster, systme d'activit, etc.) est en effet ncessaire pour obtenir des performances leves et une rflexion sur la politique de scurit des donnes est indispensable pour protger des donnes vitales pour l'entreprise.
2.3. Etendre ERP5 avec les Business Templates
Les Business Templates sont ERP5 ce que les systmes de paquetages (rpm, apt) sont aux distributions Linux. Les RPM ont pour but de simplifier l'installation de logiciels au sein d'un systme. Les Business Templates ont le mme rle en prenant en charge l'installation propre et automatise de l'ensemble d'un module d'ERP5. D'un point de vue de l'utilisateur, installer un Business Template c'est ajouter une fonctionnalit majeure l'ERP, en largissant ses capacits de gestion d'entreprise. Il existe actuellement huit Business Templates, chacun tant ddi un aspect de la gestion d'entreprise:
Trade : gestion commerciale (achats et ventes, commandes, bons de livraison, facturations, gestion des stocks) PDM (Product Data Management) : gestion des donnes produit (dfinition des produits, variantes, catgorisation, nomenclatures, gamme opratoire, catalogue multimdia) MRP (Manufacturing Ressources Planning) : organisation et gestion de production (ordres de fabrication, planning de production) CRM (Customer Relationship Management) : gestion des relations clientles (base de donnes des organisation et des personnes, opportunits commerciales) Accounting : comptabilit (livre de comptes, rapports financiers)
3 http://cvs.erp5.org voir galement le script update_cvs.sh dans /var/lib/zope/ qui permet d'automatiser les mises jour page 10/64
Tut o r i e l N e x e d i ERP5
HR (Human Resources) : gestion des ressources humaines (livre de paie, gestion de carrires) eCommerce : commerce lectronique (magasin de vente en ligne, affiliations) CMS (Content Management System) : gestion de contenu web (via NuxeoCPS4)
Certains de ces Business Template ont atteint un premier stade de maturit (ex. Accounting permet aujourd'hui de clturer un exercice comptable). Les autres sont encore en cours d'intgration. En effet, bien que ERP5 soit utilis aujourd'hui en production sur des sites importants avec une couverture fonctionnelle complte (ex. nomenclatures, gestion de production, calcul des besoins, gestion de stock, facturation, etc.), les clients d'ERP5 ne souhaitent pas pour la plupart financer le surcot de l'intgration sous forme de Business Template gnrique du travail spcifique qui a t effectu pour adapter le framework ERP5 leurs propres besoins. Le travail d'intgration des Business Template est donc effectu par Nexedi de faon bnvole. Voil pourquoi toutes les fonctionnalits du framework ERP5 ne sont pas encore couvertes par les Business Template disponibles en tlchargement. L'un des premier module conu qui utilise le systme de Business Templates est le module de gestion de feuille de paie. Ce module permet de grer un livre de paie et de crer des bulletins de salaire. C'est ce module qui nous servira de support tout au long de l'article. Nous allons maintenant dtailler le processus d'installation de ce Business Template. Ce processus ncessite de disposer un compte avec les droits Manager. Tout convient d'accder avec votre navigateur au module portal_templates en tapant une URL telle que http://localhost/erp5/portal_templates ou http://localhost:9480/erp5/portal_templates en fonction de votre configuration. Vous pourrez alors accder la liste des Business Template : d'abord, il
4 http://www.cpsproject.org/ page 11/64
Tut o r i e l N e x e d i ERP5
A titre de comparaison, un systme ERP5 plus complet comporte de nombreux Business Templates :
Notre objectif est donc de passer d'une liste pratiquement vide de Business Template une liste plus complte. Pour atteindre cet objectif, il suffit de cliquer sur le bouton "Import/Export" dans la deuxime barre de boutons partir du haut de la page ERP5. Ce bouton ressemble ceci :
Aprs avoir cliqu dessus, vous arrivez sur le dialogue d'import de Business Template :
page 12/64
Tut o r i e l N e x e d i ERP5
Utilisez alors le menu "Exchange Select" pour passer du dialogue "Import Business Template" "Download Business Template" :
Il vous reste alors saisir dans les deux champs, d'une part un identifiant du Business Template (ex. erp5_accounting) puis l'URL de ce Business Template (ex.
http://cvs.erp5.org/cgibin/viewcvs.cgi/*checkout*/erp5_bt5/erp5_trade.bt5?rev=HEAD&content-type=text/plain)
et cliquer sur "Download Business Template". Le tlchargement sera effectu automatiquement ( condition d'avoir accs Internet) et, en cas de succs, vous verrez apparatre un message "Business Template Downloaded Successfully". Vous pouvez alors cliquer sur le Business Template que vous venez de tlcharger. Vous verrez alors un formulaire de dfinition :
page 13/64
Tut o r i e l N e x e d i ERP5
Pour procder l'installation, allez dans le menu "Action" et appelez "Install Business Template"
Vous venez d'installer le Business Template de comptabilit d'ERP5. Ce module est indispensable pour le Business Template de paye. Continuons maintenant avec la paye. Le principe est le mme, il faut juste importer un Business Template diffrent en lui donnant comme id erp5_payroll et comme URL de tlchargement http://cvs.erp5.org/cgibin/viewcvs.cgi/*checkout*/erp5_payroll/erp5_trade.bt5?rev=HEAD&contenttype=text/plain
Voici un exemple de feuille de paie gnr par ce Business Template :
page 14/64
Tut o r i e l N e x e d i ERP5
Illustration 3: Une feuille de paie gnre par ERP5
Pour crer cette feuille de paie, nous nous sommes bass sur un document disponible sur le site communautaire erp5.org (http://www.erp5.org/workspaces/project/erp5_payroll/erp5_pay_sheet_for_n). Ce document en anglais destin aux dbutants explique la procdure suivre pour arriver ses fins. Il vous aidera dans l'utilisation du module de feuille de paie. Maintenant que nous connaissons le principe des Business Template d'un point de vue utilisateur, nous pouvons entamer le coeur de cet article : la cration d'un Business Template.
page 15/64
Tut o r i e l N e x e d i ERP5
3. Crons notre propre Business Template !
L'objectif de la seconde partie de cet article est d'offrir une vue d'ensemble de la plate-forme de dveloppement ERP5 des dveloppeurs. Dans ce but nous allons reconstruire dans les grandes lignes le module de feuilles de paie. Cela nous donnera l'occasion de dmontrer la convivialit et la puissance d'ERP5 pour la cration rapide de modules fonctionnels, mais galement d'approcher les technologies et les concepts qui sont la base d'ERP5.
3.1. Conception de la structure de donnes
Les objets ERP5 drivent tous de 5 classes fondamentales :
Ce modle thorique d'EPR5 dj fait l'objet d'une publication scientifique5 qu'il sera intressant de consulter pour comprendre les motivations qui se cachent derrire chacun des concepts cl d'ERP5. Nous retiendrons de ce document la description des 5 classes fondamentales :
Ressource
Le type Resource dcrit une ressource abstraite d'un processus mtier comme les comptences d'une personne, une devise, une matire premire, ou un produit.
Node
Les objets de type Node peuvent envoyer ou recevoir des ressources. Un noeud peut reprsenter une entit physique (telle une machine de production, qui reoit des matires premires, les transforment et les
5 http://www.computer.org/itpro/cover_stories/smets.htm page 16/64
Tut o r i e l N e x e d i ERP5
envoient) ou une entit abstraite (tel un compte en banque qui reoit des sommes d'argents). Les stocks sont reprsents par des noeuds. Des mtanoeud (MetaNode) sont des noeuds qui contiennent d'autres noeuds. C'est le cas par exemple d'une entreprise.
Movement
Cette classe dcrit le mouvement de ressources entre deux noeuds un moment donn, pour un temps donn. Par exemple un mouvement peut dcrire l'envoi de matire premires d'un stock vers un atelier; un mouvement peut aussi reprsenter l'envoi d'argent depuis un compte vers un autre.
Path
Un chemin dcrit le moyen pour un noeud d'accder une ressource dont il a besoin. Des prix et des profils commerciaux peuvent tre attachs un chemin pour dfinir par exemple le prix par dfaut d'une ressource fournit un fabricant. Un chemin peut aussi dfinir la manire dont un atelier obtient ses ressources du stock. Un chemin possde des attributs de date de dbut et de fin, et peut reprsenter l'affectation d'un individu une mission temporaire.
Item
Un item est une instance physique d'une quantit de ressource. Un mouvement peut se dtailler en une srie de mouvements traable via des items. Les Items dfinissent aussi la manire dont les ressources sont livres (selon un colis entier ou en listant les numros de srie des items dans chaque conteneur).
En analysant une feuille de paie franaise classique, nous avons choisis de crer 4 types d'objets :
PaySheetTransaction PaySheetTransactionLine PaySheetLine PaySheetCell
Voici un diagramme de classes qui donne la hirarchie et les hritages permettant de relier les classes de bases d'ERP5 avec nos 4 nouveaux types d'objets :
page 17/64
Tut o r i e l N e x e d i ERP5
Folder
XMLObject
Movement
Delivery
DeliveryLine
DeliveryCell
Accounting Transaction
Invoice
Accounting Transaction Line
InvoiceLine
InvoiceCell
PaySheet Transaction
1
0..* Transaction
Line
PaySheet
0..*
PaySheet Line
1
0..*
PaySheet Cell
La structure de donnes des feuilles de paie est calque sur le modle de facturation (Invoice). Ce dernier est dcrit par 3 classes : Invoice, InvoiceLine et InvoiceCell. Ces trois classes permettent de dtailler une facture (Invoice) en lignes de facturation via InvoiceLine (une ligne de facture par produit factur), elles mmes dcomposables selon des variantes du mme produit factur. Ainsi les InvoiceCell permettent par exemple de dtailler la facturation d'une uantit de quatre produits A en trois produits A de couleur bleue et un produit A de couleur verte. Comme nous le montre le diagramme, les factures spcialisent le systme de reprsentation des livraison (Delivery) qui implmente l'origine la structure Line/Cell. Les cellules (Cell) sont la partie visible du concept de variantage qu'offre ERP5. Ce concept permet de reprsenter des variantes d'une mme ressource comme la couleur, la taille ou la vitesse. Cela permet de dfinir plusieurs configurations d'un mme produit. L'avantage de ce systme rside dans la possibilit de configurer trs profondment l'ERP5 tout en gardant les bnfices d'une gestion gnrique des donnes selon une structure standardise. Nous dtaillerons le concept de variantage un peu plus loin dans cette article. Nous allons maintenant dtailler nos diffrentes classes.
PaySheetTransaction
La feuille de paie en elle mme est reprsente par un objet de type
PaySheetTransaction.
page 18/64
Tut o r i e l N e x e d i ERP5
Cette classe drive de la classe de base Folder via Invoice. Nous avons choisi cet hritage car les objets de type PaySheetTransaction vont nous servir regrouper au mme endroit les objets relatifs une feuille de paie. C'est pour cela que PaySheetTransaction n'a pas comme classe anctre l'une des 5 classes de base d'ERP5. Folder est en quelque sorte une "classe utilitaire" qui nous permet de rduire l'entropie du systme. Et comme les PaySheetTransaction sont des Folder avec des comportements particuliers dont certains sont les mmes que pour une facture (Invoice), nous avons d crer une nouvelle classe. Ces comportements particuliers permettront de prendre en compte la notion d'employeur et de salari ainsi que d'autres donnes propres la feuille de paie (date de paiement, salaire brut, ).
PaySheetLine
Comme l'indique le diagramme, chaque PaySheetTransaction peut contenir des PaySheetLine qui sont la reprsentation des diffrentes cotisations soustraite sur le salaire brut. Pour chaque cotisation il y a une et une seule PaySheetLine.
PaySheetCell
Les PaySheetLine contiennent les PaySheetCell, qui permettent de reprsenter et dtailler les montants de la PaySheetLine. Le systme de variantage permettra de distinguer les parts employeur et employe d'une cotisation sociale donne et de conserver une trace de la mthode de calcul des montants. Car pour une cotisation donne, le montant d'une part (salariale ou patronale) peut tre le fruit d'un savant calcul faisant intervenir un ou plusieurs taux, associ chacun une assiette (salaire brut, salaire plafonn, salaire tranche A/B/C, ). Le calcul des feuilles de paie n'est pas vident, d'autant plus que la lgislation change tout les jours Le variantage offre un avantage de taille dans ce cas car il permet de parer toutes les complications induites par la lgislation de chaque pays.
PaySheetTransactionLine
Les PaySheetTransactionLine sont la reprsentation comptable de la feuille de paie. Nous avons choisi de distinguer les PaySheetLine et les PaySheetTransactionLine car la reprsentation de la feuille de paie selon la logique comptable agrge certains montants et rend impossible un reporting fin sur la paye. Nous avons donc au sein d'une PaySheetTransaction deux ensembles :
Les donnes du couple PaySheetLine/PaySheetCell : un jeu de donnes de
page 19/64
Tut o r i e l N e x e d i ERP5
base qui nous permet d'afficher les dtails de la feuille de paie et de manipuler les chiffres dans tous les sens.
Les donnes de type PaySheetTransactionLine, qui reprsentent les lignes comptable de la feuille de paie
Maintenant que nous avons un modle de donnes cohrent, nous allons l'implmenter dans ERP5.
3.2. Le variantage par catgories
Les objets de type Category sont utiliss dans ERP5 pour la classification. Par exemple, un document peut possder un attribut couleur. Au lieu de laisser l'utilisateur entrer une valeur libre, via un champ texte, pour l'attribut couleur, on prfrera attribuer l'objet une catgorie. On fabriquera donc via la ZMI les catgories couleur/bleu, couleur/vert et couleur/rouge :
Les catgories peuvent contenir des sous-catgories. Par exemple pour dcrire les rgions gographiques :
region/europe region/europe/west/ region/europe/west/france region/europe/west/germany region/europe/south/spain region/americas region/americas/north region/americas/north/us
page 20/64
Tut o r i e l N e x e d i ERP5
region/americas/south region/asia
Dans cet exemple la catgorie de base est region. Les catgories ont d'autres avantages comme le catalogage automatique. Ce mcanisme rend possible l'utilisation de requtes SQL pour slectionner les objets de la ZODB selon la valeur de la catgorie (voir plus bas paragraphe : catalogage). Il est possible de crer des classifications "virtuelles" base sur des documents existant ou sur des catgories. Par exemple, si un document est accessible au chemin organisation/nexedi, et qu'il existe une catgorie de base client, l'outil portal_categories autorise la cration de la catgorie virtuelle client/organisation/nexedi. Cela permet de reprsenter un lien relationnel selon le schma : le client de tel objet est l'organisation Nexedi . Le concept de la virtualisation des catgories vite la duplication des informations en offrant des mcanismes quivalent une base de donne relationnelle.
3.3. Intgrons notre structure de donnes dans ERP5
Nous allons ajouter dans ERP5 toutes les classes d'objets que nous avons dfinies dans le paragraphe prcdent. ERP5 possde des mcanismes propres pour dfinir de nouvelles classes d'objets, ce qui lui permet de prendre en charge la cration dynamique et automatise de mthodes. Le travail de cration de nouvelles classes se limite donc les dcrire, ERP5 se chargera du reste, comme la cration dynamique des "setter" et "getter". Les classes d'objets se dfinissent via un script python dans le dossier Document de l'instance Zope/ERP5. Nous allons crer une nouvelle classe PaySheetTransaction, et pour viter de ressaisir tout le code, faire une copie du fichier Invoice.py que nous diterons :
[root@localhost /]# cd /usr/lib/zope/lib/python/Products/ERP5/Document/ [root@localhost Document]# cp Invoice.py / var/lib/zope/Document/PaySheetTransaction.py [root@localhost Document]# vi /var/lib/zope/Document/PaySheetTransaction.py () [root@localhost Document]# chown zope:zope / var/lib/zope/Document/PaySheetTransaction.py [root@localhost Document]# chmod 755 / var/lib/zope/Document/PaySheetTransaction.py
Voici ce quoi doit ressembler le fichier PaySheetTransaction.py aprs dition :
page 21/64
Tut o r i e l N e x e d i ERP5
from AccessControl import ClassSecurityInfo from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface from Products.ERP5.Document.Invoice import Invoice class PaySheetTransaction(Invoice): """ A paysheet will store data about the salary of an employee """ meta_type = 'ERP5 Pay Sheet Transaction' portal_type = 'Pay Sheet Transaction' add_permission = Permissions.AddPortalContent isPortalContent = 1 isRADContent = 1 # Declarative security security = ClassSecurityInfo() security.declareObjectProtected(Permissions.View) # Default Properties property_sheets = ( PropertySheet.Base , PropertySheet.SimpleItem , PropertySheet.CategoryCore , PropertySheet.Task , PropertySheet.Arrow , PropertySheet.Delivery , PropertySheet.Movement , PropertySheet.Amount , PropertySheet.XMLObject , PropertySheet.PaySheetTransaction ) # Declarative Interface __implements__ = ( )
3.4. Web Dveloppement rapide avec portal_classes
Il est possible de raliser l'ensemble des oprations de cration de classes ou d'dition du code via l'interface Web d'ERP5 grce l'outil portal_classes :
page 22/64
Tut o r i e l N e x e d i ERP5
L'dition de code python d'une classe ERP5 permet galement de recharger chaud le seul code modifi, sans redmarrer Zope et de gagner en productivit.
L'outil portal_classes est trs utile en phase de prototypage ou de dveloppement rapide. Il facilite galement l'apprentissage d'ERP5. Il est cependant dconseill de l'activer sur un systme en production car il comporte des risques levs en matire de scurit. Aussi est-il dsactiv par dfaut dans le LiveCD ERP5 ou dans les paquetages ERP5 pour Mandrakelinux. Pour l'activer, il est donc ncessaire de crer un fichier vide ALLOW_CLASS_TOOL dans le rpertoir du produit ERP5Type.
page 23/64
Tut o r i e l N e x e d i ERP5
3.5. Structure d'une classe Document dans ERP5
Les fichiers de type Document ont gnralement la mme allure, et les valeurs propres notre nouvelle classe se devinent facilement. Toujours dans le dossier de l'instance Zope/ERP5, PropertySheet sert contenir des scripts python similaires ceux que l'on trouve dans le dossier PropertySheet du produit ERP5. Ces scripts aux noms vocateurs permettent de dfinir des attributs de classes et, par extension, le schma de donnes d'ERP5. Les classes y font souvent rfrence grce la liste property_sheets, comme on peut le voir dans le code python prcdent. Ainsi pour que chaque feuille de paye puisse stocker le salaire brut ("gross salary" en anglais), nous avons fait rfrence la property sheet PaySheetTransaction qui contiendra la dfinition de l'attribut gross_salary de type flottant. Il nous faut maintenant la crer :
[root@localhost [root@localhost [root@localhost () [root@localhost [root@localhost /]# cd /var/lib/zope/PropertySheet/ PropertySheet]# touch PaySheetTransaction.py PropertySheet]# vi PaySheetTransaction.py PropertySheet]# chown zope:zope PaySheetTransaction.py PropertySheet]# chmod 755 PaySheetTransaction.py
Voici le contenu de la property sheet PaySheetTransaction.py :
class PaySheetTransaction: """ Properties for PaySheet Transaction objects """ _properties = ( { 'id' , 'description' paysheet' , 'type' , 'mode' }, ) _categories = ( , , , ) : 'gross_salary' : 'This variable contain the gross salary of the : 'float' : 'w'
'source' 'destination' 'source_section' 'destination_section'
La syntaxe est assez intuitive car tous les attributs se dclarent par une liste de dictionnaires python dans la variable _properties. Il convient juste de faire attention aux listes immuables (tuple) un lement en python et ne pas oublier la virgule avant la parenthse de fin.
page 24/64
Tut o r i e l N e x e d i ERP5
[kevin@localhost Products]$ python Python 2.3.3 (#2, Feb 17 2004, 11:45:40) [GCC 3.3.2 (Mandrake Linux 10.0 3.3.2-6mdk)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> (5) 5 >>> (5,) (5,) >>> (5,10) (5, 10) >>>
Ainsi (5) est interprt comme l'entier 5, et (5,) comme une liste immuable contenant un seul lment entier gal 5. La liste _categories contient la liste des catgories virtuelles. Nous utiliserons celles-ci pour crer un lien entre la feuille de paie, l'employeur et le salari. La relation source_section fera rfrence l'employeur (qui est l'organisation ou l'entreprise qui met la feuille de paie) et la relation destination_section fera rfrence au salari (la personne qui se destine la feuille de paie). Si plus tard nous avons besoin de dfinir des attributs plus complexes, nous nous inspirerons des PropertySheets pr-existante dans le produit ERP5. Cette mthode est valable pour tous les points abord dans cet article : puisque le code source est ouvert, il ne faut pas se priver de rutiliser ou de s'inspirer de choses existantes pour construire petit petit des choses nouvelles. C'est mme un obligation pour contribuer au code d'ERP5 : deux proprits similaires doivent, par principe, avoir le mme nom dans ERP5. Maintenant que notre nouvelle classe est construite, il est ncessaire soit de recharger son code (avec portal_classes sur la classe de PropertySheet puis sur la classe de Document) soit de redmarrer le serveur Zope pour qu'il puisse les prendre en compte. Si tout ce passe bien le serveur sera disponible et vous pourrez accder la ZMI :
[root@localhost kevin]# zopectl program: /usr/bin/runzope program running; pid=4450 zopectl> restart . daemon process restarted, pid=4773 zopectl> logtail -----2004-05-12T18:50:03 INFO(0) Z2 Caught signal SIGTERM -----2004-05-12T18:50:03 INFO(0) Z2 Shutting down fast -----2004-05-12T18:50:03 INFO(0) ZServer closing HTTP to new connections -----2004-05-12T18:50:03 INFO(0) ZServer closing FTP to new connections -----page 25/64
Tut o r i e l N e x e d i ERP5
2004-05-12T18:50:03 INFO(0) Zope Shutting down with exit code 0 () -----2004-05-12T18:50:42 INFO(0) Zope Ready to handle requests zopectl>
Il est possible qu'au moment du redmarrage, Zope s'arrte et refuse obstinment de dmarrer. Il est aussi possible d'observer un comportement trange de Zope : l'arrt et le dmarrage en boucle du serveur par priodes de 10 secondes. Les causes de ce blocage sont lies dans la majorit des ca de mauvaises permissions sur les scripts ou une mauvaise attribution de la proprit des fichiers que vous venez de crer. Une srie de chmod et chown rglera ce problme. Si malgr ces corrections le problme persiste, il zopectl intgre une commande debug, qui lorsqu'on l'appelle va arrter le serveur et le dmarrer en vous affichant le log de dmarrage et un rapport d'excution (traceback) en cas d'erreur. Par exemple :
[root@localhost kevin]# zopectl program: /usr/bin/runzope daemon manager not running zopectl> debug Starting debugger (the name "app" is bound to the top-level Zope object) () Traceback (most recent call last): File "<string>", line 1, in ? File "/usr/lib/python2.3/site-packages/PIL/__init__.py", line 50, in app File "/usr/lib/python2.3/site-packages/PIL/__init__.py", line 46, in startup File "/usr/lib/zope/./build/build-base/python-2.3/buildlib/Zope/App/startup.py", line 45, in startup File "/usr/lib/zope/./build/build-base/python-2.3/buildlib/OFS/Application.py", line 631, in import_products File "/usr/lib/zope/./build/build-base/python-2.3/buildlib/OFS/Application.py", line 654, in import_product File "/usr/lib/zope/lib/python/Products/ERP5/__init__.py", line 50, in ? from Tool import Category, CategoryTool, SimulationTool, RuleTool, IdTool, TemplateTool, TestTool File "/usr/lib/zope/lib/python/Products/ERP5/Tool/Category.py", line 35, in ? from Products.ERP5.Document.MetaNode import MetaNode File "/usr/lib/zope/lib/python/Products/ERP5/Document/__init__.py", line 3145, in ? import PaySheetTransaction as ERP5PaySheetTransaction File "/usr/lib/zope/lib/python/Products/ERP5/Document/PaySheetTransaction.py", line 62
page 26/64
Tut o r i e l N e x e d i ERP5
__implements__ = ( ) ^ SyntaxError: invalid syntax >>>
Le traceback nous apprend qu'il y a une erreur invalid syntax dans le fichier / usr/lib/zope/lib/python/Products/ERP5/Document/PaySheetTransaction.py, ligne 62. En ditant le dit fichier on s'aperoit en fait que le malheureux dveloppeur a oubli de fermer la liste property_sheets avec une parenthse. Il nous suffira dans ce cas que d'une petite correction pour pouvoir relancer le serveur zope Attention : pour utiliser la commande debug il ne faut pas oublier de mettre on l'option debug-mode du fichier /etc/zope.conf. Il n'est d'ailleurs pas surprenant de devoir utiliser debug 30 fois par jour lorsque l'on dbute et que l'on ne matrise pas la syntaxe de python, ou lorsque l'on travaille sur le CVS d'un projet ERP5 en quipe et que des conflits surgissent. Selon le mme principe nous avons construit les nouveaux types
PaySheetTransactionLine, PaySheetLine et PaySheetCell. Par curiosit on pourra
aller consulter les classes pythons qui les dfinissent :
[root@localhost [root@localhost [root@localhost [root@localhost /]# cd /usr/lib/zope/lib/python/Products/ERP5/Document/ Document]# vi PaySheetTransactionLine.py Document]# vi PaySheetLine.py Document]# vi PaySheetCell.py
Le lecteur attentif aura sans doute remarqu ici que le code du module de paye est parfois situ dans le dossier /usr/lib/zope/lib/python/Products/ERP5/Document/ et parfois dans le dossier /var/lib/zope/Document. Une explication s'impose. Le dossier /var/lib/zope/Document est conu pour le dveloppement rapide de code d'extension au framework ERP5. C'est donc bien dans ce dossier qu'il faut commencer travailler lorsque l'on conoit un nouveau jeu de classes pour un client ou pour une future extension d'ERP5. Si ce jeu de classes semble suffisamment gnrique et susceptible de correspondre une fonction universelle d'un ERP, il est conseill de l'intgrer au projet ERP5 afin de le partager avec l'ensemble de la communaut. C'est bien le cas de la paye. En revanche, si ce jeu de classes est li un mtier ou aux besoins spcifiques d'une entreprise, il n'y a aucune raison de l'intgrer au coeur d'ERP5. La paye faisant dsormais partie du coeur d'ERP5, il nous arrivera souvent de mentionner des fichiers situs dans le dossier Document du produit ERP5. Cependant, pour les besoins du tutoriel, nous crerons tous les nouvelles classes dans les dossiers de l'instance Zope/ERP5, c'est--dire gnralement /var/lib/zope.
3.6. Crer un Module dans EPR5
Lors de l'introduction de ce chapitre nous avons fait l'amalgame entre les
page 27/64
Tut o r i e l N e x e d i ERP5
Business Templates et les modules de l'ERP. Nous allons maintenant faire la diffrence et dcrire plus prcisment le rle d'un module, au sens d'ERP5, puis en crer un. Un module est simplement un lieu dans l'interface utilisateur d'ERP5 ou se rassemblent les fonctionnalits propres un aspect de la gestion d'entreprise. Le Business Template contient tous les scripts et objets qui permettent de faire fonctionner le module. D'o l'amalgame. La cration rapide d'un nouveau module peut tre effectue en allant l'URL :
http://localhost:9480/erp5/ERP5Site_viewCreateModuleDialog
o apparat le dialogue suivant :
Ce dialogue comporte 6 paramtres :
Module Id : l'id du dossier (Folder) cr la racine du site ERP5 et qui contiendra l'ensemble des feuilles de paye. Module Portal Type : le nom du type documentaire qui sera cr pour contenir toutes les feuilles de paye Module Title : le titre qui apparatra dans le menu modules pour le module de paye Object Portal Type : le nom du type documentaire qui sera cr pour dfinir les feuilles de paye Object Title : le titre qui apparatra par dfaut pour chaque feuille de paye Portal Skins Folder : le dossier dans lequel seront crs les formulaires par dfaut
En cliquant sur "Create Module", tous les types documentaires sont
page 28/64
Tut o r i e l N e x e d i ERP5
automatiquement crs et les menus mis jour. Un module de paye "vide" vient d'tre cr. Il s'agit dsormais de le paramtrer.
3.7. Intgrer les classes, donnes, menus et prsentation : l'outil portal_types
ERP5 est conu autour de l'architecture Zope/CMF. L'une des caractristiques du CMF est le concept d'outil (tool en anglais) plac la racine d'un portail et conu pour fournir divers services : traduction de formats de documents, gestion des menus associs un document, internationalisation, synchronisation, etc. L'outil portal_types permet de crer des types gnriques de document sur la base de nos classes dfinies dans la partie prcdente et de leur associer des menus ainsi que des lments de prsentation. Nous ferons la distinction par la suite entre portal_types (l'outil) et les portal types (les types de document dfinis par l'outil portal_types). Le contenu de l'outil portal_types correspond aux modules et aux types documentaires disponibles dans l'instance ERP5.
Pour rsumer on peut dire que tous nos portal types du genre PaySheet* sont des images dans Zope de nos classes dfinies par nos scripts python. La ralit est plus subtile car ils peut y avoir deux portal types diffrents qui se basent sur la mme classe, car leur rle premier est de crer des types
page 29/64
Tut o r i e l N e x e d i ERP5
documentaires. Par exemple depuis une mme classe DocumentEcrit nous pouvons crer deux portal types diffrents : Article et CommuniquDePresse. Les deux se dcrivent par la mme structure de donnes et les mmes proprits. L'intrt de crer deux types de documents est que nous pouvons appliquer chaque type un workflow diffrent ou une mise en page adapte.
3.8. L'interface utilisateur avec ERP5Form
Nous allons exploiter ici les capacits de RAD (environnement de dveloppement rapide) d'ERP5 via le produit ERP5Form, afin de dfinir l'interface utilisateur de notre module. ERP5Form est le gnrateur de formulaires d'ERP5. Il est driv de Formulator, un produit Zope cr par Infrae. Lorsque nous allons dans le module de paye, nous pouvons ajouter des PaySheetTransaction :
Cependant, notre action se termine sur une erreur :
page 30/64
Tut o r i e l N e x e d i ERP5
Or, la mthode de cration d'une nouvelle feuille de paie bien fonctionn comme l'atteste la prsence dans la ZODB d'une nouvelle instance du portal type Pay Sheet Transaction qui t cre dans le dossier paysheet du module :
Il ne s'agit donc que d'un problme de prsentation. Pour le rsoudre, nous devons ajouter une interface utilisateur la feuille de paie pour que l'action de cration n'aboutisse pas sur une erreur lorsque elle tente d'afficher l'objet cr. Nous allons donc crer un nouveau formulaire. Comme tous les formulaires et les autres objets de prsentation, ils sont dfinis dans des sous-dossiers de l'outil portal_skins. Allons par exemple dans le dossier /erp5/portal_skins/local_erp5.
page 31/64
Tut o r i e l N e x e d i ERP5
Un formulaire se cre comme n'importe quel objet zope via la ZMI : il suffit de choisir le type "ERP5 Form". Appelons notre formulaire PaySheetTransaction_view :
Commenons pour l'diter par lui ajouter un champ de type float pour reprsenter le salaire brut :
Pour indiquer implicitement que ce champ correspond l'attribut gross_salary de notre objet, il suffit de le nommer my_gross_salary :
page 32/64
Tut o r i e l N e x e d i ERP5
L'utilisation du prfixe my_ est une des rgles de nommage propre ERP5. Si un champ de formulaire est nomm my_quelque_chose, il affichera par dfaut une valeur obtenue en appelant la mthode getQuelqueChose sur le document auquel il est appliqu. En cas de validation du formulaire, la mthode setQuelqueChose sera appele sur le document auquel le formulaire a t appliqu pour mettre jour la valeur de la proprit quelque_chose. Pour tre complet, il faut galement configurer le formulaire pour que le salaire brut puisse tre modifi en dfinissant la proprit Form action comme sur la capture d'cran :
L'action "Base_edit" est appele lorsque l'on valide le formulaire et prend en compte les donnes saisies par l'utilisateur pour mettre jour le document auquel le formulaire est appliqu. Pour tester que notre formulaire fonctionne, appelons directement depuis l'url :
page 33/64
Tut o r i e l N e x e d i ERP5
http://localhost:9080/erp5/paysheet/1/PaySheetTransaction_view
Afin que ce formulaire soit utilis par dfaut pout afficher les feuilles de paie, retournons dans l'outil portal_types. Allons dans l'onglet action du portal type correspondant la feuille de paie. On peut alors dfinir une nouvelle action :
Le choix de la catgorie "object_view" Le choix de l'id "view" correspond nous ajoutons une nouvelle feuille de module de paye, le formulaire va information de salaire brut :
correspond la notion d'onglet dans ERP5. l'affichage par dfaut. Dsormais, lorsque paie depuis le menu droulant Actions du tre automatiquement affich avec une
Notons ici que les deux URL :
http://localhost:9080/erp5/paysheet/2/view
et
http://localhost:9080/erp5/paysheet/2/PaySheetTransaction_view
page 34/64
Tut o r i e l N e x e d i ERP5
donnent le mme rsultat en raison de l'association de PaySheetTransaction_view l'id view dans les actions du portal_type. Il peut tre intressant ce stade de tester quelques URL typiques d'ERP5 afin de bien comprendre la notion d'accesseur. Par exemple, le fait d'avoir dfini dans la PropertySheet de feuille de paye une proprit "gross_salary" a entrain la gnration automatique par ERP5 d'une mthode "getGrossSalary". Cette mthode peut tre teste directement en appelant une URL adquate sur la feuille de paye :
http://localhost:9080/erp5/paysheet/2/getGrossSalary
Cette URL affiche dans le navigateur la valeur de forme de chane de caractre.
gross_salary convertie sous
En utilisant les proprits du formulaire et des champs qui le constituent, on peu obtenir rapidement un formulaire plus dvelopp et plus utile. On commence par ajouter des champs pour chaque proprit que l'on souhaite grer avec le formulaire :
Illustration 4: De nouveaux champs pour chaque attribut de l'objet
L'onglet "Order" permet de regrouper les champs et dfinir leur prsentation :
page 35/64
Tut o r i e l N e x e d i ERP5
Illustration 5: Utilisation de groupes pour la reprsentation du formulaire
Le style ERP5 par dfaut utilise 4 groupes : left (ou Default), right, center et bottom. Nous n'avons pour l'instant utilis que les deux premiers groupes qui se traduisent par un affichage sur 2 colonnes :
Illustration 6: Le formulaire vu par l'utilisateur
Ajoutons maintenant deux champs qui permettent d'associer la feuille de paie l'employeur et au salari. Avant cela il est indispensable d'installer le Business Template CRM, qui permet de grer les personnes et les organisations, en suivant la mthode explique en premire partie. Une fois install, nous pouvons nous occuper des relations.
page 36/64
Tut o r i e l N e x e d i ERP5
Les champs ajouter sont de type RelationStringField :
Nous ajouterons deux champs de ce type, my_destination_section_title permettra de saisir le salari qui la feuille de paie est destine et my_source_section_title l'employeur qui met la feuille de paie :
page 37/64
Tut o r i e l N e x e d i ERP5
Il faut ensuite modifier les proprits des deux widgets pour qu'ils puissent fonctionner :
Comme on peut le deviner avec les captures prcdentes, Base Category permet d'indiquer la catgorie de base sur laquelle la relation s'appuie. Souvenez-vous galement que cette catgorie t explicitement dclare dans la property sheet adquate, justement pour pouvoir tre utilise cet endroit. La relation d'employeur est maintenant dfinissable par une catgorie virtuelle de la forme source_section/organisation/nexedi. On peut vrifier la bonne intgration des donnes en appelant directement le getter de l'attribut sur l'objet, et ce depuis l'url :
http://localhost:9080/erp5/paysheet/2/getSourceSection
Pour comprendre comment ces informations sont gres par ERP5, il peut tre utile d'appeler la mthode Base_viewDict qui permet d'inspecter le contenu des objets enregistrs dans la ZODB :
http://localhost:9080/erp5/paysheet/2/Base_viewDict
La proprit Portal Type de ce type de widget permet quand elle de spcifier les types d'objets qui seront accepts comme relation par le champ. On retrouvera cette proprit dans diffrents widgets du produit Formulator. Ensuite, la valeur donner aux autres proprits de ce type de champ sont assez intuitives.
page 38/64
Tut o r i e l N e x e d i ERP5
Nous nous retrouvons ainsi avec un formulaire qui se rapproche de sa forme finale :
De
existe une action view relie au formulaire PaySheetTransaction_view dfinie dans le portal type Pay Sheet Transaction, il existe une action view sur le portal type du module qui par dfaut est Folder_list :
mme
qu'il
Nous allons crer notre propre formulaire PaySheetModule_view qui va nous servir l'affichage par dfaut du contenu du module. Pour cela il nous faut changer les actions du module et crer un nouveau formulaire :
page 39/64
Tut o r i e l N e x e d i ERP5
Ce formulaire n'a besoin de contenir qu'un seul widget de type ListBox :
page 40/64
Tut o r i e l N e x e d i ERP5
Toujours par convention, nous l'appellerons listbox. Les List Box sont trs flexibles et nous allons les utiliser pour afficher un rsum du contenu du module de feuille de paie. La capture d'cran suivante vous montre les proprits de la List Box :
D'un point de vue utilisateur, ce formulaire aura le look suivant :
page 41/64
Tut o r i e l N e x e d i ERP5
Les proprits importantes d'une List Box sont List Action et List Method. Cette dernire prend la valeur portal_catalog, pour indiquer que la mthode utilise pour la gnration de la liste se base sur le catalogue. La proprit Colum,s permet de dfinir l'ordre et les donnes des colonnes de la liste. Le reste des proprits permet de grer un comportement avanc de la liste, comme le tri, la slection de lignes, le filtrage, etc. Nous ne nous attarderons pas dessus, et je vous laisse le soin d'explorer les possibilits offertes par ERP5Form. Cela devrait tre assez facile car les noms des proprits sont assez transparents et peuvent tre compris par des tests et essais.
page 42/64
Tut o r i e l N e x e d i ERP5
3.9. Les scripts python de calcul
L'tape suivante consiste crer un script qui, depuis le salaire brut, produit toutes les donnes de la feuille de paie. Pour cela nous crons un nouveau script python que nous nommerons PaySheetTransaction_calcul :
Nous mettons galement jour les actions du portal type des Pay Sheet Transaction pour qu'il prenne en compte notre script :
page 43/64
Tut o r i e l N e x e d i ERP5
En donnant la valeur object_action l'attribut Category, on ajoute une entre dans le menu d'action de la vue des Pay Sheet Transaction :
Le script tant vide, il ne va forcement rien se passer si on slectionne Calcul dans la liste des actions. Maintenant il va nous falloir coder le script pour qu'il : rcupre les donnes suffisante (salaire brut, employeur, etc), calcule les taux et les assiettes et distribue les montants selon les bonnes catgories et aux bons organismes sociaux. Les points 1 et 2 ne ncessitent pas d'explication particulires, en dehors de la connaissance fine de la mthode de calcul des montants. Nous allons ce propos simplement gnrer quelques lignes de feuilles de paies titre d'exemple. Le troisime et dernier point requiert quelques explications. Nous allons dtailler le comportement de la Structure PaySheetLine / PaySheetCell du point de vue du dveloppeur. Les cellules peuvent tre reprsentes comme des tableaux ou des matrices repres par deux catgories de base : assiette et categorie_taxe. Pour illustrer notre propos, prenons l'assurance vieillesse (les taux sont ceux d'avril 2003). La part salariale est gale la valeur du salaire plafonn multiplie par 6.55%. La part patronale est gale la somme de 1.60% du salaire brut et de 8.20% du salaire plafonn. Voici la reprsentation de ces chiffres au sein de la PaySheetLine pour un salaire de 3000 euros :
page 44/64
Tut o r i e l N e x e d i ERP5
Les objets sont identifis par un cadre rouge et leurs attributs les plus significatifs sont nots l'intrieur. La cotisation "Assurance vieillesse" est reprsente par une PaySheetLine qui contient une matrice de 4 cellules de type PaySheetCell. Puisque les catgories et les catgories de base se dfinissent au niveau de la PaySheetLine, cette dernire va tre capable de gnrer automatiquement le tableau de cellules sa cration. De ce fait nous n'avons plus qu' choisir notre cellule selon les catgories et lui affecter ses valeurs. Une cellule possde deux attributs : quantity et price. quantity reprsente l'assiette et price le taux. Pour calculer le montant, il suffit d'invoquer getTotalPrice() qui effectuera la multiplication quantity * price. L'assurance vieillesse est une sous-partie des cotisations de scurit sociale, et pour reprsenter cette hirarchie nous avons cr la sous catgorie secu. Cette dernire se subdivise en part salariale et en part employeur pour rpartir finement les montants. Puisque l'assurance vieillesse est calcule partir du salaire brut et du salaire plafonn, nous avons cr les sous-catgories correspondantes dans la catgorie de base assiette. Une bonne dfinition des catgories nous permettras par la suite de gnrer facilement des rapports dtaills. Puisque dans le script nous allons gnrer les cotisations d'assurance maladie, d'assurance vieillesse et d'assurance chmage, voici les catgories que nous avons ajoutes dans l'outil portal_category :
categorie_taxe categorie_taxe/secu categorie_taxe/secu/part_employeur categorie_taxe/secu/part_salariale categorie_taxe/chomage categorie_taxe/chomage/part_employeur categorie_taxe/chomage/part_salariale
page 45/64
Tut o r i e l N e x e d i ERP5
assiette assiette/salaire_brut assiette/salaire_plafonne assiette/tranche_a assiette/tranche_b assiette/tranche_c
Voici donc le script python qui gnrera les quelques lignes de feuilles de paie :
# Ce script est donn titre d'exemple # Les constantes ont t codes en dur pour faciliter la lecture global paysheet paysheet paysheet_type paysheet_cell_type paysheet_transactionline_type = = = = context.getObject() paysheet.getPortalType() 'Pay Sheet Cell' 'Pay Sheet Transaction Line'
employer = paysheet.getSourceSection() employee = paysheet.getDestinationSection() if employer in ('', None): return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employer+is+required') if employee in ('', None): return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employee+is+required') employer_object = paysheet.getSourceSectionValue() if employer_obj.getDefaultAddress().getZipCode() in ('', None): return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employer+must+have+a+zip+code') gross_salary = abs(paysheet.getGrossSalary()) employer_region = employer_object.getDefaultAddress().getZipCode()[:2] # limited salary = salaire plafonn if gross_salary < 2432: limited_salary = gross_salary else: limited_salary = 2432 # "Char" slice type if gross_salary <= 2432: char_slice = 'A' elif gross_salary <= 9728: char_slice = 'B' elif gross_salary <= 19456:
page 46/64
Tut o r i e l N e x e d i ERP5
char_slice = 'C' else: char_slice = '' ######################################################################### # This part of the script implement functions to register all pay sheet # informations from an ERP5 point of view. ######################################################################### def createPaySheetItem(title='', dest_org='', cells=[]): global paysheet # get all variation categories used in cells var_cat_list = [] for cell in cells: var_cat_list.append(cell["x"]) var_cat_list.append(cell["y"]) # add a new Pay Sheet Line payline = paysheet.newContent( portal_type = 'Pay Sheet Line' , title = title , destination = dest_org , variation_base_category_list = ('tax_category', 'salary_range') , variation_category_list = var_cat_list ) # fill each cell with values for cell in cells: paycell = payline.getCell(cell["x"], cell["y"], base_id = 'movement') paycell.edit(quantity=-cell["base"], price=cell["rate"]/100.0) ######################################################################### # This part of script describe the behaviour of the calculation process # from accountant point of view. ######################################################################### # social organism org_urssaf = 'organisation/urssaf' org_assedic = 'organisation/assedic' # variation categories cat_social_salary_share cat_social_employer_share cat_unemployment_salary_share cat_unemployment_employer_share cat_gross_salary cat_limited_salary cat_slice_a cat_slice_b cat_slice_c = = = = = = = = = 'tax_category/social/salary_share' 'tax_category/social/employer_share' 'tax_category/unemployment/salary_share' 'tax_category/unemployment/employer_share' 'salary_range/france/salaire_brut' 'salary_range/france/salaire_plafonne' 'salary_range/france/tranche_a' 'salary_range/france/tranche_b' 'salary_range/france/tranche_c'
# sickness insurance = assurance maladie if employer_region in ('57', '67', '68'):
page 47/64
Tut o r i e l N e x e d i ERP5
salary_share_rate else: salary_share_rate createPaySheetItem( , ,
= 1.70 = 0.75 title = 'Assurance maladie' dest_org = org_urssaf cells = [ { "x" : cat_social_salary_share , "y" : cat_gross_salary , "base" : gross_salary , "rate" : salary_share_rate }, { "x" : cat_social_employer_share , "y" : cat_gross_salary , "base" : gross_salary , "rate" : 12.80 } ] = assurance vieillesse title = 'Assurance vieillesse' dest_org = org_urssaf cells = [ { "x" : cat_social_salary_share , "y" : cat_limited_salary , "base" : limited_salary , "rate" : 6.55 }, { "x" : cat_social_employer_share , "y" : cat_gross_salary , "base" : gross_salary , "rate" : 1.60 }, { "x" : cat_social_employer_share , "y" : cat_limited_salary , "base" : limited_salary , "rate" : 8.20 } ]
) # old-age insurance createPaySheetItem( , ,
) # unemployment insurance = assurance chomage if char_slice in ('A', 'B'): if char_slice == 'A': cat_slice = cat_slice_a else: cat_slice = cat_slice_b createPaySheetItem( title = 'Assurance chomage' , dest_org = org_assedic , cells = [ { "x" : cat_unemployment_salary_share , "y" : cat_slice , "base" : gross_salary , "rate" : 2.4 }, { "x" : cat_unemployment_employer_share , "y" : cat_slice
page 48/64
Tut o r i e l N e x e d i ERP5
, "base" : gross_salary , "rate" : 4.0 } ] )
Si votre diteur prfr supporte le protocole WebDAV, n'oubliez pas que Zope le supporte galement. En d-commentant quelques lignes dans le fichier / etc/zope.conf et aprs un redmarrage de Zope, WebDAV sera activ et vous pourrez naviguer au sein de la ZODB puis diter trs facilement des script python dans votre environnement de dveloppement favori.
Illustration 7: Utilisation de WebDAV avec KATE
Avant de tester le script, n'oublier pas de crer les organisations Assedic et Urssaf avec le mme id qui est utilis dans le script (organisation/urssaf et organisation/assedic) pour qu'il puisse fonctionner.
page 49/64
Tut o r i e l N e x e d i ERP5
3.10. Le reporting
Nous allons voir dans cette partie comment utiliser les donnes gnres par notre script pour crer des rapports et les versions imprimable des feuilles de paie. Ces dernires seront produites au travers d'une Page Template que l'on crera dans local_erp5 sous le nom de PaySheetTransaction_print :
Les page templates ne sont en fait que de simples fichiers html (ou xml) dans lesquels nous allons utiliser des attributs spciaux dans les balises. Ce langage nomm TAL (Template Attribute Language) propre Zope permet de dcrire un comportement dynamique des pages. ERP5 intgre d'ailleurs un script qui permet de convertir automatiquement un document OpenOffice en TAL afin de faciliter la cration rapide de rapports PDF. Dans le cas de notre feuille de paie, nous allons crer un script python qui va se charger de pr-formater les donnes de la feuille de paie et nous allons l'appeler depuis la Page Template. Le script, que nous appellerons PaySheetTransaction_getDetails, va se charger essentiellement de collecter les part patronale et salariale pour chacune des taxe et les rassembler dans un dictionnaire :
# this dict contain all paysheet details
page 50/64
Tut o r i e l N e x e d i ERP5
paysheet_details = {} # initialize the employee and total_employee_share total_employer_share total_taxable_employee_share employer share total = 0.0 = 0.0 = 0.0
# get the gross salary gross_salary = context.getGrossSalary() if gross_salary == None: gross_salary = 0.0 paysheet_cat = {} object_list = [] for object in context.objectValues(): object_list += [object] # Sort the list by id since lines are already ordered by id. object_list.sort(lambda x, y: cmp(int(x.getId()), int(y.getId()))) for pay_sheet_line in object_list: variation_list = pay_sheet_line.getVariationCategoryList() range_variation = [] for variation in variation_list: if variation.find('salary_range')==0: if not variation in range_variation: # Extra checking because # get VariationCategoryList returns # the same 1 items 2 times range_variation += [variation] for range in range_variation: pay_sheet_dict = {} #pay_sheet_dict['range']=range[range.rfind('/')+1:] pay_sheet_dict['id'] = pay_sheet_line.getId() pay_sheet_dict['title'] = pay_sheet_line.getResourceTitle() for cell in pay_sheet_line.objectValues(): predicate_list = cell.getMembershipCriterionCategoryList() if range in predicate_list: pay_sheet_dict['base_name'] = context.portal_categories.resolveCategory(range).getTitleOrId() for predicate in predicate_list: if cell.getTotalPrice() != 0: if predicate.find('employee_share')>=0: pay_sheet_dict['base']= - cell.getQuantity() pay_sheet_dict['employee_share'] = cell.getTotalPrice() pay_sheet_dict['employee_share_rate'] = cell.getPrice() * 100 total_employee_share += float(-pay_sheet_dict ['employee_share']) # here we decide if a resource is taxable or not if str(pay_sheet_line.getResource())[-14:] == 'non_deductible' or str(pay_sheet_line.getResource())[-4:] == 'crds' or str (pay_sheet_line.getResource())[-7:] == 'taxable': pay_sheet_dict['taxable']='yes' elif str(pay_sheet_line.getResource())[-10:] == 'deductible': pay_sheet_dict['taxable']='no' else: pay_sheet_dict['taxable']='no'
page 51/64
Tut o r i e l N e x e d i ERP5
if pay_sheet_dict['taxable'] == 'yes': total_taxable_employee_share += float(-pay_sheet_dict ['employee_share']) elif predicate.find('employer_share')>=0: pay_sheet_dict['base'] = - cell.getQuantity() pay_sheet_dict['employer_share'] = cell.getTotalPrice() pay_sheet_dict['employer_share_rate'] = cell.getPrice() * 100 total_employer_share += float(-pay_sheet_dict ['employer_share']) for key in ('employee_share','employee_share_rate','employer_share','employer_share_rat e'): if not (pay_sheet_dict.has_key(key)): pay_sheet_dict[key]='' # so that we can display nothing # find the category of the current pay sheet line cat_id = None cat_path = None for var in variation_list: sub_cat = var.split('/') if sub_cat[0] == 'tax_category': cat_id = sub_cat[1] cat_path = sub_cat[0] + '/' + sub_cat[1] break if cat_id == None: cat_id = 'no_cat' # add the current pay sheet line to its category if not paysheet_cat.has_key(cat_id): paysheet_cat[cat_id] = {} paysheet_cat[cat_id]['lines'] = [] if cat_path != None: paysheet_cat[cat_id]['title'] = context.portal_categories.resolveCategory(cat_path).getTitleOrId() paysheet_cat[cat_id]['lines'].append(pay_sheet_dict) # get all paysheet transaction to calculate the sum of different value in a year accounting_folder = context.aq_parent paysheet_transactions = accounting_folder.contentValues(filter= {'portal_type':'Pay Sheet Transactionss'}) # initialize every yearly variable yearly_net_salary = 0.0 yearly_gross_salary = 0.0 yearly_employee_share = 0.0 yearly_employer_share = 0.0 yearly_taxable_net_salary = 0.0 # get the current paysheet start date and employee start_date = context.getStartDate() from DateTime import DateTime start_date = DateTime("%i/01/01" % start_date.year()) stop_date = context.getStopDate() employee = context.restrictedTraverse (context.getDestinationSectionRelativeUrl())
page 52/64
Tut o r i e l N e x e d i ERP5
#start_date = start_date.strftime('%Y-%m-%d') #stop_date = start_date.strftime('%Y-%m-%d') #yearly_employee_share = -float (context.PaySheetTransaction_zGetDetailedTotal (start_date=start_date,stop_date=stop_date,tax_category='employee_share') [0].total) #yearly_employer_share = -float (context.PaySheetTransaction_zGetDetailedTotal (start_date=start_date,stop_date=stop_date,tax_category='employer_share') [0].total) yearly_employee_share = 0 yearly_employer_share = 0 try: yearly_employer_share = -float (context.PaySheetTransaction_zGetDetailedTotal (start_date=start_date,stop_date=stop_date,tax_category='employer_share') [0].total) except: pass # browse through paysheet transaction for paysheet_obj in paysheet_transactions: # ignore the current paysheet to avoid infinite loop if paysheet_obj.getId() != context.getId(): # the paysheet must have the same employee if (employee==None) or (employee!=None and context.restrictedTraverse (paysheet_obj.getDestinationSectionRelativeUrl())==employee): # check the date if (start_date==None) or (start_date!=None and paysheet_obj.getStartDate()!=None and start_date.year() ==paysheet_obj.getStartDate().year() and paysheet_obj.getStartDate()<= start_date): # get all detailed values of the paysheet ps_details = paysheet_obj.PaySheetTransaction_getDetails() # sum of yearly values yearly_net_salary += float(ps_details['net_salary']) yearly_gross_salary += float(ps_details['gross_salary']) yearly_employee_share += float(ps_details ['total_employee_share']) yearly_employer_share += float(ps_details ['total_employer_share']) yearly_taxable_net_salary += float(ps_details ['taxable_net_salary']) # save the total share values in the exported dict paysheet_details['net_salary'] = gross_salary total_employee_share paysheet_details['gross_salary'] = gross_salary paysheet_details['paysheet_categories'] = paysheet_cat paysheet_details['total_employee_share'] = total_employee_share paysheet_details['taxable_net_salary'] = paysheet_details ['net_salary'] + total_taxable_employee_share paysheet_details['total_employer_share'] = total_employer_share
page 53/64
Tut o r i e l N e x e d i ERP5
paysheet_details['total_taxable_employee_share'] total_taxable_employee_share # don't forget to add the current values to the paysheet_details['yearly_net_salary'] = paysheet_details['net_salary'] paysheet_details['yearly_gross_salary'] = paysheet_details['gross_salary'] paysheet_details['yearly_employee_share'] = paysheet_details['total_employee_share'] paysheet_details['yearly_employer_share'] = paysheet_details['total_employer_share'] paysheet_details['yearly_taxable_net_salary'] = paysheet_details['taxable_net_salary'] return paysheet_details
= yearly sum yearly_net_salary + yearly_gross_salary + yearly_employee_share + yearly_employer_share + yearly_taxable_net_salary +
Une premire version de notre Page Template pourrait ressembler ceci :
<?xml version="1.0" encoding="iso-8859-1" ?> <document filename="report01.pdf" xmlns:tal="http://xml.zope.org/namespaces/tal" tal:define="employee python: here.getDestinationSectionValue(); employer python: here.getSourceSectionValue(); paysheet_details python: here.PaySheetTransaction_getDetails(); paysheet_categories python: paysheet_details ['paysheet_categories']; urssaf python: employer.getDestinationSectionValue(); start_date python: here.getStartDate(); boldstyle python:'(\'FONT\', \'Helvetica-Bold\', 7)'"> <title>VPN</title> <author>Nexedi</author> <subject>VPN List</subject> <content> <table splitbyrow="1" rowheight='0.4cm' repeatrows="1" repeatcols="0" style="decompte"> <tr> <td colwidth="4.318cm">Nature</td> <td colwidth="3.81cm">Assiette</td> <td colwidth="1.524cm">Montant</td> <td colwidth="2.77cm">Taux part patronale</td> <td colwidth="2.288cm">Part patronale</td> <td colwidth="2.397cm">Taux part salariale</td> <td colwidth="1.959cm">Part salariale</td> </tr> <tr tal:attributes="stylecmd boldstyle"> <!--stylecmd="('FONT', 'Helvetica-Bold', 7)"> --> <td>Salaire brut</td>
page 54/64
Tut o r i e l N e x e d i ERP5
<td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td tal:content="python: '%.2f' % paysheet_details ['gross_salary']" tal:condition="python: paysheet_details['gross_salary'] not in (None, '')">???</td> </tr> <tal:block tal:condition="python: paysheet_categories.has_key ('no_cat')"> <tal:block define="no_cat_lines python: paysheet_categories ['no_cat']['lines']"> <tr tal:repeat="line no_cat_lines"> <td><tal:block content="python: line['title']"/> </td> <td content="python: line['base_name']"> </td> <td content="python: '%.2f' % line['base']" tal:condition="python: line['base'] not in (None, '')"> </td> <td content="python: '%.3f %%' % line['employer_share_rate']" tal:condition="python: line['employer_share_rate'] not in (None, '')"> </td> <td content="python: '%.2f' % line['employer_share']" tal:condition="python: line['employer_share'] not in (None, '')"> </td> <td content="python: '%.3f %%' % line['employee_share_rate']" tal:condition="python: line['employee_share_rate'] not in (None, '')"> </td> <td content="python: '%.2f' % line['employee_share']" tal:condition="python: line['employee_share'] not in (None, '')"> </td> </tr> </tal:block> </tal:block> <tal:block repeat="category paysheet_categories"> <tr tal:attributes="stylecmd boldstyle"> <td tal:content="python: paysheet_categories[category] ['title']"> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tal:block define="paysheet_lines python: paysheet_categories [category]['lines']"> <tr tal:repeat="line paysheet_lines" stylecmd="('LEFTPADDING',8)"> <td><tal:block tal:content="python: ' ' + line['title']"/> </td> <td><tal:block tal:content="python: line['base_name']"/> </td> <td> <tal:block content="python: '%.2f' % line['base']" tal:condition="python: line['base'] not in (None, '')"></tal:block></td> <td> <tal:block content="python: '%.3f %%' % line ['employer_share_rate']" tal:condition="python: line['employer_share_rate'] not in (None, '')"></tal:block></td>
page 55/64
Tut o r i e l N e x e d i ERP5
<td> <tal:block content="python: '%.2f' % line ['employer_share']" tal:condition="python: line['employer_share'] not in (None, '')"></tal:block></td> <td> <tal:block content="python: '%.3f %%' % line ['employee_share_rate']" tal:condition="python: line['employee_share_rate'] not in (None, '')"></tal:block></td> <td> <tal:block content="python: '%.2f' % line ['employee_share']" tal:condition="python: line['employee_share'] not in (None, '')"></tal:block></td> </tr> </tal:block> </tal:block> <tr tal:attributes="stylecmd boldstyle"> <td>Total des cotisations</td> <td> </td> <td> </td> <td> </td> <td> <tal:block replace="python: '-%.2f' % paysheet_details ['total_employer_share']" tal:condition="python: paysheet_details ['total_employer_share'] not in ('', None)"> </tal:block></td> <td> </td> <td> <tal:block replace="python: '-%.2f' % paysheet_details ['total_employee_share']" tal:condition="python: paysheet_details ['total_employee_share'] not in ('', None)"> </tal:block></td> </tr> <tr tal:attributes="stylecmd boldstyle"> <td>Salaire Net</td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> <tal:block replace="python: '%.2f' % paysheet_details ['net_salary']" tal:condition="python: paysheet_details['net_salary'] not in ('', None)"> </tal:block></td> </tr> <tal:block repeat="category paysheet_categories"> <tal:block define="paysheet_lines python: paysheet_categories [category]['lines']"> <tal:block repeat="line paysheet_lines"> <tr tal:condition="python: line.has_key('taxable') and line ['taxable']=='yes'"> <td> <tal:block content="python: line['title']"/></td> <td> <tal:block content="python: line['base_name']"/></td> <td> <tal:block replace="python: '%.2f' % line['base']" tal:condition="python: line['base'] not in ('', None)"></tal:block></td> <td> </td> <td> </td> <td> <tal:block replace="python: '%.3f %%' % line ['employee_share_rate']" tal:condition="python: line['employee_share_rate'] not in ('', None)"></tal:block></td>
page 56/64
Tut o r i e l N e x e d i ERP5
<td> <tal:block replace="python: '+%.2f' % abs(float(line ['employee_share']))" tal:condition="python: line['employee_share'] not in ('', None)"></tal:block></td> </tr> </tal:block> </tal:block> </tal:block> <tr tal:attributes="stylecmd boldstyle"> <td>Salaire Net Imposable</td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> <tal:block replace="python: '%.2f' % paysheet_details ['taxable_net_salary']" tal:condition="python: paysheet_details ['taxable_net_salary'] not in ('', None)"> </tal:block></td> </tr> </table> <table rowheight="0.6cm"><tr><td> </td></tr></table> <table style="cumul_conges"> <tr> <td colwidth="11cm"> <tal:block tal:replace="python: 'Cumuls annuels (%s)' % start_date.year()" tal:condition="python: start_date not in ('', None)"/></td> <td colwidth="3cm"> </td> <td colwidth="5cm"> <!-- <tal:block tal:replace="python: 'Dure des congs pays : ???'"/> --> </td> </tr> </table> <table style="cumul_conges_corps"> <tr> <td colwidth="2cm">Salaire brut</td> <td colwidth="3cm">Cotisations salariales</td> <td colwidth="2cm">Salaire net</td> <td colwidth="2cm">Net imposable</td> <td colwidth="2cm">Part patronale</td> <td colwidth="3cm"> </td> <td colwidth="5cm"> <tal:block tal:replace="python: 'Dure des dlais de pravis : ' + context.PaySheetTransaction_getPreavis()"/></td> </tr> <tr> <td> <tal:block replace="python: '%.2f' % paysheet_details ['yearly_gross_salary']" tal:condition="python: paysheet_details ['yearly_gross_salary'] not in ('', None)"></tal:block></td> <td> <tal:block replace="python: '%.2f' % paysheet_details ['yearly_employee_share']" tal:condition="python: paysheet_details ['yearly_employee_share'] not in ('', None)"></tal:block></td> <td> <tal:block replace="python: '%.2f' % paysheet_details ['yearly_net_salary']" tal:condition="python: paysheet_details ['yearly_net_salary'] not in ('', None)"></tal:block></td>
page 57/64
Tut o r i e l N e x e d i ERP5
<td> <tal:block replace="python: '%.2f' % paysheet_details ['yearly_taxable_net_salary']" tal:condition="python: paysheet_details ['yearly_taxable_net_salary'] not in ('', None)"></tal:block></td> <td> <tal:block replace="python: '%.2f' % paysheet_details ['yearly_employer_share']" tal:condition="python: paysheet_details ['yearly_employer_share'] not in ('', None)"></tal:block></td> <td> </td> <td> </td> </tr> </table> </content> </document>
Ajoutons ensuite une action dans le portal type des Pay Sheet Transaction avec la valeur object_print pour category :
Grce cette petite manipulation il nous reste plus qu' cliquer sur l'icne de l'imprimante dans la vue d'une feuille de paie pour rcuprer la version imprimable :
La Page Template sera appele dans le contexte actuel et la feuille de paie imprimable s'affichera l'cran sous forme de document PDF :
page 58/64
Tut o r i e l N e x e d i ERP5
Illustration 8: Une feuille de paie gnre par ERP5
La technologie employe pour le rendu PDF est reportlab. Il s'agit d'une bibliothque crite en python, utilise par des tablissements financiers prestigieux et capable de gnrer plusieurs centaines de pages PDF par minute sur un serveur bas de gamme.
page 59/64
Tut o r i e l N e x e d i ERP5
3.11. La cration du business template
Maintenant que le module fonctionne dans son ensemble, nous allons le rassembler au sein d'un Business Template pour pouvoir le distribuer et l'installer facilement. La procdure de cration d'un Business Template est assez rapide si on connat exactement toutes les composantes qui sont ncessaire au bon fonctionnement du module que l'on veut packager. Il faut d'abord nous rendre dans l'outil portal_templates et ajouter un nouveau Business Template en utilisant le menu "Action". Nous appellerons ce Business Template erp5_payroll et allons maintenant l'diter et lister dans les diffrents champs les objets qui doivent tre inclus :
http://localhost:9080/erp5/portal_templates/GestionDesSalaires/view
Les champs renseigns sont :
id : L'id du Business Template Name : le nom du Business Template, qui doit tre unique pour chaque groupe de fonctionnalits Portal Types : la liste des types documentaires dfinis par le Business Template Skin Folders : le dossier dans portal_skins o sont stocks les lments de prsentation
page 60/64
Tut o r i e l N e x e d i ERP5
Base Categories : les catgories et relations ncessaires au fonctionnement du module Paths : des documents ncessaires au fonctionnement du module (ici, les organisations URSSAF, etc, ncessaires au calcul de la paye)
Maintenant que le Businnes Template connat toutes les composantes de notre module, nous pouvons construire le Business Template via l'action "Build Business Template" du menu "Action" puis l'export via l'action "Export Busines Template" du mme menu. On peut ds prsent tester notre nouveau Business Template sur une nouvelle instance de Zope pour s'assurer que notre module fonctionne avant de le distribuer.
page 61/64
Tut o r i e l N e x e d i ERP5
3.12. Le point sur la catalogage
Le catalogage est en fait un moyen de stocker certaines information d'un objet (comme sont ID, titre, description, etc) dans une base de donne annexe. Le catalogue permet de slectionner instantanment des objets sans reparcourir toute la base objet de Zope. Il permet d'effectuer des requtes rapides sur des bases de grande taille. Nexedi a par exemple dploy un systme contenant plus de 2.000.000 de documents et plus de 10 000 000 d'enregistrements de catalogue. La technologie de catalogue dveloppe par Nexedi pour ERP5 se nomme "ZSQL Catalog". C'est un produit zope qui permet d'effectuer des requtes SQL sans limite de complexit sur un catalogue dont la structure est elle-mme adaptable sans limites. L'objectif est de constituer un catalogue selon un modle d'indexation susceptible d'offrir des temps de rponse trs courts. L'approche est similaire celle utilise par les moteurs OLAP ou le datawarehousing pour le traitement statistiques de donnes consolides.
page 62/64
Tut o r i e l N e x e d i ERP5
4. Conclusion
Nous avons appris dans cet article installer une plateforme ERP5 et ses modules grce au systme de Business Template d'ERP5. Nous avons ensuite cr une version simpliste du module de feuille de paie qui existe dj dans ERP5. Il existe beaucoup de diffrences entre ces deux versions. En particulier, le module de paye d'ERP5 repose sur le moteur de planification d'ERP5 afin de permettre des prvisions de trsorerie. Cependant, la structure de donne et les principes de base restent les mmes. Nous pouvons dsormais exploiter ERP5 pour construire en un temps record un ERP fonctionnel capable de grer un grand nombre d'aspects d'une entreprise ou d'une organisation. La bibliothque actuelle de Business Template, qui est appele croitre et s'enrichir, offre la fois des briques de base et une source d'inspiration. Si toutefois les Business Template existants ne rpondent pas votre besoin, vous disposez dsormais des bases ncessaire pour crer les votres. Dans ce cas n'oubliez pas de partager avec nous vos crations sur le site web www.erp5.org et sur les mailing-list erp5-dev et erp5-user.
page 63/64
Tut o r i e l N e x e d i ERP5
5. TODO
Amliorations envisager sur ce document. Question se poser: * faut-il supprimer certaines parties trop dtaille ? (variantage, category, construction des classes) * indiquer les conventsion de nommage utilises par ERP5 * crer avec le lecteur un nouveau folder dans les portal_skins et lui faire changer les settings pour lui expliquer comment erp5 va chercher les formulaire ? * dire l'utilisateur qu'il est prudent de donner un nom chaque formulaire * ne pas evoquer les paysheet transaction line ? (compression de l'article) TODO: * couper les parties des images qui ne sont pas utiles (surtout celle avec des scrennshot de dropdown list/combo) * mettre en italique les babarismes (getter / setter / packages / etc) ou trouver une version franaise * intgrer une bibliographie/webographie la fin de l'article * intgrer "Lors du dveloppement du vritable Business Template, que vous trouverez dans la section download du site erp5.org, nous n'avons pas eu besoin de crer de module. En ralit le produit final des feuilles de paie est rassembl dans le Business Template Human Resources (HR) qui contient aussi les fonctionnalits de gestion de carrires et s'intgre dans diffrents modules pr-existants (les feuilles de paie dans le module Accounting et la gestion de carrires dans le module Person). " * simplifier les scripts et templates de rapports * mettre jour les recopies d'cran qui mentionnent base_edit, base_update_relation, etc. en utilisant le nouveau nommage (Base_edit, Base_updateRelation, etc.)
page 64/64
Tut o r i e l N e x e d i ERP5
Dveloppez votre propre Dveloppez ERP grce aux Business Templates ERP5
page 1/64
Tut o r i e l N e x e d i ERP5
page 2/64
Tut o r i e l N e x e d i ERP5
Sommaire
1. Introduction.............................................................................4 2. ERP5: un ERP pour tous............................................................5
2.1. ERP5 sans installation.......................................... .................................5 2.2. Installer un systme ERP5....................................................................5 2.3. Etendre ERP5 avec les Business Templates........................................10
3. Crons notre propre Business Template !.................................16
3.1. Conception de la structure de donnes..............................................16 3.2. Le variantage par catgories..............................................................20 3.3. Intgrons notre structure de donnes dans ERP5...............................21 3.4. Web Dveloppement rapide avec portal_classes................................22 3.5. Structure d'une classe Document dans ERP5......................................24 3.6. Crer un Module dans EPR5................................. ...............................27 3.7. Intgrer les classes, donnes, menus et prsentation : l'outil portal_types............................................................ ...................................29 3.8. L'interface utilisateur avec ERP5Form........................................ .........30 3.9. Les scripts python de calcul....................................... .........................43 3.10. Le reporting..................................... .................................................50 3.11. La cration du business template.....................................................60 3.12. Le point sur la catalogage................................................ .................62
4. Conclusion..............................................................................63 5. TODO.....................................................................................64
page 3/64
Tut o r i e l N e x e d i ERP5
1. Introduction
Cet article est destin aux dveloppeurs qui veulent s'approprier ERP5 et ses mcanismes pour en faire un outil de gestion d'entreprise qui rpond exactement leurs besoins. Avec ERP5, ce n'est plus l'entreprise qui se conforme la logique ERP, c'est l'ERP qui s'adapte la culture de l'entreprise, ses mthodes et ses habitudes de travail. ERP5 dispose sous forme de framework de tous les outils ncessaires pour atteindre cet objectif. Cela passe la plupart du temps par la ralisation ou la modification d'un module de l'ERP sous la forme d'un paquetage fonctionnel ou mtier appel "Business Template". Cet article vous apprendra installer rapidement une plate-forme ERP5 grce aux Business Template avant de vous accompagner dans la ralisation d'un module simple de gestion de feuilles de paie. Cette seconde partie de l'article sera l'occasion idale d'aborder toutes les techniques de conception au sein d'ERP5 pour que vous puissiez par la suite crer vos propres Business Template de faon autonome.
Support Commercial ERP5 ERP5 est un ERP libre en licence GPL dvelopp et dit par la socit Nexedi. Nexedi coordonne un rseau de partenaires certifis pour le dploiement de solutions ERP5 en entreprise. Nexedi et ses partenaires assurent travers leurs quipes d'ingnieurs et leurs consultants l'assistance, la formation et le transfert des comptences ncessaires la matrise d'ERP5 sur le terrain. http://www.erp5.org/sections/documentation/evangelism/enterprise/ Tel. +33 662 05 76 14 Mel. info@nexedi.com
page 4/64
Tut o r i e l N e x e d i ERP5
2. ERP5: un ERP pour tous
2.1. ERP5 sans installation
Si vous souhaitez utiliser ERP5 srieusement et sans perdre du temps dans des problmatiques d'installation sans valeur ajoute, nous vous recommandons d'utiliser le LiveCD d'ERP5 (et d'y contribuer). Le LiveCD ERP5 a t conu comme un outil de dveloppement et de production, et pas seulement comme un dmonstrateur. Il peut tre tlcharg sur: http://livecd.erp5.org. Son principe est simple :
On inserre un CD dans un PC standard, on appuye sur dmarrer puis, aprs quelques minutes, on installe des Business Template que l'on peut utiliser, paramtrer et tendre.
2.2. Installer un systme ERP5
Si l'usage d'un LiveCD ne vous convient pas, il est cependant possible d'installer ERP5 de faon traditionnelle. Il faut compter entre quelques dizaines de minutes (si vous utilisez une distribution comme Mandrakelinux pour laquelle tous les paquetages et leurs dpendances ont t crs) et quelques jours (si vous utilisez une distribution sans paquetages ERP5).
page 5/64
Tut o r i e l N e x e d i ERP5
Pour fonctionner, ERP5 a besoin du serveur d'applications Zope sur lequel il se fonde et ainsi qu'un nombre consquent de produits Zope. Nous avons aussi besoin d'installer MySQL-max (une version de la plus populaire des bases de donnes libres qui supporte les transactions). MySQL-max est utilis par le moteur de recherche de Zope via le produit ZSQLcatalog. Pour un systme complet, il nous faut donc :
un serveur Zope (et toutes ses dpendances li Python) comportant les optimisations dveloppes par Nexedi en matire de mta-programmation1 les produits Zope BTreeFolder, Base18, CMF, CMFActivity, CMFCategory, CMFMailIn, CMFPhoto, CMFReportTool, ERP5, ERP5Catalog, ERP5Compatibility, ERP5Form, ERP5SyncML, ERP5Type, ExtFile, Formulator, Localizer, Photo, TranslationService, ZMailIn, ZMySQLDA et ZSQLCatalog.
MySQL-max
Pour mener bien cette mission, il faudra compter sur les paquetages de votre distribution Linux. Vous pouvez aussi partir des sources et installer Zope par un traditionnel ./configure, make, make install. Quand aux produits Zope, ils sont trs faciles et rapide installer puisqu'il s'agit en fait d'archives dcompresser dans le rpertoire Products de Zope (gnralement /var/lib/zope/Products ou / usr/lib/zope/lib/python/Products) et de quelques extensions (zsqlbrain.py et InventoryBrain.py) ajouter dans le rpertoire Extensions de Zope (gnralement /var/lib/zope/Extensions ou /usr/lib/zope/lib/python/Extensions). Vous trouverez sans trop de difficults des didacticiels et de la documentation sur le net pour l'installation et la configuration globale de Zope. Les heureux utilisateurs de Mandrake peuvent se contenter d'un simple urpmi ERP5 mysql-max, aprs avoir ajout les sources main, contrib et nexedi2 leur gestionnaire de paquetages. Notons que l'ensemble des manipulations dcrites dans cet article ont t ralises sur une Mandrake 10.0 et devraient tre quivalentes avec une Mandrake 10.1. Une fois l'installation le des paquetages termine, utilisons la console d'administration de Zope, zopectl, pour changer le mot de passe par dfaut de l'administrateur (le login par dfaut tant admin). L'ajout d'un utilisateur ne peut se faire que si le serveur Zope est arrt. Il se peut trs bien que la procdure d'installation ait dmarr le serveur, nous l' arrterons donc avant la manipulation. Ensuite seulement nous pourrons dmarrer MySQL-max et Zope :
[root@localhost /]# /etc/init.d/zope stop Arrt de zope : . daemon process stopped
1 Le code source de ces optimisations est tlchargeable l'URL http://www.nexedi.org/static/Mandrake/10.1/SRPMS/zope2.7.2rc1 1nxd.src.rpm 2 http://www.nexedi.org/static/Mandrake/10.1/RPMS ou http://www.nexedi.org/static/Mandrake/10.0/RPMS page 6/64
Tut o r i e l N e x e d i ERP5
[root@localhost /]# zopectl program: /usr/bin/runzope daemon manager not running zopectl> help adduser adduser -- add a Zope management user zopectl> adduser admin admin [root@localhost /]# /etc/init.d/mysql-max start Lancement du serveur MySQL [root@localhost /]# zopectl program: /usr/bin/runzope daemon manager not running zopectl> start daemon process started, pid=7944 [ OK ]
Il nous reste plus qu' vrifier le fonctionnement de Zope en accdant la ZMI, l'interface web de gestion de Zope, o l'on s'identifiera avec le mot de passe de l'utilisateur admin que l'on vient d'ajouter :
http://localhost:9080/manage
Illustration 1: L'accs la Z MI ncessite une authentification
page 7/64
Tut o r i e l N e x e d i ERP5
Illustration 2: ZMI, l'interface web de gestion de Zope
Le serveur Zope tant dsormais oprationnel et accessible, nous allons crer une instance d'ERP5 en slectionnant le type ERP5 Site dans la liste droulante en haut droite :
Une page de proprits est affiche dans la ZMI et nous la remplirons comme sur la capture d'cran :
page 8/64
Tut o r i e l N e x e d i ERP5
La validation de ce formulaire conduit cet cran en cas de succs :
Mais il est frquent de voir apparatre l'erreur suivante ce moment prcis :
Site Error An error was encountered while publishing this resource. Error Type: DatabaseError Error Value: z0_catalog_object is not connected to a database
Cette erreur signifie simplement que le serveur MySQL-max n'est pas dmarr. Un redmarrage de ce dernier suffit pour que tout rentre dans l'ordre. On peut maintenant se rendre sur la page de garde d'ERP5 via l'url :
page 9/64
Tut o r i e l N e x e d i ERP5
http://localhost:9080/erp5/
ERP5 est maintenant oprationnel sur votre machine et se suffit lui mme pour commencer l'initiation. Je conseillerais cependant aux plus courageux de mettre jour ERP5 depuis le CVS d'ERP53, pour pouvoir profiter des dernires volutions et corrections de bugs. Mise en garde : bien que ERP5 soit maintenant install et utilisable sur votre machine ou sur votre serveur, il n'est pas conseill de l'utiliser "tel quel" en production. Une configuration fine (cluster, systme d'activit, etc.) est en effet ncessaire pour obtenir des performances leves et une rflexion sur la politique de scurit des donnes est indispensable pour protger des donnes vitales pour l'entreprise.
2.3. Etendre ERP5 avec les Business Templates
Les Business Templates sont ERP5 ce que les systmes de paquetages (rpm, apt) sont aux distributions Linux. Les RPM ont pour but de simplifier l'installation de logiciels au sein d'un systme. Les Business Templates ont le mme rle en prenant en charge l'installation propre et automatise de l'ensemble d'un module d'ERP5. D'un point de vue de l'utilisateur, installer un Business Template c'est ajouter une fonctionnalit majeure l'ERP, en largissant ses capacits de gestion d'entreprise. Il existe actuellement huit Business Templates, chacun tant ddi un aspect de la gestion d'entreprise:
Trade : gestion commerciale (achats et ventes, commandes, bons de livraison, facturations, gestion des stocks) PDM (Product Data Management) : gestion des donnes produit (dfinition des produits, variantes, catgorisation, nomenclatures, gamme opratoire, catalogue multimdia) MRP (Manufacturing Ressources Planning) : organisation et gestion de production (ordres de fabrication, planning de production) CRM (Customer Relationship Management) : gestion des relations clientles (base de donnes des organisation et des personnes, opportunits commerciales) Accounting : comptabilit (livre de comptes, rapports financiers)
3 http://cvs.erp5.org voir galement le script update_cvs.sh dans /var/lib/zope/ qui permet d'automatiser les mises jour page 10/64
Tut o r i e l N e x e d i ERP5
HR (Human Resources) : gestion des ressources humaines (livre de paie, gestion de carrires) eCommerce : commerce lectronique (magasin de vente en ligne, affiliations) CMS (Content Management System) : gestion de contenu web (via NuxeoCPS4)
Certains de ces Business Template ont atteint un premier stade de maturit (ex. Accounting permet aujourd'hui de clturer un exercice comptable). Les autres sont encore en cours d'intgration. En effet, bien que ERP5 soit utilis aujourd'hui en production sur des sites importants avec une couverture fonctionnelle complte (ex. nomenclatures, gestion de production, calcul des besoins, gestion de stock, facturation, etc.), les clients d'ERP5 ne souhaitent pas pour la plupart financer le surcot de l'intgration sous forme de Business Template gnrique du travail spcifique qui a t effectu pour adapter le framework ERP5 leurs propres besoins. Le travail d'intgration des Business Template est donc effectu par Nexedi de faon bnvole. Voil pourquoi toutes les fonctionnalits du framework ERP5 ne sont pas encore couvertes par les Business Template disponibles en tlchargement. L'un des premier module conu qui utilise le systme de Business Templates est le module de gestion de feuille de paie. Ce module permet de grer un livre de paie et de crer des bulletins de salaire. C'est ce module qui nous servira de support tout au long de l'article. Nous allons maintenant dtailler le processus d'installation de ce Business Template. Ce processus ncessite de disposer un compte avec les droits Manager. Tout convient d'accder avec votre navigateur au module portal_templates en tapant une URL telle que http://localhost/erp5/portal_templates ou http://localhost:9480/erp5/portal_templates en fonction de votre configuration. Vous pourrez alors accder la liste des Business Template : d'abord, il
4 http://www.cpsproject.org/ page 11/64
Tut o r i e l N e x e d i ERP5
A titre de comparaison, un systme ERP5 plus complet comporte de nombreux Business Templates :
Notre objectif est donc de passer d'une liste pratiquement vide de Business Template une liste plus complte. Pour atteindre cet objectif, il suffit de cliquer sur le bouton "Import/Export" dans la deuxime barre de boutons partir du haut de la page ERP5. Ce bouton ressemble ceci :
Aprs avoir cliqu dessus, vous arrivez sur le dialogue d'import de Business Template :
page 12/64
Tut o r i e l N e x e d i ERP5
Utilisez alors le menu "Exchange Select" pour passer du dialogue "Import Business Template" "Download Business Template" :
Il vous reste alors saisir dans les deux champs, d'une part un identifiant du Business Template (ex. erp5_accounting) puis l'URL de ce Business Template (ex.
http://cvs.erp5.org/cgibin/viewcvs.cgi/*checkout*/erp5_bt5/erp5_trade.bt5?rev=HEAD&content-type=text/plain)
et cliquer sur "Download Business Template". Le tlchargement sera effectu automatiquement ( condition d'avoir accs Internet) et, en cas de succs, vous verrez apparatre un message "Business Template Downloaded Successfully". Vous pouvez alors cliquer sur le Business Template que vous venez de tlcharger. Vous verrez alors un formulaire de dfinition :
page 13/64
Tut o r i e l N e x e d i ERP5
Pour procder l'installation, allez dans le menu "Action" et appelez "Install Business Template"
Vous venez d'installer le Business Template de comptabilit d'ERP5. Ce module est indispensable pour le Business Template de paye. Continuons maintenant avec la paye. Le principe est le mme, il faut juste importer un Business Template diffrent en lui donnant comme id erp5_payroll et comme URL de tlchargement http://cvs.erp5.org/cgibin/viewcvs.cgi/*checkout*/erp5_payroll/erp5_trade.bt5?rev=HEAD&contenttype=text/plain
Voici un exemple de feuille de paie gnr par ce Business Template :
page 14/64
Tut o r i e l N e x e d i ERP5
Illustration 3: Une feuille de paie gnre par ERP5
Pour crer cette feuille de paie, nous nous sommes bass sur un document disponible sur le site communautaire erp5.org (http://www.erp5.org/workspaces/project/erp5_payroll/erp5_pay_sheet_for_n). Ce document en anglais destin aux dbutants explique la procdure suivre pour arriver ses fins. Il vous aidera dans l'utilisation du module de feuille de paie. Maintenant que nous connaissons le principe des Business Template d'un point de vue utilisateur, nous pouvons entamer le coeur de cet article : la cration d'un Business Template.
page 15/64
Tut o r i e l N e x e d i ERP5
3. Crons notre propre Business Template !
L'objectif de la seconde partie de cet article est d'offrir une vue d'ensemble de la plate-forme de dveloppement ERP5 des dveloppeurs. Dans ce but nous allons reconstruire dans les grandes lignes le module de feuilles de paie. Cela nous donnera l'occasion de dmontrer la convivialit et la puissance d'ERP5 pour la cration rapide de modules fonctionnels, mais galement d'approcher les technologies et les concepts qui sont la base d'ERP5.
3.1. Conception de la structure de donnes
Les objets ERP5 drivent tous de 5 classes fondamentales :
Ce modle thorique d'EPR5 dj fait l'objet d'une publication scientifique5 qu'il sera intressant de consulter pour comprendre les motivations qui se cachent derrire chacun des concepts cl d'ERP5. Nous retiendrons de ce document la description des 5 classes fondamentales :
Ressource
Le type Resource dcrit une ressource abstraite d'un processus mtier comme les comptences d'une personne, une devise, une matire premire, ou un produit.
Node
Les objets de type Node peuvent envoyer ou recevoir des ressources. Un noeud peut reprsenter une entit physique (telle une machine de production, qui reoit des matires premires, les transforment et les
5 http://www.computer.org/itpro/cover_stories/smets.htm page 16/64
Tut o r i e l N e x e d i ERP5
envoient) ou une entit abstraite (tel un compte en banque qui reoit des sommes d'argents). Les stocks sont reprsents par des noeuds. Des mtanoeud (MetaNode) sont des noeuds qui contiennent d'autres noeuds. C'est le cas par exemple d'une entreprise.
Movement
Cette classe dcrit le mouvement de ressources entre deux noeuds un moment donn, pour un temps donn. Par exemple un mouvement peut dcrire l'envoi de matire premires d'un stock vers un atelier; un mouvement peut aussi reprsenter l'envoi d'argent depuis un compte vers un autre.
Path
Un chemin dcrit le moyen pour un noeud d'accder une ressource dont il a besoin. Des prix et des profils commerciaux peuvent tre attachs un chemin pour dfinir par exemple le prix par dfaut d'une ressource fournit un fabricant. Un chemin peut aussi dfinir la manire dont un atelier obtient ses ressources du stock. Un chemin possde des attributs de date de dbut et de fin, et peut reprsenter l'affectation d'un individu une mission temporaire.
Item
Un item est une instance physique d'une quantit de ressource. Un mouvement peut se dtailler en une srie de mouvements traable via des items. Les Items dfinissent aussi la manire dont les ressources sont livres (selon un colis entier ou en listant les numros de srie des items dans chaque conteneur).
En analysant une feuille de paie franaise classique, nous avons choisis de crer 4 types d'objets :
PaySheetTransaction PaySheetTransactionLine PaySheetLine PaySheetCell
Voici un diagramme de classes qui donne la hirarchie et les hritages permettant de relier les classes de bases d'ERP5 avec nos 4 nouveaux types d'objets :
page 17/64
Tut o r i e l N e x e d i ERP5
Folder
XMLObject
Movement
Delivery
DeliveryLine
DeliveryCell
Accounting Transaction
Invoice
Accounting Transaction Line
InvoiceLine
InvoiceCell
PaySheet Transaction
1
0..* Transaction
Line
PaySheet
0..*
PaySheet Line
1
0..*
PaySheet Cell
La structure de donnes des feuilles de paie est calque sur le modle de facturation (Invoice). Ce dernier est dcrit par 3 classes : Invoice, InvoiceLine et InvoiceCell. Ces trois classes permettent de dtailler une facture (Invoice) en lignes de facturation via InvoiceLine (une ligne de facture par produit factur), elles mmes dcomposables selon des variantes du mme produit factur. Ainsi les InvoiceCell permettent par exemple de dtailler la facturation d'une uantit de quatre produits A en trois produits A de couleur bleue et un produit A de couleur verte. Comme nous le montre le diagramme, les factures spcialisent le systme de reprsentation des livraison (Delivery) qui implmente l'origine la structure Line/Cell. Les cellules (Cell) sont la partie visible du concept de variantage qu'offre ERP5. Ce concept permet de reprsenter des variantes d'une mme ressource comme la couleur, la taille ou la vitesse. Cela permet de dfinir plusieurs configurations d'un mme produit. L'avantage de ce systme rside dans la possibilit de configurer trs profondment l'ERP5 tout en gardant les bnfices d'une gestion gnrique des donnes selon une structure standardise. Nous dtaillerons le concept de variantage un peu plus loin dans cette article. Nous allons maintenant dtailler nos diffrentes classes.
PaySheetTransaction
La feuille de paie en elle mme est reprsente par un objet de type
PaySheetTransaction.
page 18/64
Tut o r i e l N e x e d i ERP5
Cette classe drive de la classe de base Folder via Invoice. Nous avons choisi cet hritage car les objets de type PaySheetTransaction vont nous servir regrouper au mme endroit les objets relatifs une feuille de paie. C'est pour cela que PaySheetTransaction n'a pas comme classe anctre l'une des 5 classes de base d'ERP5. Folder est en quelque sorte une "classe utilitaire" qui nous permet de rduire l'entropie du systme. Et comme les PaySheetTransaction sont des Folder avec des comportements particuliers dont certains sont les mmes que pour une facture (Invoice), nous avons d crer une nouvelle classe. Ces comportements particuliers permettront de prendre en compte la notion d'employeur et de salari ainsi que d'autres donnes propres la feuille de paie (date de paiement, salaire brut, ).
PaySheetLine
Comme l'indique le diagramme, chaque PaySheetTransaction peut contenir des PaySheetLine qui sont la reprsentation des diffrentes cotisations soustraite sur le salaire brut. Pour chaque cotisation il y a une et une seule PaySheetLine.
PaySheetCell
Les PaySheetLine contiennent les PaySheetCell, qui permettent de reprsenter et dtailler les montants de la PaySheetLine. Le systme de variantage permettra de distinguer les parts employeur et employe d'une cotisation sociale donne et de conserver une trace de la mthode de calcul des montants. Car pour une cotisation donne, le montant d'une part (salariale ou patronale) peut tre le fruit d'un savant calcul faisant intervenir un ou plusieurs taux, associ chacun une assiette (salaire brut, salaire plafonn, salaire tranche A/B/C, ). Le calcul des feuilles de paie n'est pas vident, d'autant plus que la lgislation change tout les jours Le variantage offre un avantage de taille dans ce cas car il permet de parer toutes les complications induites par la lgislation de chaque pays.
PaySheetTransactionLine
Les PaySheetTransactionLine sont la reprsentation comptable de la feuille de paie. Nous avons choisi de distinguer les PaySheetLine et les PaySheetTransactionLine car la reprsentation de la feuille de paie selon la logique comptable agrge certains montants et rend impossible un reporting fin sur la paye. Nous avons donc au sein d'une PaySheetTransaction deux ensembles :
Les donnes du couple PaySheetLine/PaySheetCell : un jeu de donnes de
page 19/64
Tut o r i e l N e x e d i ERP5
base qui nous permet d'afficher les dtails de la feuille de paie et de manipuler les chiffres dans tous les sens.
Les donnes de type PaySheetTransactionLine, qui reprsentent les lignes comptable de la feuille de paie
Maintenant que nous avons un modle de donnes cohrent, nous allons l'implmenter dans ERP5.
3.2. Le variantage par catgories
Les objets de type Category sont utiliss dans ERP5 pour la classification. Par exemple, un document peut possder un attribut couleur. Au lieu de laisser l'utilisateur entrer une valeur libre, via un champ texte, pour l'attribut couleur, on prfrera attribuer l'objet une catgorie. On fabriquera donc via la ZMI les catgories couleur/bleu, couleur/vert et couleur/rouge :
Les catgories peuvent contenir des sous-catgories. Par exemple pour dcrire les rgions gographiques :
region/europe region/europe/west/ region/europe/west/france region/europe/west/germany region/europe/south/spain region/americas region/americas/north region/americas/north/us
page 20/64
Tut o r i e l N e x e d i ERP5
region/americas/south region/asia
Dans cet exemple la catgorie de base est region. Les catgories ont d'autres avantages comme le catalogage automatique. Ce mcanisme rend possible l'utilisation de requtes SQL pour slectionner les objets de la ZODB selon la valeur de la catgorie (voir plus bas paragraphe : catalogage). Il est possible de crer des classifications "virtuelles" base sur des documents existant ou sur des catgories. Par exemple, si un document est accessible au chemin organisation/nexedi, et qu'il existe une catgorie de base client, l'outil portal_categories autorise la cration de la catgorie virtuelle client/organisation/nexedi. Cela permet de reprsenter un lien relationnel selon le schma : le client de tel objet est l'organisation Nexedi . Le concept de la virtualisation des catgories vite la duplication des informations en offrant des mcanismes quivalent une base de donne relationnelle.
3.3. Intgrons notre structure de donnes dans ERP5
Nous allons ajouter dans ERP5 toutes les classes d'objets que nous avons dfinies dans le paragraphe prcdent. ERP5 possde des mcanismes propres pour dfinir de nouvelles classes d'objets, ce qui lui permet de prendre en charge la cration dynamique et automatise de mthodes. Le travail de cration de nouvelles classes se limite donc les dcrire, ERP5 se chargera du reste, comme la cration dynamique des "setter" et "getter". Les classes d'objets se dfinissent via un script python dans le dossier Document de l'instance Zope/ERP5. Nous allons crer une nouvelle classe PaySheetTransaction, et pour viter de ressaisir tout le code, faire une copie du fichier Invoice.py que nous diterons :
[root@localhost /]# cd /usr/lib/zope/lib/python/Products/ERP5/Document/ [root@localhost Document]# cp Invoice.py / var/lib/zope/Document/PaySheetTransaction.py [root@localhost Document]# vi /var/lib/zope/Document/PaySheetTransaction.py () [root@localhost Document]# chown zope:zope / var/lib/zope/Document/PaySheetTransaction.py [root@localhost Document]# chmod 755 / var/lib/zope/Document/PaySheetTransaction.py
Voici ce quoi doit ressembler le fichier PaySheetTransaction.py aprs dition :
page 21/64
Tut o r i e l N e x e d i ERP5
from AccessControl import ClassSecurityInfo from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface from Products.ERP5.Document.Invoice import Invoice class PaySheetTransaction(Invoice): """ A paysheet will store data about the salary of an employee """ meta_type = 'ERP5 Pay Sheet Transaction' portal_type = 'Pay Sheet Transaction' add_permission = Permissions.AddPortalContent isPortalContent = 1 isRADContent = 1 # Declarative security security = ClassSecurityInfo() security.declareObjectProtected(Permissions.View) # Default Properties property_sheets = ( PropertySheet.Base , PropertySheet.SimpleItem , PropertySheet.CategoryCore , PropertySheet.Task , PropertySheet.Arrow , PropertySheet.Delivery , PropertySheet.Movement , PropertySheet.Amount , PropertySheet.XMLObject , PropertySheet.PaySheetTransaction ) # Declarative Interface __implements__ = ( )
3.4. Web Dveloppement rapide avec portal_classes
Il est possible de raliser l'ensemble des oprations de cration de classes ou d'dition du code via l'interface Web d'ERP5 grce l'outil portal_classes :
page 22/64
Tut o r i e l N e x e d i ERP5
L'dition de code python d'une classe ERP5 permet galement de recharger chaud le seul code modifi, sans redmarrer Zope et de gagner en productivit.
L'outil portal_classes est trs utile en phase de prototypage ou de dveloppement rapide. Il facilite galement l'apprentissage d'ERP5. Il est cependant dconseill de l'activer sur un systme en production car il comporte des risques levs en matire de scurit. Aussi est-il dsactiv par dfaut dans le LiveCD ERP5 ou dans les paquetages ERP5 pour Mandrakelinux. Pour l'activer, il est donc ncessaire de crer un fichier vide ALLOW_CLASS_TOOL dans le rpertoir du produit ERP5Type.
page 23/64
Tut o r i e l N e x e d i ERP5
3.5. Structure d'une classe Document dans ERP5
Les fichiers de type Document ont gnralement la mme allure, et les valeurs propres notre nouvelle classe se devinent facilement. Toujours dans le dossier de l'instance Zope/ERP5, PropertySheet sert contenir des scripts python similaires ceux que l'on trouve dans le dossier PropertySheet du produit ERP5. Ces scripts aux noms vocateurs permettent de dfinir des attributs de classes et, par extension, le schma de donnes d'ERP5. Les classes y font souvent rfrence grce la liste property_sheets, comme on peut le voir dans le code python prcdent. Ainsi pour que chaque feuille de paye puisse stocker le salaire brut ("gross salary" en anglais), nous avons fait rfrence la property sheet PaySheetTransaction qui contiendra la dfinition de l'attribut gross_salary de type flottant. Il nous faut maintenant la crer :
[root@localhost [root@localhost [root@localhost () [root@localhost [root@localhost /]# cd /var/lib/zope/PropertySheet/ PropertySheet]# touch PaySheetTransaction.py PropertySheet]# vi PaySheetTransaction.py PropertySheet]# chown zope:zope PaySheetTransaction.py PropertySheet]# chmod 755 PaySheetTransaction.py
Voici le contenu de la property sheet PaySheetTransaction.py :
class PaySheetTransaction: """ Properties for PaySheet Transaction objects """ _properties = ( { 'id' , 'description' paysheet' , 'type' , 'mode' }, ) _categories = ( , , , ) : 'gross_salary' : 'This variable contain the gross salary of the : 'float' : 'w'
'source' 'destination' 'source_section' 'destination_section'
La syntaxe est assez intuitive car tous les attributs se dclarent par une liste de dictionnaires python dans la variable _properties. Il convient juste de faire attention aux listes immuables (tuple) un lement en python et ne pas oublier la virgule avant la parenthse de fin.
page 24/64
Tut o r i e l N e x e d i ERP5
[kevin@localhost Products]$ python Python 2.3.3 (#2, Feb 17 2004, 11:45:40) [GCC 3.3.2 (Mandrake Linux 10.0 3.3.2-6mdk)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> (5) 5 >>> (5,) (5,) >>> (5,10) (5, 10) >>>
Ainsi (5) est interprt comme l'entier 5, et (5,) comme une liste immuable contenant un seul lment entier gal 5. La liste _categories contient la liste des catgories virtuelles. Nous utiliserons celles-ci pour crer un lien entre la feuille de paie, l'employeur et le salari. La relation source_section fera rfrence l'employeur (qui est l'organisation ou l'entreprise qui met la feuille de paie) et la relation destination_section fera rfrence au salari (la personne qui se destine la feuille de paie). Si plus tard nous avons besoin de dfinir des attributs plus complexes, nous nous inspirerons des PropertySheets pr-existante dans le produit ERP5. Cette mthode est valable pour tous les points abord dans cet article : puisque le code source est ouvert, il ne faut pas se priver de rutiliser ou de s'inspirer de choses existantes pour construire petit petit des choses nouvelles. C'est mme un obligation pour contribuer au code d'ERP5 : deux proprits similaires doivent, par principe, avoir le mme nom dans ERP5. Maintenant que notre nouvelle classe est construite, il est ncessaire soit de recharger son code (avec portal_classes sur la classe de PropertySheet puis sur la classe de Document) soit de redmarrer le serveur Zope pour qu'il puisse les prendre en compte. Si tout ce passe bien le serveur sera disponible et vous pourrez accder la ZMI :
[root@localhost kevin]# zopectl program: /usr/bin/runzope program running; pid=4450 zopectl> restart . daemon process restarted, pid=4773 zopectl> logtail -----2004-05-12T18:50:03 INFO(0) Z2 Caught signal SIGTERM -----2004-05-12T18:50:03 INFO(0) Z2 Shutting down fast -----2004-05-12T18:50:03 INFO(0) ZServer closing HTTP to new connections -----2004-05-12T18:50:03 INFO(0) ZServer closing FTP to new connections -----page 25/64
Tut o r i e l N e x e d i ERP5
2004-05-12T18:50:03 INFO(0) Zope Shutting down with exit code 0 () -----2004-05-12T18:50:42 INFO(0) Zope Ready to handle requests zopectl>
Il est possible qu'au moment du redmarrage, Zope s'arrte et refuse obstinment de dmarrer. Il est aussi possible d'observer un comportement trange de Zope : l'arrt et le dmarrage en boucle du serveur par priodes de 10 secondes. Les causes de ce blocage sont lies dans la majorit des ca de mauvaises permissions sur les scripts ou une mauvaise attribution de la proprit des fichiers que vous venez de crer. Une srie de chmod et chown rglera ce problme. Si malgr ces corrections le problme persiste, il zopectl intgre une commande debug, qui lorsqu'on l'appelle va arrter le serveur et le dmarrer en vous affichant le log de dmarrage et un rapport d'excution (traceback) en cas d'erreur. Par exemple :
[root@localhost kevin]# zopectl program: /usr/bin/runzope daemon manager not running zopectl> debug Starting debugger (the name "app" is bound to the top-level Zope object) () Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.3/site-packages/PIL/__init__.py", line 50, in app File "/usr/lib/python2.3/site-packages/PIL/__init__.py", line 46, in startup File "/usr/lib/zope/./build/build-base/python-2.3/buildlib/Zope/App/startup.py", line 45, in startup File "/usr/lib/zope/./build/build-base/python-2.3/buildlib/OFS/Application.py", line 631, in import_products File "/usr/lib/zope/./build/build-base/python-2.3/buildlib/OFS/Application.py", line 654, in import_product File "/usr/lib/zope/lib/python/Products/ERP5/__init__.py", line 50, in ? from Tool import Category, CategoryTool, SimulationTool, RuleTool, IdTool, TemplateTool, TestTool File "/usr/lib/zope/lib/python/Products/ERP5/Tool/Category.py", line 35, in ? from Products.ERP5.Document.MetaNode import MetaNode File "/usr/lib/zope/lib/python/Products/ERP5/Document/__init__.py", line 3145, in ? import PaySheetTransaction as ERP5PaySheetTransaction File "/usr/lib/zope/lib/python/Products/ERP5/Document/PaySheetTransaction.py", line 62
page 26/64
Tut o r i e l N e x e d i ERP5
__implements__ = ( ) ^ SyntaxError: invalid syntax >>>
Le traceback nous apprend qu'il y a une erreur invalid syntax dans le fichier / usr/lib/zope/lib/python/Products/ERP5/Document/PaySheetTransaction.py, ligne 62. En ditant le dit fichier on s'aperoit en fait que le malheureux dveloppeur a oubli de fermer la liste property_sheets avec une parenthse. Il nous suffira dans ce cas que d'une petite correction pour pouvoir relancer le serveur zope Attention : pour utiliser la commande debug il ne faut pas oublier de mettre on l'option debug-mode du fichier /etc/zope.conf. Il n'est d'ailleurs pas surprenant de devoir utiliser debug 30 fois par jour lorsque l'on dbute et que l'on ne matrise pas la syntaxe de python, ou lorsque l'on travaille sur le CVS d'un projet ERP5 en quipe et que des conflits surgissent. Selon le mme principe nous avons construit les nouveaux types
PaySheetTransactionLine, PaySheetLine et PaySheetCell. Par curiosit on pourra
aller consulter les classes pythons qui les dfinissent :
[root@localhost [root@localhost [root@localhost [root@localhost /]# cd /usr/lib/zope/lib/python/Products/ERP5/Document/ Document]# vi PaySheetTransactionLine.py Document]# vi PaySheetLine.py Document]# vi PaySheetCell.py
Le lecteur attentif aura sans doute remarqu ici que le code du module de paye est parfois situ dans le dossier /usr/lib/zope/lib/python/Products/ERP5/Document/ et parfois dans le dossier /var/lib/zope/Document. Une explication s'impose. Le dossier /var/lib/zope/Document est conu pour le dveloppement rapide de code d'extension au framework ERP5. C'est donc bien dans ce dossier qu'il faut commencer travailler lorsque l'on conoit un nouveau jeu de classes pour un client ou pour une future extension d'ERP5. Si ce jeu de classes semble suffisamment gnrique et susceptible de correspondre une fonction universelle d'un ERP, il est conseill de l'intgrer au projet ERP5 afin de le partager avec l'ensemble de la communaut. C'est bien le cas de la paye. En revanche, si ce jeu de classes est li un mtier ou aux besoins spcifiques d'une entreprise, il n'y a aucune raison de l'intgrer au coeur d'ERP5. La paye faisant dsormais partie du coeur d'ERP5, il nous arrivera souvent de mentionner des fichiers situs dans le dossier Document du produit ERP5. Cependant, pour les besoins du tutoriel, nous crerons tous les nouvelles classes dans les dossiers de l'instance Zope/ERP5, c'est--dire gnralement /var/lib/zope.
3.6. Crer un Module dans EPR5
Lors de l'introduction de ce chapitre nous avons fait l'amalgame entre les
page 27/64
Tut o r i e l N e x e d i ERP5
Business Templates et les modules de l'ERP. Nous allons maintenant faire la diffrence et dcrire plus prcisment le rle d'un module, au sens d'ERP5, puis en crer un. Un module est simplement un lieu dans l'interface utilisateur d'ERP5 ou se rassemblent les fonctionnalits propres un aspect de la gestion d'entreprise. Le Business Template contient tous les scripts et objets qui permettent de faire fonctionner le module. D'o l'amalgame. La cration rapide d'un nouveau module peut tre effectue en allant l'URL :
http://localhost:9480/erp5/ERP5Site_viewCreateModuleDialog
o apparat le dialogue suivant :
Ce dialogue comporte 6 paramtres :
Module Id : l'id du dossier (Folder) cr la racine du site ERP5 et qui contiendra l'ensemble des feuilles de paye. Module Portal Type : le nom du type documentaire qui sera cr pour contenir toutes les feuilles de paye Module Title : le titre qui apparatra dans le menu modules pour le module de paye Object Portal Type : le nom du type documentaire qui sera cr pour dfinir les feuilles de paye Object Title : le titre qui apparatra par dfaut pour chaque feuille de paye Portal Skins Folder : le dossier dans lequel seront crs les formulaires par dfaut
En cliquant sur "Create Module", tous les types documentaires sont
page 28/64
Tut o r i e l N e x e d i ERP5
automatiquement crs et les menus mis jour. Un module de paye "vide" vient d'tre cr. Il s'agit dsormais de le paramtrer.
3.7. Intgrer les classes, donnes, menus et prsentation : l'outil portal_types
ERP5 est conu autour de l'architecture Zope/CMF. L'une des caractristiques du CMF est le concept d'outil (tool en anglais) plac la racine d'un portail et conu pour fournir divers services : traduction de formats de documents, gestion des menus associs un document, internationalisation, synchronisation, etc. L'outil portal_types permet de crer des types gnriques de document sur la base de nos classes dfinies dans la partie prcdente et de leur associer des menus ainsi que des lments de prsentation. Nous ferons la distinction par la suite entre portal_types (l'outil) et les portal types (les types de document dfinis par l'outil portal_types). Le contenu de l'outil portal_types correspond aux modules et aux types documentaires disponibles dans l'instance ERP5.
Pour rsumer on peut dire que tous nos portal types du genre PaySheet* sont des images dans Zope de nos classes dfinies par nos scripts python. La ralit est plus subtile car ils peut y avoir deux portal types diffrents qui se basent sur la mme classe, car leur rle premier est de crer des types
page 29/64
Tut o r i e l N e x e d i ERP5
documentaires. Par exemple depuis une mme classe DocumentEcrit nous pouvons crer deux portal types diffrents : Article et CommuniquDePresse. Les deux se dcrivent par la mme structure de donnes et les mmes proprits. L'intrt de crer deux types de documents est que nous pouvons appliquer chaque type un workflow diffrent ou une mise en page adapte.
3.8. L'interface utilisateur avec ERP5Form
Nous allons exploiter ici les capacits de RAD (environnement de dveloppement rapide) d'ERP5 via le produit ERP5Form, afin de dfinir l'interface utilisateur de notre module. ERP5Form est le gnrateur de formulaires d'ERP5. Il est driv de Formulator, un produit Zope cr par Infrae. Lorsque nous allons dans le module de paye, nous pouvons ajouter des PaySheetTransaction :
Cependant, notre action se termine sur une erreur :
page 30/64
Tut o r i e l N e x e d i ERP5
Or, la mthode de cration d'une nouvelle feuille de paie bien fonctionn comme l'atteste la prsence dans la ZODB d'une nouvelle instance du portal type Pay Sheet Transaction qui t cre dans le dossier paysheet du module :
Il ne s'agit donc que d'un problme de prsentation. Pour le rsoudre, nous devons ajouter une interface utilisateur la feuille de paie pour que l'action de cration n'aboutisse pas sur une erreur lorsque elle tente d'afficher l'objet cr. Nous allons donc crer un nouveau formulaire. Comme tous les formulaires et les autres objets de prsentation, ils sont dfinis dans des sous-dossiers de l'outil portal_skins. Allons par exemple dans le dossier /erp5/portal_skins/local_erp5.
page 31/64
Tut o r i e l N e x e d i ERP5
Un formulaire se cre comme n'importe quel objet zope via la ZMI : il suffit de choisir le type "ERP5 Form". Appelons notre formulaire PaySheetTransaction_view :
Commenons pour l'diter par lui ajouter un champ de type float pour reprsenter le salaire brut :
Pour indiquer implicitement que ce champ correspond l'attribut gross_salary de notre objet, il suffit de le nommer my_gross_salary :
page 32/64
Tut o r i e l N e x e d i ERP5
L'utilisation du prfixe my_ est une des rgles de nommage propre ERP5. Si un champ de formulaire est nomm my_quelque_chose, il affichera par dfaut une valeur obtenue en appelant la mthode getQuelqueChose sur le document auquel il est appliqu. En cas de validation du formulaire, la mthode setQuelqueChose sera appele sur le document auquel le formulaire a t appliqu pour mettre jour la valeur de la proprit quelque_chose. Pour tre complet, il faut galement configurer le formulaire pour que le salaire brut puisse tre modifi en dfinissant la proprit Form action comme sur la capture d'cran :
L'action "Base_edit" est appele lorsque l'on valide le formulaire et prend en compte les donnes saisies par l'utilisateur pour mettre jour le document auquel le formulaire est appliqu. Pour tester que notre formulaire fonctionne, appelons directement depuis l'url :
page 33/64
Tut o r i e l N e x e d i ERP5
http://localhost:9080/erp5/paysheet/1/PaySheetTransaction_view
Afin que ce formulaire soit utilis par dfaut pout afficher les feuilles de paie, retournons dans l'outil portal_types. Allons dans l'onglet action du portal type correspondant la feuille de paie. On peut alors dfinir une nouvelle action :
Le choix de la catgorie "object_view" Le choix de l'id "view" correspond nous ajoutons une nouvelle feuille de module de paye, le formulaire va information de salaire brut :
correspond la notion d'onglet dans ERP5. l'affichage par dfaut. Dsormais, lorsque paie depuis le menu droulant Actions du tre automatiquement affich avec une
Notons ici que les deux URL :
http://localhost:9080/erp5/paysheet/2/view
et
http://localhost:9080/erp5/paysheet/2/PaySheetTransaction_view
page 34/64
Tut o r i e l N e x e d i ERP5
donnent le mme rsultat en raison de l'association de PaySheetTransaction_view l'id view dans les actions du portal_type. Il peut tre intressant ce stade de tester quelques URL typiques d'ERP5 afin de bien comprendre la notion d'accesseur. Par exemple, le fait d'avoir dfini dans la PropertySheet de feuille de paye une proprit "gross_salary" a entrain la gnration automatique par ERP5 d'une mthode "getGrossSalary". Cette mthode peut tre teste directement en appelant une URL adquate sur la feuille de paye :
http://localhost:9080/erp5/paysheet/2/getGrossSalary
Cette URL affiche dans le navigateur la valeur de forme de chane de caractre.
gross_salary convertie sous
En utilisant les proprits du formulaire et des champs qui le constituent, on peu obtenir rapidement un formulaire plus dvelopp et plus utile. On commence par ajouter des champs pour chaque proprit que l'on souhaite grer avec le formulaire :
Illustration 4: De nouveaux champs pour chaque attribut de l'objet
L'onglet "Order" permet de regrouper les champs et dfinir leur prsentation :
page 35/64
Tut o r i e l N e x e d i ERP5
Illustration 5: Utilisation de groupes pour la reprsentation du formulaire
Le style ERP5 par dfaut utilise 4 groupes : left (ou Default), right, center et bottom. Nous n'avons pour l'instant utilis que les deux premiers groupes qui se traduisent par un affichage sur 2 colonnes :
Illustration 6: Le formulaire vu par l'utilisateur
Ajoutons maintenant deux champs qui permettent d'associer la feuille de paie l'employeur et au salari. Avant cela il est indispensable d'installer le Business Template CRM, qui permet de grer les personnes et les organisations, en suivant la mthode explique en premire partie. Une fois install, nous pouvons nous occuper des relations.
page 36/64
Tut o r i e l N e x e d i ERP5
Les champs ajouter sont de type RelationStringField :
Nous ajouterons deux champs de ce type, my_destination_section_title permettra de saisir le salari qui la feuille de paie est destine et my_source_section_title l'employeur qui met la feuille de paie :
page 37/64
Tut o r i e l N e x e d i ERP5
Il faut ensuite modifier les proprits des deux widgets pour qu'ils puissent fonctionner :
Comme on peut le deviner avec les captures prcdentes, Base Category permet d'indiquer la catgorie de base sur laquelle la relation s'appuie. Souvenez-vous galement que cette catgorie t explicitement dclare dans la property sheet adquate, justement pour pouvoir tre utilise cet endroit. La relation d'employeur est maintenant dfinissable par une catgorie virtuelle de la forme source_section/organisation/nexedi. On peut vrifier la bonne intgration des donnes en appelant directement le getter de l'attribut sur l'objet, et ce depuis l'url :
http://localhost:9080/erp5/paysheet/2/getSourceSection
Pour comprendre comment ces informations sont gres par ERP5, il peut tre utile d'appeler la mthode Base_viewDict qui permet d'inspecter le contenu des objets enregistrs dans la ZODB :
http://localhost:9080/erp5/paysheet/2/Base_viewDict
La proprit Portal Type de ce type de widget permet quand elle de spcifier les types d'objets qui seront accepts comme relation par le champ. On retrouvera cette proprit dans diffrents widgets du produit Formulator. Ensuite, la valeur donner aux autres proprits de ce type de champ sont assez intuitives.
page 38/64
Tut o r i e l N e x e d i ERP5
Nous nous retrouvons ainsi avec un formulaire qui se rapproche de sa forme finale :
De
existe une action view relie au formulaire PaySheetTransaction_view dfinie dans le portal type Pay Sheet Transaction, il existe une action view sur le portal type du module qui par dfaut est Folder_list :
mme
qu'il
Nous allons crer notre propre formulaire PaySheetModule_view qui va nous servir l'affichage par dfaut du contenu du module. Pour cela il nous faut changer les actions du module et crer un nouveau formulaire :
page 39/64
Tut o r i e l N e x e d i ERP5
Ce formulaire n'a besoin de contenir qu'un seul widget de type ListBox :
page 40/64
Tut o r i e l N e x e d i ERP5
Toujours par convention, nous l'appellerons listbox. Les List Box sont trs flexibles et nous allons les utiliser pour afficher un rsum du contenu du module de feuille de paie. La capture d'cran suivante vous montre les proprits de la List Box :
D'un point de vue utilisateur, ce formulaire aura le look suivant :
page 41/64
Tut o r i e l N e x e d i ERP5
Les proprits importantes d'une List Box sont List Action et List Method. Cette dernire prend la valeur portal_catalog, pour indiquer que la mthode utilise pour la gnration de la liste se base sur le catalogue. La proprit Colum,s permet de dfinir l'ordre et les donnes des colonnes de la liste. Le reste des proprits permet de grer un comportement avanc de la liste, comme le tri, la slection de lignes, le filtrage, etc. Nous ne nous attarderons pas dessus, et je vous laisse le soin d'explorer les possibilits offertes par ERP5Form. Cela devrait tre assez facile car les noms des proprits sont assez transparents et peuvent tre compris par des tests et essais.
page 42/64
Tut o r i e l N e x e d i ERP5
3.9. Les scripts python de calcul
L'tape suivante consiste crer un script qui, depuis le salaire brut, produit toutes les donnes de la feuille de paie. Pour cela nous crons un nouveau script python que nous nommerons PaySheetTransaction_calcul :
Nous mettons galement jour les actions du portal type des Pay Sheet Transaction pour qu'il prenne en compte notre script :
page 43/64
Tut o r i e l N e x e d i ERP5
En donnant la valeur object_action l'attribut Category, on ajoute une entre dans le menu d'action de la vue des Pay Sheet Transaction :
Le script tant vide, il ne va forcement rien se passer si on slectionne Calcul dans la liste des actions. Maintenant il va nous falloir coder le script pour qu'il : rcupre les donnes suffisante (salaire brut, employeur, etc), calcule les taux et les assiettes et distribue les montants selon les bonnes catgories et aux bons organismes sociaux. Les points 1 et 2 ne ncessitent pas d'explication particulires, en dehors de la connaissance fine de la mthode de calcul des montants. Nous allons ce propos simplement gnrer quelques lignes de feuilles de paies titre d'exemple. Le troisime et dernier point requiert quelques explications. Nous allons dtailler le comportement de la Structure PaySheetLine / PaySheetCell du point de vue du dveloppeur. Les cellules peuvent tre reprsentes comme des tableaux ou des matrices repres par deux catgories de base : assiette et categorie_taxe. Pour illustrer notre propos, prenons l'assurance vieillesse (les taux sont ceux d'avril 2003). La part salariale est gale la valeur du salaire plafonn multiplie par 6.55%. La part patronale est gale la somme de 1.60% du salaire brut et de 8.20% du salaire plafonn. Voici la reprsentation de ces chiffres au sein de la PaySheetLine pour un salaire de 3000 euros :
page 44/64
Tut o r i e l N e x e d i ERP5
Les objets sont identifis par un cadre rouge et leurs attributs les plus significatifs sont nots l'intrieur. La cotisation "Assurance vieillesse" est reprsente par une PaySheetLine qui contient une matrice de 4 cellules de type PaySheetCell. Puisque les catgories et les catgories de base se dfinissent au niveau de la PaySheetLine, cette dernire va tre capable de gnrer automatiquement le tableau de cellules sa cration. De ce fait nous n'avons plus qu' choisir notre cellule selon les catgories et lui affecter ses valeurs. Une cellule possde deux attributs : quantity et price. quantity reprsente l'assiette et price le taux. Pour calculer le montant, il suffit d'invoquer getTotalPrice() qui effectuera la multiplication quantity * price. L'assurance vieillesse est une sous-partie des cotisations de scurit sociale, et pour reprsenter cette hirarchie nous avons cr la sous catgorie secu. Cette dernire se subdivise en part salariale et en part employeur pour rpartir finement les montants. Puisque l'assurance vieillesse est calcule partir du salaire brut et du salaire plafonn, nous avons cr les sous-catgories correspondantes dans la catgorie de base assiette. Une bonne dfinition des catgories nous permettras par la suite de gnrer facilement des rapports dtaills. Puisque dans le script nous allons gnrer les cotisations d'assurance maladie, d'assurance vieillesse et d'assurance chmage, voici les catgories que nous avons ajoutes dans l'outil portal_category :
categorie_taxe categorie_taxe/secu categorie_taxe/secu/part_employeur categorie_taxe/secu/part_salariale categorie_taxe/chomage categorie_taxe/chomage/part_employeur categorie_taxe/chomage/part_salariale
page 45/64
Tut o r i e l N e x e d i ERP5
assiette assiette/salaire_brut assiette/salaire_plafonne assiette/tranche_a assiette/tranche_b assiette/tranche_c
Voici donc le script python qui gnrera les quelques lignes de feuilles de paie :
# Ce script est donn titre d'exemple # Les constantes ont t codes en dur pour faciliter la lecture global paysheet paysheet paysheet_type paysheet_cell_type paysheet_transactionline_type = = = = context.getObject() paysheet.getPortalType() 'Pay Sheet Cell' 'Pay Sheet Transaction Line'
employer = paysheet.getSourceSection() employee = paysheet.getDestinationSection() if employer in ('', None): return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employer+is+required') if employee in ('', None): return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employee+is+required') employer_object = paysheet.getSourceSectionValue() if employer_obj.getDefaultAddress().getZipCode() in ('', None): return context.REQUEST.RESPONSE.redirect(context.absolute_url() + '?portal_status_message=The+employer+must+have+a+zip+code') gross_salary = abs(paysheet.getGrossSalary()) employer_region = employer_object.getDefaultAddress().getZipCode()[:2] # limited salary = salaire plafonn if gross_salary < 2432: limited_salary = gross_salary else: limited_salary = 2432 # "Char" slice type if gross_salary <= 2432: char_slice = 'A' elif gross_salary <= 9728: char_slice = 'B' elif gross_salary <= 19456:
page 46/64
Tut o r i e l N e x e d i ERP5
char_slice = 'C' else: char_slice = '' ######################################################################### # This part of the script implement functions to register all pay sheet # informations from an ERP5 point of view. ######################################################################### def createPaySheetItem(title='', dest_org='', cells=[]): global paysheet # get all variation categories used in cells var_cat_list = [] for cell in cells: var_cat_list.append(cell["x"]) var_cat_list.append(cell["y"]) # add a new Pay Sheet Line payline = paysheet.newContent( portal_type = 'Pay Sheet Line' , title = title , destination = dest_org , variation_base_category_list = ('tax_category', 'salary_range') , variation_category_list = var_cat_list ) # fill each cell with values for cell in cells: paycell = payline.getCell(cell["x"], cell["y"], base_id = 'movement') paycell.edit(quantity=-cell["base"], price=cell["rate"]/100.0) ######################################################################### # This part of script describe the behaviour of the calculation process # from accountant point of view. ######################################################################### # social organism org_urssaf = 'organisation/urssaf' org_assedic = 'organisation/assedic' # variation categories cat_social_salary_share cat_social_employer_share cat_unemployment_salary_share cat_unemployment_employer_share cat_gross_salary cat_limited_salary cat_slice_a cat_slice_b cat_slice_c = = = = = = = = = 'tax_category/social/salary_share' 'tax_category/social/employer_share' 'tax_category/unemployment/salary_share' 'tax_category/unemployment/employer_share' 'salary_range/france/salaire_brut' 'salary_range/france/salaire_plafonne' 'salary_range/france/tranche_a' 'salary_range/france/tranche_b' 'salary_range/france/tranche_c'
# sickness insurance = assurance maladie if employer_region in ('57', '67', '68'):
page 47/64
Tut o r i e l N e x e d i ERP5
salary_share_rate else: salary_share_rate createPaySheetItem( , ,
= 1.70 = 0.75 title = 'Assurance maladie' dest_org = org_urssaf cells = [ { "x" : cat_social_salary_share , "y" : cat_gross_salary , "base" : gross_salary , "rate" : salary_share_rate }, { "x" : cat_social_employer_share , "y" : cat_gross_salary , "base" : gross_salary , "rate" : 12.80 } ] = assurance vieillesse title = 'Assurance vieillesse' dest_org = org_urssaf cells = [ { "x" : cat_social_salary_share , "y" : cat_limited_salary , "base" : limited_salary , "rate" : 6.55 }, { "x" : cat_social_employer_share , "y" : cat_gross_salary , "base" : gross_salary , "rate" : 1.60 }, { "x" : cat_social_employer_share , "y" : cat_limited_salary , "base" : limited_salary , "rate" : 8.20 } ]
) # old-age insurance createPaySheetItem( , ,
) # unemployment insurance = assurance chomage if char_slice in ('A', 'B'): if char_slice == 'A': cat_slice = cat_slice_a else: cat_slice = cat_slice_b createPaySheetItem( title = 'Assurance chomage' , dest_org = org_assedic , cells = [ { "x" : cat_unemployment_salary_share , "y" : cat_slice , "base" : gross_salary , "rate" : 2.4 }, { "x" : cat_unemployment_employer_share , "y" : cat_slice
page 48/64
Tut o r i e l N e x e d i ERP5
, "base" : gross_salary , "rate" : 4.0 } ] )
Si votre diteur prfr supporte le protocole WebDAV, n'oubliez pas que Zope le supporte galement. En d-commentant quelques lignes dans le fichier / etc/zope.conf et aprs un redmarrage de Zope, WebDAV sera activ et vous pourrez naviguer au sein de la ZODB puis diter trs facilement des script python dans votre environnement de dveloppement favori.
Illustration 7: Utilisation de WebDAV avec KATE
Avant de tester le script, n'oublier pas de crer les organisations Assedic et Urssaf avec le mme id qui est utilis dans le script (organisation/urssaf et organisation/assedic) pour qu'il puisse fonctionner.
page 49/64
Tut o r i e l N e x e d i ERP5
3.10. Le reporting
Nous allons voir dans cette partie comment utiliser les donnes gnres par notre script pour crer des rapports et les versions imprimable des feuilles de paie. Ces dernires seront produites au travers d'une Page Template que l'on crera dans local_erp5 sous le nom de PaySheetTransaction_print :
Les page templates ne sont en fait que de simples fichiers html (ou xml) dans lesquels nous allons utiliser des attributs spciaux dans les balises. Ce langage nomm TAL (Template Attribute Language) propre Zope permet de dcrire un comportement dynamique des pages. ERP5 intgre d'ailleurs un script qui permet de convertir automatiquement un document OpenOffice en TAL afin de faciliter la cration rapide de rapports PDF. Dans le cas de notre feuille de paie, nous allons crer un script python qui va se charger de pr-formater les donnes de la feuille de paie et nous allons l'appeler depuis la Page Template. Le script, que nous appellerons PaySheetTransaction_getDetails, va se charger essentiellement de collecter les part patronale et salariale pour chacune des taxe et les rassembler dans un dictionnaire :
# this dict contain all paysheet details
page 50/64
Tut o r i e l N e x e d i ERP5
paysheet_details = {} # initialize the employee and total_employee_share total_employer_share total_taxable_employee_share employer share total = 0.0 = 0.0 = 0.0
# get the gross salary gross_salary = context.getGrossSalary() if gross_salary == None: gross_salary = 0.0 paysheet_cat = {} object_list = [] for object in context.objectValues(): object_list += [object] # Sort the list by id since lines are already ordered by id. object_list.sort(lambda x, y: cmp(int(x.getId()), int(y.getId()))) for pay_sheet_line in object_list: variation_list = pay_sheet_line.getVariationCategoryList() range_variation = [] for variation in variation_list: if variation.find('salary_range')==0: if not variation in range_variation: # Extra checking because # get VariationCategoryList returns # the same 1 items 2 times range_variation += [variation] for range in range_variation: pay_sheet_dict = {} #pay_sheet_dict['range']=range[range.rfind('/')+1:] pay_sheet_dict['id'] = pay_sheet_line.getId() pay_sheet_dict['title'] = pay_sheet_line.getResourceTitle() for cell in pay_sheet_line.objectValues(): predicate_list = cell.getMembershipCriterionCategoryList() if range in predicate_list: pay_sheet_dict['base_name'] = context.portal_categories.resolveCategory(range).getTitleOrId() for predicate in predicate_list: if cell.getTotalPrice() != 0: if predicate.find('employee_share')>=0: pay_sheet_dict['base']= - cell.getQuantity() pay_sheet_dict['employee_share'] = cell.getTotalPrice() pay_sheet_dict['employee_share_rate'] = cell.getPrice() * 100 total_employee_share += float(-pay_sheet_dict ['employee_share']) # here we decide if a resource is taxable or not if str(pay_sheet_line.getResource())[-14:] == 'non_deductible' or str(pay_sheet_line.getResource())[-4:] == 'crds' or str (pay_sheet_line.getResource())[-7:] == 'taxable': pay_sheet_dict['taxable']='yes' elif str(pay_sheet_line.getResource())[-10:] == 'deductible': pay_sheet_dict['taxable']='no' else: pay_sheet_dict['taxable']='no'
page 51/64
Tut o r i e l N e x e d i ERP5
if pay_sheet_dict['taxable'] == 'yes': total_taxable_employee_share += float(-pay_sheet_dict ['employee_share']) elif predicate.find('employer_share')>=0: pay_sheet_dict['base'] = - cell.getQuantity() pay_sheet_dict['employer_share'] = cell.getTotalPrice() pay_sheet_dict['employer_share_rate'] = cell.getPrice() * 100 total_employer_share += float(-pay_sheet_dict ['employer_share']) for key in ('employee_share','employee_share_rate','employer_share','employer_share_rat e'): if not (pay_sheet_dict.has_key(key)): pay_sheet_dict[key]='' # so that we can display nothing # find the category of the current pay sheet line cat_id = None cat_path = None for var in variation_list: sub_cat = var.split('/') if sub_cat[0] == 'tax_category': cat_id = sub_cat[1] cat_path = sub_cat[0] + '/' + sub_cat[1] break if cat_id == None: cat_id = 'no_cat' # add the current pay sheet line to its category if not paysheet_cat.has_key(cat_id): paysheet_cat[cat_id] = {} paysheet_cat[cat_id]['lines'] = [] if cat_path != None: paysheet_cat[cat_id]['title'] = context.portal_categories.resolveCategory(cat_path).getTitleOrId() paysheet_cat[cat_id]['lines'].append(pay_sheet_dict) # get all paysheet transaction to calculate the sum of different value in a year accounting_folder = context.aq_parent paysheet_transactions = accounting_folder.contentValues(filter= {'portal_type':'Pay Sheet Transactionss'}) # initialize every yearly variable yearly_net_salary = 0.0 yearly_gross_salary = 0.0 yearly_employee_share = 0.0 yearly_employer_share = 0.0 yearly_taxable_net_salary = 0.0 # get the current paysheet start date and employee start_date = context.getStartDate() from DateTime import DateTime start_date = DateTime("%i/01/01" % start_date.year()) stop_date = context.getStopDate() employee = context.restrictedTraverse (context.getDestinationSectionRelativeUrl())
page 52/64
Tut o r i e l N e x e d i ERP5
#start_date = start_date.strftime('%Y-%m-%d') #stop_date = start_date.strftime('%Y-%m-%d') #yearly_employee_share = -float (context.PaySheetTransaction_zGetDetailedTotal (start_date=start_date,stop_date=stop_date,tax_category='employee_share') [0].total) #yearly_employer_share = -float (context.PaySheetTransaction_zGetDetailedTotal (start_date=start_date,stop_date=stop_date,tax_category='employer_share') [0].total) yearly_employee_share = 0 yearly_employer_share = 0 try: yearly_employer_share = -float (context.PaySheetTransaction_zGetDetailedTotal (start_date=start_date,stop_date=stop_date,tax_category='employer_share') [0].total) except: pass # browse through paysheet transaction for paysheet_obj in paysheet_transactions: # ignore the current paysheet to avoid infinite loop if paysheet_obj.getId() != context.getId(): # the paysheet must have the same employee if (employee==None) or (employee!=None and context.restrictedTraverse (paysheet_obj.getDestinationSectionRelativeUrl())==employee): # check the date if (start_date==None) or (start_date!=None and paysheet_obj.getStartDate()!=None and start_date.year() ==paysheet_obj.getStartDate().year() and paysheet_obj.getStartDate()<= start_date): # get all detailed values of the paysheet ps_details = paysheet_obj.PaySheetTransaction_getDetails() # sum of yearly values yearly_net_salary += float(ps_details['net_salary']) yearly_gross_salary += float(ps_details['gross_salary']) yearly_employee_share += float(ps_details ['total_employee_share']) yearly_employer_share += float(ps_details ['total_employer_share']) yearly_taxable_net_salary += float(ps_details ['taxable_net_salary']) # save the total share values in the exported dict paysheet_details['net_salary'] = gross_salary total_employee_share paysheet_details['gross_salary'] = gross_salary paysheet_details['paysheet_categories'] = paysheet_cat paysheet_details['total_employee_share'] = total_employee_share paysheet_details['taxable_net_salary'] = paysheet_details ['net_salary'] + total_taxable_employee_share paysheet_details['total_employer_share'] = total_employer_share
page 53/64
Tut o r i e l N e x e d i ERP5
paysheet_details['total_taxable_employee_share'] total_taxable_employee_share # don't forget to add the current values to the paysheet_details['yearly_net_salary'] = paysheet_details['net_salary'] paysheet_details['yearly_gross_salary'] = paysheet_details['gross_salary'] paysheet_details['yearly_employee_share'] = paysheet_details['total_employee_share'] paysheet_details['yearly_employer_share'] = paysheet_details['total_employer_share'] paysheet_details['yearly_taxable_net_salary'] = paysheet_details['taxable_net_salary'] return paysheet_details
= yearly sum yearly_net_salary + yearly_gross_salary + yearly_employee_share + yearly_employer_share + yearly_taxable_net_salary +
Une premire version de notre Page Template pourrait ressembler ceci :
VPN Nexedi VPN List | Nature | Assiette | Montant | Taux part patronale | Part patronale | Taux part salariale | Part salariale |
| Salaire brut |
page 54/64
Tut o r i e l N e x e d i ERP5
| | | | | ??? |
| | | | | | | |
| | | | | | | |
| | | | |
page 55/64
Tut o r i e l N e x e d i ERP5
| | |
| Total des cotisations | | | | | | |
| Salaire Net | | | | | | |
| | | | | | |
page 56/64
Tut o r i e l N e x e d i ERP5
|
| Salaire Net Imposable | | | | | | |
| Salaire brut | Cotisations salariales | Salaire net | Net imposable | Part patronale | | |
| | | |
page 57/64
Tut o r i e l N e x e d i ERP5
| | | |
Ajoutons ensuite une action dans le portal type des Pay Sheet Transaction avec la valeur object_print pour category :
Grce cette petite manipulation il nous reste plus qu' cliquer sur l'icne de l'imprimante dans la vue d'une feuille de paie pour rcuprer la version imprimable :
La Page Template sera appele dans le contexte actuel et la feuille de paie imprimable s'affichera l'cran sous forme de document PDF :
page 58/64
Tut o r i e l N e x e d i ERP5
Illustration 8: Une feuille de paie gnre par ERP5
La technologie employe pour le rendu PDF est reportlab. Il s'agit d'une bibliothque crite en python, utilise par des tablissements financiers prestigieux et capable de gnrer plusieurs centaines de pages PDF par minute sur un serveur bas de gamme.
page 59/64
Tut o r i e l N e x e d i ERP5
3.11. La cration du business template
Maintenant que le module fonctionne dans son ensemble, nous allons le rassembler au sein d'un Business Template pour pouvoir le distribuer et l'installer facilement. La procdure de cration d'un Business Template est assez rapide si on connat exactement toutes les composantes qui sont ncessaire au bon fonctionnement du module que l'on veut packager. Il faut d'abord nous rendre dans l'outil portal_templates et ajouter un nouveau Business Template en utilisant le menu "Action". Nous appellerons ce Business Template erp5_payroll et allons maintenant l'diter et lister dans les diffrents champs les objets qui doivent tre inclus :
http://localhost:9080/erp5/portal_templates/GestionDesSalaires/view
Les champs renseigns sont :
id : L'id du Business Template Name : le nom du Business Template, qui doit tre unique pour chaque groupe de fonctionnalits Portal Types : la liste des types documentaires dfinis par le Business Template Skin Folders : le dossier dans portal_skins o sont stocks les lments de prsentation
page 60/64
Tut o r i e l N e x e d i ERP5
Base Categories : les catgories et relations ncessaires au fonctionnement du module Paths : des documents ncessaires au fonctionnement du module (ici, les organisations URSSAF, etc, ncessaires au calcul de la paye)
Maintenant que le Businnes Template connat toutes les composantes de notre module, nous pouvons construire le Business Template via l'action "Build Business Template" du menu "Action" puis l'export via l'action "Export Busines Template" du mme menu. On peut ds prsent tester notre nouveau Business Template sur une nouvelle instance de Zope pour s'assurer que notre module fonctionne avant de le distribuer.
page 61/64
Tut o r i e l N e x e d i ERP5
3.12. Le point sur la catalogage
Le catalogage est en fait un moyen de stocker certaines information d'un objet (comme sont ID, titre, description, etc) dans une base de donne annexe. Le catalogue permet de slectionner instantanment des objets sans reparcourir toute la base objet de Zope. Il permet d'effectuer des requtes rapides sur des bases de grande taille. Nexedi a par exemple dploy un systme contenant plus de 2.000.000 de documents et plus de 10 000 000 d'enregistrements de catalogue. La technologie de catalogue dveloppe par Nexedi pour ERP5 se nomme "ZSQL Catalog". C'est un produit zope qui permet d'effectuer des requtes SQL sans limite de complexit sur un catalogue dont la structure est elle-mme adaptable sans limites. L'objectif est de constituer un catalogue selon un modle d'indexation susceptible d'offrir des temps de rponse trs courts. L'approche est similaire celle utilise par les moteurs OLAP ou le datawarehousing pour le traitement statistiques de donnes consolides.
page 62/64
Tut o r i e l N e x e d i ERP5
4. Conclusion
Nous avons appris dans cet article installer une plateforme ERP5 et ses modules grce au systme de Business Template d'ERP5. Nous avons ensuite cr une version simpliste du module de feuille de paie qui existe dj dans ERP5. Il existe beaucoup de diffrences entre ces deux versions. En particulier, le module de paye d'ERP5 repose sur le moteur de planification d'ERP5 afin de permettre des prvisions de trsorerie. Cependant, la structure de donne et les principes de base restent les mmes. Nous pouvons dsormais exploiter ERP5 pour construire en un temps record un ERP fonctionnel capable de grer un grand nombre d'aspects d'une entreprise ou d'une organisation. La bibliothque actuelle de Business Template, qui est appele croitre et s'enrichir, offre la fois des briques de base et une source d'inspiration. Si toutefois les Business Template existants ne rpondent pas votre besoin, vous disposez dsormais des bases ncessaire pour crer les votres. Dans ce cas n'oubliez pas de partager avec nous vos crations sur le site web www.erp5.org et sur les mailing-list erp5-dev et erp5-user.
page 63/64
Tut o r i e l N e x e d i ERP5
5. TODO
Amliorations envisager sur ce document. Question se poser: * faut-il supprimer certaines parties trop dtaille ? (variantage, category, construction des classes) * indiquer les conventsion de nommage utilises par ERP5 * crer avec le lecteur un nouveau folder dans les portal_skins et lui faire changer les settings pour lui expliquer comment erp5 va chercher les formulaire ? * dire l'utilisateur qu'il est prudent de donner un nom chaque formulaire * ne pas evoquer les paysheet transaction line ? (compression de l'article) TODO: * couper les parties des images qui ne sont pas utiles (surtout celle avec des scrennshot de dropdown list/combo) * mettre en italique les babarismes (getter / setter / packages / etc) ou trouver une version franaise * intgrer une bibliographie/webographie la fin de l'article * intgrer "Lors du dveloppement du vritable Business Template, que vous trouverez dans la section download du site erp5.org, nous n'avons pas eu besoin de crer de module. En ralit le produit final des feuilles de paie est rassembl dans le Business Template Human Resources (HR) qui contient aussi les fonctionnalits de gestion de carrires et s'intgre dans diffrents modules pr-existants (les feuilles de paie dans le module Accounting et la gestion de carrires dans le module Person). " * simplifier les scripts et templates de rapports * mettre jour les recopies d'cran qui mentionnent base_edit, base_update_relation, etc. en utilisant le nouveau nommage (Base_edit, Base_updateRelation, etc.)
page 64/64
%PDF-1.4
%
1 0 obj
<< /Length 2 0 R
/Filter /FlateDecode
>>
stream
xWn7/sLDJ$%`G M]8~Q: z x ?Oƻ/ózQ)}ӽ>~|p翎&t1\iB>Z\NBp/7bI{s{xtWwWWIR* Nh=`11I2hl2*]gsctYV8 o