ERP en LOGICIEL LIBRE dédié aux PME-PMI

           Devenez partenaire Principal ou Majeur de Neogia

Questions fréquentes

Contents

Comment exécuter OfbizNeogia avec une configuration alternative pour éviter d'avoir à modifier les fichiers de configuration par défaut ?

  1. Créer un dossier ofbizNeogia/conf/site (il ne peut pas être commité par erreur car il est référencé dans .cvsignore)
  2. Placer les fichiers de configuration modifiés et les fichiers jars dans ce dossier
  3. 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 :


Comment faire fonctionner OfbizNeogia sous Eclipse ?

  1. Sélectionner le projet ofbizNeogia, effectuer un clic-droit dessus -> Run As (Exécuter comme)-> Run (Exécuter)...
  2. Sélectionner Application Java et cliquer sur New (Nouvelle)
  3.  !! 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
  4. 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.


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 Services

L'appel du service renvoie l'erreur :
" EventHandlerException: Service invocation error (null) "
ou
"org.ofbiz.service.GenericServiceException: Specified object is null (null)"

Cette erreur peut se produire lorsqu'un service n'est pas déclaré conformément à sa classe.
Par exemple s'il n'est pas déclaré en "static". Au lieu de

public Map nomService(DispatchContext ctx, Map context)


Il faut faire:

public static Map nomService(DispatchContext ctx, Map context)

groovy

appel d'un service, avec remplissage du context

   trainingActionContext = dctx.makeValidContext("updateTrainingAction", "IN", context);
   trainingActionContext.startDate = startDate;
   trainingActionContext.completionDate = completionDate;
   resultMap = dispatcher.runSync("updateTrainingAction", trainingActionContext);
   if ( ServiceUtil.isError(resultMap) ) return resultMap;

java

Résoudre Type safety: Unchecked cast from Object to List

