Questions fréquentes
Comment exécuter OfbizNeogia avec une configuration alternative pour éviter d'avoir à modifier les fichiers de configuration par défaut ?
- Créer un dossier ofbizNeogia/conf/site (il ne peut pas être commité par erreur car il est référencé dans .cvsignore)
- Placer les fichiers de configuration modifiés et les fichiers jars dans ce dossier
- Créer un fichier ofbizNeogia/site.properties qui contient la ligne suivante :
ofbiz.neogia.site.conf=conf/site
Il y a des exemples de configurations alternatives dans le dossier ofbizNeogia/conf :
- ofbiz.neogia.site.conf=conf/portplus1 : configure tous les ports d'écoute à leur valeur par défaut + 1
- ofbiz.neogia.site.conf=conf/postgresql-8.0 : configuration d'ofbizNeogia pour utiliser la base de données postgresql-8.0
Comment faire fonctionner OfbizNeogia sous Eclipse ?
- Sélectionner le projet ofbizNeogia, effectuer un clic-droit dessus -> Run As (Exécuter comme)-> Run (Exécuter)...
- Sélectionner Application Java et cliquer sur New (Nouvelle)
- !! Set Run configuration name to OfbizNeogia !!
- Onglet principal :
- Projet : ofbizNeogia
- Classe principale : org.ofbiz.base.start.Start
- Arguments :
- Arguments VM : -Xms128M -Xmx256M (coller directement cette information dans la zone qui est éditable)
- Répertoire de travail : utiliser par défaut le répertoire de travail
- Cheminement de classe :
- Entrées Amorce : JRE System Library (laisser par défaut)
- Entrées utilisateurs : ofbiz.jar depuis le projet ofbizNeogia (il faut supprimer tous existant et ne mettre que le jar : ofbiz.jar du projet à debugger)
- Environnement :
- Ajouter une variable à l'environnement LC_ALL=C
- Onglet principal :
- Cliquer sur appliquer et exécuter
Vous pouvez également consulter le guide établi en espagnol :
Comment voir quels sont les fichiers modifiés après un rafraîchissement ?
Après avoir rafraîchi un composant, tous ses fichiers générés apparaissent modifiés parce que leur "timbre à date" a changé. Néanmoins, seul un petit sous-ensemble a réellement été modifié. En effectuant une mise à jour cvs au niveau du composant, le "timbre à date" des fichiers inchangés sera réactualisé.
Why some xml files contains validation errors when displayed in Eclipse?
By default, Eclipse looks for xml schema definitions by using the namespaces declared in xml documents which points to www.ofbiz.org. Xml schemas presented on this site don't contain neogia extensions that's why validation errors appear. You can define an XML catalog to force eclipse to look for xml schema on the machine instead of on the net.
- Window menu
- Preferences...
- Web and XML -> XML Catalog
- Click on Advanced...
- Click on Import...
- Select ofbizNeogia/.xmlcatalog
- Preferences...
Change TCP Port
You can find some basic start configuration in the file: {ofbiz.neogia.home}/base/config/ofbiz-containers.xml. On this file you can change the line:
<property name="port" value="8080"/>
You can use any port that you want (of course an unused port).
This works for windows also. Remember that you have to be careful with the port number, for example on linux any port below 1024 requires root priviledges to work.
Comptabilité
Saisie de facture impossible; Le rôle d'acteur n'existe pas
Vous venez de charger les données minimum (seed) vous avez paramétré le centre de profit, les périodes, les comptes comptables, .... et plein d'autres choses. Vous testez votre configuration et dans la comptabilité lors de la saisie d'une facture fournisseur le message d'erreur <<Le rôle d'acteur n'existe pas>> apparait:
Vous avez oublié de modifier dans le fichier AccountingProperties.properties l'ID de l'acteur représentant la société pour lequel vous faite la compta, cet acteur doit avoir le rôle INTERNAL_ORGANIZATION.
Généralités sur les screens et les forms
Dans un form "single", comment ajouter un champs de saisie de donnée ?
- Selon le type de variable à saisir, on dispose de plusieurs balises : <text>, <text-find> <date-find> avec des options sur la taille de la zone de saisie et la taille maximale de la variable. Le <text-find> et le <date-find> permettent de disposer d'opérateurs sur cette variable. Cela sert pour des zones de recherches (les dates entre hier et aujourdh'ui, un nom commençant par Ar, ...).
Dans un form "single", comment positionner le focus dans un des champs ?
- On utilise l'attribut focus-field-name de la balise <form>.
Dans un form "single", comment définir la taille maximale du champs à renseigner ?
- On utilise la balise <text> et son attribut "maxlength".
- Ex:
<field name="productId" title="${uiLabelMap.ProductProductId}"><text maxlength="20" size="20"/></field>
- Pour les champs à renseigner on peut aussi utiliser la balise <text-find> qui permet de disposer d'opérateur sur le champs.
- Ex:
<field name="productId" title="${uiLabelMap.ProductProductId}"><text-find /></field>
Dans un form "single", comment choisir la position des champs ?
- L'attribut "position" permet de répartir les champs dans la zone. On fixe une position au niveau des colonnes par un numéro de 1 au nombre de colonnes désirées. Ainsi, s'il apparait le nombre 3, alors les champs seront répartis sur trois colonnes.
- Ex:
<form name="FindOrder" target="Orders" type="single">
<field name="productId" position="1"><text/></field>
<field name="goodValue" position="2"><text/></field>
<field name="orderId" position="3"><text/></field>
<field name="entryDate" position="1"><date-find/></field>
<field name="submitButton" title="${uiLabelMap.CommonFind}" position="1" widget-style="buttontext">
<submit button-type="text-link"/>
</field>
</form>
- Ainsi les éléments ayant une position à "1" seront alignés verticalement sur la première colonne.
Dans un form "single", comment mettre un champs caché ?
- On utilise la balise <hidden> au niveau du champs.
- Ex:
<field name="orderId"><hidden/></field>
Dans un form list, quels sont les opérateurs disponibles dans le service performFind utilisé pour constituer la liste ?
- and, between, equals, greaterThan, greaterThanEqualTo, in, lessThan, lessThanEqualTo, like, not, notEqual, or.
Dans un form list, comment peut-on charger une liste sans que les critères du performFind aient été entrés ?
- Il suffit de mettre le champs noConditionFind à "Y".
- Ex:
<actions>
<service service-name="performFind" result-map-name="result" result-map-list-name="listIt">
<field-map field-name="inputFields" env-name="requestParameters"/>
<field-map field-name="entityName" env-name="entityName"/>
<set field="noConditionFind" value="Y"/>
<field-map field-name="orderBy" value="shipmentId"/>
<field-map field-name="orderBy" value="dateCreated"/>
</service>
</actions>
Dans un form "list", comment faire pour qu'un champs de la liste affiche non pas la clé mais un autre champs de la table ?
- L'option <display-entity> permet de récupérer un autre champs de la base.
- Ex:
<field name="statusId" title="Nom de statut">
<display-entity entity-name="StatusItem" description="${description}" key-field-name="statusId"/>
</field>
Dans un form "list", comment faire lorsqu'on veut utilisé un display-entity mais que la table a plusieurs clés ?
- Il suffit d'utiliser un <row-actions> dans la form.
- Ex:
<row-actions>
<entity-one entity-name="FacilityLocation" use-cache="true">
<field-map field-name="facilityId" env-name="facilityIdTo"/>
<field-map field-name="locationSeqId" env-name="locationSeqIdTo"/>
</entity-one>
</row-actions>
<field name="locationName" title="${uiLabelMap.WarehouseLocationName}"><display /></field>
Dans un form "list", comment créer un lien pour renvoyer vers une autre uri ?
- On utilise la balise <hyperlink> en renseignant sa target. La target correponds à une request du controller. On peut également passer des paramètres.
- Ex:
<field name="stickerLink" widget-style="buttontext" title="${uiLabelMap.ButtonSticker}">
<hyperlink target="stickerPDF.pdf?orderId=${orderId}&shipmentId=${shipmentId}" description="${uiLabelMap.ButtonSticker}"/>
</field>
Dans un form "list", comment charger les éléments d'un drop-down à partir d'une table ? Comment trier ces éléments ?
- On utilise la balise <entity-options> pour récupérer les données dans la base. On peut aussi appliquer une sélection avec opérateur ou ordonner.
- Ex:
<field name="facilityId" position="1" title="${uiLabelMap.ProductFacility}:" >
<drop-down allow-empty="true">
<entity-options entity-name="Facility" description="${description}" key-field-name="facilityId">
<entity-constraint name="facilityTypeId" operator="equals" value="PICK"/>
<entity-constraint name="facilityId" operator="not-equals" value="MONO"/>
<entity-order-by field-name="description"/>
</entity-options>
</drop-down>
</field>
Dans un form multi, comment utiliser un service dans les listes ?
- Les list multi permettent d'appeler un service pour traiter les informations de la liste. Ce service n'est pas appelé directement mais par le controller. On va donc définir la "target" du form, elle correspondra à une request du controller, qui lui appelera le service.
- Ex:
<form name="ListPickListItem" target="SendPicklistMulti" paginate-target="PickListItem" ....>
- La "target" correspond à une request du controller (elle permet de déclencher un "event", comme par exemple un service), le "paginate-target" correspond à une view du controller (elle appele donc un screen pour afficher la liste dans celui-ci).
Dans un form multi, le retour OUT du service n'est pas pris en compte dans ma list ?
http://neogia.org/Multi_Service
Dans un form "multi", comment faire pour qu'un champs de la liste ne soit envoyé au service ?
- L'attribut also-hidden="false" de <display> permet cela.
- Ex:
<field name="orderDate" title="${uiLabelMap.OrderDate}"><display also-hidden="false" /></field>
Dans un form "multi", comment ajouter des cases à cocher ?
- On ajoute l'attribut use-row-submit="true" dans la balise form. On ajoute ensuite dans les champs un champs "_rowSubmit" avec une balise <check/>.
- Ex:
<form name="ListPickListItem" target="SendPicklistMulti" paginate-target="PickListItem"
type="multi" list-name="listIt" paginate="true" use-row-submit="true">
<actions>
<service service-name="performFind" result-map-name="result" result-map-list-name="listIt" >
<field-map field-name="inputFields" env-name="requestParameters" />
<field-map field-name="entityName" env-name="entityName"/>
</service>
</actions>
<field name="_rowSubmit" title="${uiLabelMap.CommonSelect}"><check/></field>
<field name="picklistBinId"><hidden/></field>
<field name="picklistId" title="${uiLabelMap.PicklistId}"><display /></field>
<field name="picklistDate" title="${uiLabelMap.PicklistDate}"><display type="date-hm"/></field>
<field name="submitButton" title="${uiLabelMap.CommonSend}" position="1" widget-style="buttontext">
<submit button-type="text-link"/>
</field>
</form>
Dans un form "multi", comment faire pour que tous les éléments de la liste soient cochés par défaut ?
- L'attribut all-checked de la balise <check> doit être mis à "true".
- Ex:
<form name="ListOrdersMulti" target="SendOrdersMulti" ... use-row-submit="true">
<field name="_rowSubmit" title="${uiLabelMap.CommonSelect}"><check all-checked="true"/></field>
<field name="orderStatusId" title="${uiLabelMap.CommonStatus}">
<display-entity also-hidden="false" entity-name="StatusItem" description="${description}" key-field-name="statusId"/>
</field>
.....
<field name="submitButton" title="${uiLabelMap.CommonSend}" position="1" widget-style="buttontext">
<submit button-type="text-link"/>
</field>
</form>
Dans un form "multi" avec des cases à cocher, comment faire pour qu'une ligne ne soit pas cochable ?
- Il faut pour cela ajouter un champs "_rowSubmit" avec une condition exprimée par un "use-when". Cette solution pose souci car elle provoque un 'trou' dans le tableau. Il faut donc ajouter un deuxième champs "_rowSubmit" avec une condition inverse. Si cette condition porte sur un attribut d'une entité, ce champs doit se trouver dans la liste.
- Ex:
<form name="ListReceive" target="ReceiveIn" paginate-target="ReceiveSelection"
type="multi" list-name="listIt" paginate="true" use-row-submit="true">
<field name="facilityId"><hidden /></field>
<field name="_rowSubmit" title="${uiLabelMap.CommonSelect}" use-when="! "PICK".equals( "${facilityId}" )"><check/></field>
<field name="_rowSubmit" title="${uiLabelMap.CommonSelect}"
use-when=" "STOCK".equals( "${facilityId}" )"><display/></field>
<field name="quantity" entry-name="qtyToReceive" title="${uiLabelMap.CommonQty}"
use-when="! "BIG_P".equals( "${facilityId}" )"><text size="2" /></field>
<field name="orderId" title="${uiLabelMap.OrderOrderId}"><display /></field>
<field name="productId" title="${uiLabelMap.ProductProductId}">
<display description="<a onClick="showDetail('ShowProduct','productId', '${productId}')">${productId}</a>"/>
</field>
<field name="orderDate" title="${uiLabelMap.OrderDate}"><display type="date-hm"/></field>
<field name="submitButton" title="${uiLabelMap.CommonSend}" widget-style="buttontext"><submit /></field>
</form>
Dans un screen, comment récupérer des informations dans une table ?
- On utilise les balises <entity-one>, <entity-and> et <entity-condition>.
Ex:
- Ex: Dans le cas où on dispose de la clé primaire on utilise <entity-one>
<entity-one entity-name="Product" value-name="product"> <field-map field-name="productId"/> </entity-one>
- Ex: Lorsqu'on récupère plusieurs enregistrement, on utilise <entity-and>. La liste peut être utilisé directement dans un form en renseignant l'attribut "list-name" avec le nom de la liste.
<entity-and list-name="lOrderItem" entity-name="OrderItem"> <field-map field-name="orderId"/> </entity-and>
- Ex: On peut aussi exprimer des contraintes avec <entity-condition>.
<entity-condition list-name="lInvent" entity-name="InventoryItem" >
<condition-list combine="and">
<condition-expr field-name="productId" env-name="productId"/>
<condition-expr field-name="quantityOnHandTotal" operator="greater-equals" value="1"/>
</condition-list>
</entity-condition>
Dans un screen, comment faire pour afficher un form ou un screen selon une variable récupérer dans les paramètres ?
- On utilise la balise <condition> avec plusieurs autres balises servant d'opérateur : <not>, <if-empty>, <if-compare>, <if-has-permission>, ...
<screen ...>
<actions>
....
<set field="productId" from-field="parameters.productId"/>
</actions>
<widgets>
<container>
<section>
<condition><not><if-empty field-name="productId"/></not></condition>
<widgets>
<include-form-ftl name="Features" location="component://warehouse/widget/warehouse/WarehouseForms.xml"/>
</widgets>
<fail-widgets>
<include-screen name="OrderStock"/>
</fail-widgets>
</section>
</container>
</widget>
</screen>
Freemarker (*.ftl)
Comment faire pour appeler un service dans un fichier .ftl ?
Exemple :
<#assign pageTotal = dispatcher.runSync("getTotalAmountForAdvancedGlEntry", Static["org.ofbiz.base.util.UtilMisc"].toMap("trItIdName",
'${transaction.idName}' , "trTyIdName", '${transactionType.idName}', "userLogin", userLogin))/>
Comment lire une map ?
- Afficher le contenu complet de ma map
${entryMaps["entryMap${i}"]}
- Prendre un élément d'une liste contenue dans la map
${entryMaps["entryMap${i}"]["bonDyns"][0].description?if_exists}
Afficher une valeur au format 0,00
Test si la variable contient une valeur, si oui, on applique le formatage. Il n'est pas possible de combiner ?if_exists et ?string...
<#if pageTotal["amounts"].ChargeAchatCol_Charge_Achat_1?has_content>${monthTotal["amounts"].ChargeAchatCol_Charge_Achat_1?string(",##0.00")}
Boucle finie
- Avec un itérateur
<#list 1..30 as i >
<fo:block>${i}</fo:block>
</#list>
- Sur une liste
<#list nomDeListe as item >
<fo:block>${item.champ}</fo:block>
</#list>
XSL-FO pour générer des fichiers au format pdf via FOP
Liste de liens
Les balises du language XSL-FO
RenderX - XSL FO Features Test: Demo Code
Extensible Stylesheet Language (XSL) Version 1.1
Tuteur XSL-FO -- XSL-FO tutorial
Using XSL-FO to create printable documents