Il faut utiliser la method UtilGenerics.checkList(xxx

nettoyer le cache manuellement

Généralités sur les screens et les forms

Dans un form "single", comment ajouter un champs de saisie de donnée ?

Dans un form "single", comment positionner le focus dans un des champs ?

Dans un form "single", comment définir la taille maximale du champs à renseigner ?

 <field name="productId" title="${uiLabelMap.ProductProductId}"><text maxlength="20" size="20"/></field> 
 <field name="productId" title="${uiLabelMap.ProductProductId}"><text-find /></field> 

Dans un form "single", comment choisir la position des champs ?

 <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>

Dans un form "single", comment mettre un champs caché ?

 <field name="orderId"><hidden/></field>

Dans un form list, quels sont les opérateurs disponibles dans le service performFind utilisé pour constituer la liste ?

 <form name="ListExamples" type="list" list-name="listIt" paginate-target="FindExample" default-entity-name="Example" separate-columns="true"
       odd-row-style="alternate-row" header-row-style="header-row-2" default-table-style="basic-table hover-bar">
       <actions>
           <set field="notExamples[]" value="EX01" />
           <set field="notExamples[]" value="EX03"/>
           <set field="parameters.exampleId_fld0_op" value="not-in"/>
           <set field="parameters.exampleId_fld0_value" from-field="notExamples" type="List"/>
           <service service-name="performFind" result-map="result" result-map-list="listIt">
               <field-map field-name="inputFields" from-field="exampleCtx"/>
               <field-map field-name="entityName" value="Example"/>
               <field-map field-name="orderBy" from-field="parameters.sortField"/>
               <field-map field-name="viewIndex" from-field="viewIndex"/>
               <field-map field-name="viewSize" from-field="viewSize"/>
           </service>
       </actions>

Dans un form list, comment peut-on charger une liste sans que les critères du performFind aient été entrés ?

 <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 ?

       <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 ?

     <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 ?

 <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 ?

 <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 ?

 <form name="ListPickListItem" target="SendPicklistMulti" paginate-target="PickListItem" ....>
   <request-map uri="updateTrainingActionPartyAssMulti">
       <security https="true" auth="true"/>
       <event type="service-multi" invoke="updateTrainingActionPartyAss"/>
       <response name="success" type="request" value="json"/>
       <response name="error" type="request" value="json"/>
   </request-map>

, 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 ?

 <field name="orderDate" title="${uiLabelMap.OrderDate}"><display also-hidden="false" /></field>

Dans un form "multi", comment ajouter des cases à cocher ?

 <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 ?

 <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 ?

 <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 ?

Ex: 
 <entity-one entity-name="Product" value-name="product">
   <field-map field-name="productId"/>
 </entity-one>
 <entity-and list-name="lOrderItem" entity-name="OrderItem">
   <field-map field-name="orderId"/>
 </entity-and>
 <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 ?

<screen ...>
  <actions>
    ....
    <set field="productId" from-field="parameters.productId"/>
  </actions>
  <widgets>  
    <container>
      
    </container>
  </widget>
</screen>

A quoi sert le global="true" dans le set

Par défaut, les variables créer dans un screen, une form ou un menu sont visible uniquement au niveau où elles sont créé (le screen, la form ou le menu). Cela permet de garantir une indépendance d'usage, global=true permet de la définir au niveau du plus niveau (souvent le screen qui utilise le ou les decorator, les form, ...), attention elle n'est disponible que pour les instructions se trouvant après.
Dans les decorators il faut souvent utiliser le global="true" pour pouvoir les utiliser au niveau des forms

Dans un screen ou un form, comment comparer avec la valeur null ?

Dans le contexte, la variable "null" permet de réaliser ce genre de comparaison en utilisant la balise "env-name".

<entity-condition list-name="listIt"  entity-name="SiriusScreenProductWithStock">
 <select-field field-name="productId"/>
 <select-field field-name="facilityId"/>
 <select-field field-name="internalName"/>
 <select-field field-name="locationSeqId"/>
 <select-field field-name="quantity"/>
 <condition-list combine="and">
   <condition-expr field-name="productId" operator="equals" env-name="requestParameters.productId" ignore-if-empty="true"/>
   <condition-expr field-name="locationSeqId" operator="equals" env-name="requestParameters.locationSeqId" ignore-if-empty="true"/>
   <condition-expr field-name="facilityId" operator="in" env-name="facilitiesList"/>
   <condition-expr field-name="quantityOnHandTotal" operator="not-equals" value="0" ignore-if-empty="true"/>
   <condition-expr field-name="quantityOnHandTotal" operator="not-equals" env-name="null"/>
 </condition-list>
 <order-by field-name="productId"/>
 <order-by field-name="facilityId"/>
 <order-by field-name="locationSeqId"/>
</entity-condition>

Dans un screen ou un form, comment créer une liste d'éléments ?

Il y a plusieurs méthodes. Ceci permet de charger une liste :

 <set field="facilitiesList[]" value="BIG_P"/>
 <set field="facilitiesList[]" value="VERTICAL_P"/>
 <set field="facilitiesList[]" value="NOT_EXPECTED_B"/>

Mais on peut aussi utiliser le bsh pour créer et charger la liste :

 <set field="facilityTypeList" value="${bsh: import org.ofbiz.base.util.UtilMisc; UtilMisc.toList("WAREHOUSE","STOCK")}" type="List"/>

Dans un screen ou une form, comment récupérer une liste utilisable en provenance d'un submit de form ?

Il est possible d'utiliser les capacités du service handler du controller, pour cela il faut déclarer un service avec un ou des paramètres de type list avec un suffix

 <attribute name="statusList" type="List" mode="IN" optional="true" string-list-suffix="Status"/>

Dans la form de départ (celle qui sera submitté) tous les contenu des variables qui doivent se retrouver dans la liste, doivent avoir en nom de variable des noms avec le suffix donné dans le service.

Il y a la même chose pour les Map (prefix)

Dans l'addon TCM (et surement dans un addon dédié ou directement OFBiz, dans le futur) il y a un java qui peut être utilisé en tant que service qui transfert les paramètres d'entrés en paramètres de sortie. Donc dans le service créé on l'utilisera :

 <service name="createStatusList" engine="java" location="org.ofbiz.tcm.TcmUtil" invoke="convertParamType" auth="true">

Dans le controller, l'entrée renverra sur le screen souhaité où les variables souhaités seront disponible.

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 ?

${entryMaps["entryMap${i}"]}
${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

<#list 1..30 as i >
    <fo:block>${i}</fo:block>
</#list>
<#list nomDeListe as item >
    <fo:block>${item.champ}</fo:block>
</#list>

Affichage date au format jj/mm/aaaa

${dateEdition?string("dd/MM/yyyy")}

XSL-FO pour générer des fichiers au format pdf via FOP

Ecrire un texte vertical

On crée un block-container de la taille voulue et on indique via reference-orientation l'orientation du texte. Dans ce block-container, il ne reste plus qu'à mettre un block standard contenant le texte.

<fo:block-container width="30mm" height="4mm" reference-orientation="90">
   <fo:block text-align="center" font-size="8pt">Mon texte vertical</fo:block>
</fo:block-container>

Nettoyage des logs

Les tableaux

Si message de ce style :

INFO  [LayoutManager] table-layout="fixed" and width="auto", but auto-layout not supported => assuming width="100%"

Dans la déclaration du tableau, mettre :

<fo:table table-layout="fixed" width="100%">

Liste de liens

Tutoriel renderx

les paragraphes

XSL-FO généralités

[XSL-FO sur w3schools

Les balises du language XSL-FO

XSL-FO table-row Object

RenderX - XSL FO Features Test: Demo Code

XSL Formatting Objects

Extensible Stylesheet Language (XSL) Version 1.1

XSL-FO Tutorial and Samples

Tuteur XSL-FO -- XSL-FO tutorial

Using XSL-FO to create printable documents

Régions et marges

Messages d'erreurs dans les logs

Les polices

Pour ceux qui générent des PDF via FOP, vous avez dû vous apercevoir que peu de polices étaient disponibles. J'ai donc rajouté dans neogia un certain nombre de polices libres afin de pouvoir avoir un plus grand choix.

Les polices "Liberation" sont maintenant dispo et sont équivalentes à Liberation Sans = Arial, Albany, Helvetica, Nimbus Sans L et Bitstream Vera Sans Liberation Serif = Times New Roman, Thorndale, Nimbus Roman et Bitstream Vera Serif. Liberation Mono = Courier New, Cumberland, Courier, Nimbus Mono L et Bitstream Vera Sans Mono.

pour plus d'infos sur ces polices, voir : http://framablog.org/index.php/post/2007/05/12/Liberation-fonts-polices-libres-de-caractere

De plus, j'ai aussi ajouté la police jGara2, qui est un équivalent de Garamond http://www.janthor.com/jGaramond/index.html

Vous trouverez un aperçu des polices, et aussi de la manière de les appeler pour les utiliser dans vos documents. Media:NewFonts.pdf