Author: nmalin
Date: Sat Jan 28 13:22:55 2017
New Revision: 1780683

URL: http://svn.apache.org/viewvc?rev=1780683&view=rev
Log:
Implemented: Birt Report Builder: an enhancement of the Birt component. Easier 
user possibility of report creation. (OFBIZ-6919)

The concept, you define a report domain related to an entity or a service 
through a master content (master report) and a master search form.
When a high level user create a report on a configured domain, OFBiz prepare an 
instantiation of the master content (flexible report) that permit
to surcharge the search form (recorded dynamically on the content as 
ElectronicText) and prepare a rptDesign skeleton.
The high level user can download the rptDesign to edit it trhough the birt 
editor, with all fields that ofbiz will be load as dataset and when is finish 
upload the result on the content instantiation.
For the end user, he selected the instantiation report, OFBiz display the 
report search from the content instantiation and the submission call birt with 
the search parameters and the linked rptDesign.

The rptDesign file is drive by OFBiz to build the data set by two methods :
 * call the performFind if the domain is related to an entity
 * call the a custom service if the domain is related to a service.
For the last case we need two services, a first who prepare and list available 
fields for search and display. And a second who realize the search.
By convention currently the first service as the same name that the second 
service suffixed by 'PrepareFields'

This commit contains :
 * useful UI to create a new content instance from a master content. List, 
edit, remove a content instance and a simple drop-down to list all instance 
published (ready to use by end user)
 * all services (with the work flexibleReport) to manage a flexible report, 
prepare the rptDesign skeleton, reanalyze the rptDesign uploaded, prepare the 
search form
 * Services interface to define you own search custom method
 * Two examples, one on the entity Exemple and one with the service 
flexibleReportTurnOver. Warning ! there are raw example without a beautiful 
rptDesign so you need to update the rptDesign with the birt editor to display 
something.
Thanks: François Wurmser for initialize this improvement, Jacques and Gil for 
their time to analyze, document and refactor the code

Added:
    ofbiz/trunk/plugins/birt/config/BirtErrorUiLabels.xml
    ofbiz/trunk/plugins/birt/data/BirtMasterData.xml
    ofbiz/trunk/plugins/birt/data/BirtSecurityGroupDemoData.xml
    ofbiz/trunk/plugins/birt/data/BirtTypeData.xml
    ofbiz/trunk/plugins/birt/groovyScripts/report/
    ofbiz/trunk/plugins/birt/groovyScripts/report/PrepareBirtCall.groovy
    ofbiz/trunk/plugins/birt/minilang/
    ofbiz/trunk/plugins/birt/minilang/BirtPermissionServices.xml
    ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/
    
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtMasterReportServices.java
    
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtServices.java
    
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtUtil.java
    
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/ReportDesignGenerator.java
    ofbiz/trunk/plugins/birt/widget/birt/BirtMasterForms.xml
Modified:
    ofbiz/trunk/plugins/birt/config/BirtUiLabels.xml
    ofbiz/trunk/plugins/birt/ofbiz-component.xml
    ofbiz/trunk/plugins/birt/servicedef/services.xml
    ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/BirtWorker.java
    
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/report/servlet/BirtEngineServlet.java
    
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/report/servlet/BirtViewerServlet.java
    
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/webapp/view/BirtViewHandler.java
    ofbiz/trunk/plugins/birt/webapp/birt/WEB-INF/controller.xml
    ofbiz/trunk/plugins/birt/widget/birt/BirtForms.xml
    ofbiz/trunk/plugins/birt/widget/birt/BirtMenus.xml
    ofbiz/trunk/plugins/birt/widget/birt/BirtScreens.xml

Added: ofbiz/trunk/plugins/birt/config/BirtErrorUiLabels.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/config/BirtErrorUiLabels.xml?rev=1780683&view=auto
==============================================================================
--- ofbiz/trunk/plugins/birt/config/BirtErrorUiLabels.xml (added)
+++ ofbiz/trunk/plugins/birt/config/BirtErrorUiLabels.xml Sat Jan 28 13:22:55 
2017
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+          
xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-properties.xsd";>
+    <property key="BirtErrorCannotDetermineDataSource">
+        <value xml:lang="en">Failed to determine data source for report</value>
+        <value xml:lang="fr">La détermination de la source de données à 
échoué</value>
+    </property>
+    <property key="BirtErrorCannotFindUploadedFile">
+        <value xml:lang="en">Could not find uploaded file</value>
+        <value xml:lang="fr">Impossible de trouver le fichier uploadé</value>
+    </property>
+    <property key="BirtErrorCannotLocateReportFile">
+        <value xml:lang="en">Report file cannot be located. It does not exist 
in specified directory.</value>
+        <value xml:lang="fr">Le fichier de rapport n'a pas pu être localisé. 
Il n'existe pas dans le dossier spécifié.</value>
+    </property>
+    <property key="BirtErrorCannotLocateReportFolder">
+        <value xml:lang="en">Report folder cannot be located. Are you sure you 
configured correctly birt.properties for the report folder path?</value>
+        <value xml:lang="fr">Le dossier de stockage des rapports n'a pu être 
localisé. Êtes-vous sûr d'avoir bien configuré birt.properties pour le 
chemin du dossier ?</value>
+    </property>
+    <property key="BirtErrorConversionFieldToBirtFailed">
+        <value xml:lang="en">Failed to convert fieldType to birtType</value>
+        <value xml:lang="fr">Conversion du type de champ en type birt 
échouée</value>
+    </property>
+    <property key="BirtErrorCreatingDefaultSearchForm">
+        <value xml:lang="en">An error happened while creating the display of 
current form.</value>
+        <value xml:lang="fr">Erreur à la création de l'affichage du 
formulaire actuel</value>
+    </property>
+    <property key="BirtErrorCreatingFlexibleReport">
+        <value xml:lang="en">Error while generating report</value>
+        <value xml:lang="fr">Erreur lors de la création du rapport</value>
+    </property>
+    <property key="BirtErrorEntityViewNotExist">
+        <value xml:lang="en">This entity/view name is not valid</value>
+        <value xml:lang="fr">Ce nom de vue/entité n'est pas valide</value>
+    </property>
+    <property key="BirtErrorEntityViewNotFound">
+        <value xml:lang="en">No view entity name found</value>
+        <value xml:lang="fr">Aucun nom de vue/entité n'a été trouvé</value>
+    </property>
+    <property key="BirtErrorNoAttributeFound">
+        <value xml:lang="en">Master workflow attribute not found</value>
+        <value xml:lang="fr">L'attribut de workflow du master n'as pas pu 
être trouvé</value>
+    </property>
+    <property key="BirtErrorNoFlexibleReportToDelete">
+        <value xml:lang="en">No report to delete</value>
+        <value xml:lang="fr">Aucun rapport à supprimer</value>
+    </property>
+    <property key="BirtErrorRetrievingTurnOver">
+        <value xml:lang="en">Error while retrieving turnover 
informations</value>
+        <value xml:lang="fr">Erreur lors de l'accès aux informations liées 
au chiffre d'affaire</value>
+    </property>
+    <property key="BirtErrorRunningPerformFind">
+        <value xml:lang="en">Error running performFind</value>
+        <value xml:lang="fr">Erreur lors de l'exécution du performFind</value>
+    </property>
+    <property key="BirtErrorUnauthorisedCharacter">
+        <value xml:lang="en">Form refused: unauthorised character 
detected</value>
+        <value xml:lang="fr">Formulaire refusé : caractère non 
autorisé</value>
+    </property>
+    <property key="BirtErrorUnexpectedNumberReportToDelete">
+        <value xml:lang="en">Unexpected number of reports selected for 
deletion</value>
+        <value xml:lang="fr">Tentative de suppression d'un nombre inattendu de 
rapports</value>
+    </property>
+</resource>
\ No newline at end of file

Modified: ofbiz/trunk/plugins/birt/config/BirtUiLabels.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/config/BirtUiLabels.xml?rev=1780683&r1=1780682&r2=1780683&view=diff
==============================================================================
--- ofbiz/trunk/plugins/birt/config/BirtUiLabels.xml (original)
+++ ofbiz/trunk/plugins/birt/config/BirtUiLabels.xml Sat Jan 28 13:22:55 2017
@@ -21,6 +21,7 @@
 <resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-properties.xsd";>
     <property key="BirtApplication">
         <value xml:lang="en">Eclipse BIRT Application</value>
+        <value xml:lang="fr">Application Eclipse Birt</value>
         <value xml:lang="ja">Eclipse BIRT 業務</value>
         <value xml:lang="th">Eclipse BIRT Application</value>
         <value xml:lang="zh">Eclipse BIRT应用程序</value>
@@ -41,6 +42,22 @@
         <value xml:lang="zh">开源软件OFBiz的组成部分</value>
         <value xml:lang="zh-TW">開源軟體OFBiz的組成部分</value>
     </property>
+    <property key="BirtConfirmDeleteFlexibleReports">
+        <value xml:lang="en">Are you sure you want to delete all 
reports?</value>
+        <value xml:lang="fr">Voulez-vous vraiment supprimer tous les rapports 
?</value>
+    </property>
+    <property key="BirtDeleteFlexibeReports">
+        <value xml:lang="en">Delete all reports</value>
+        <value xml:lang="fr">Supprimer tous les rapports</value>
+    </property>
+    <property key="BirtDownloadRptDesign">
+        <value xml:lang="en">Download rptdesign file</value>
+        <value xml:lang="fr">Télécharger le fichier rptdesign</value>
+    </property>
+    <property key="BirtEditFlexibleReport">
+        <value xml:lang="en">Edit report</value>
+        <value xml:lang="fr">Modification du rapport</value>
+    </property>
     <property key="BirtErrorFOPRenderingAttachmentForEmail">
         <value xml:lang="en">Error FOP rendering ${birtContentType} attachment 
for email: ${errorString}</value>
     </property>
@@ -88,6 +105,66 @@
         <value xml:lang="fr">Ruptures de stock, pour le nombre de derniers 
mois : </value>
         <value xml:lang="zh">上月脱销的数量</value>
     </property>
+    <property key="BirtFindCompareOperator">
+        <value xml:lang="en"> - Operator - </value>
+        <value xml:lang="fr"> - Opérateur - </value>
+    </property>
+    <property key="BirtFindFieldOptionValue0">
+        <value xml:lang="en"> - Lower bound or equal - </value>
+        <value xml:lang="fr"> - Borne basse ou égal - </value>
+    </property>
+    <property key="BirtFindFieldOptionValue1">
+        <value xml:lang="en"> - Higher bound  - </value>
+        <value xml:lang="fr"> - Borne haute - </value>
+    </property>
+    <property key="BirtFilteringParameters">
+        <value xml:lang="en">Filtering parameters</value>
+        <value xml:lang="fr">Paramètres de filtrage</value>
+    </property>
+    <property key="BirtFlexibleReport">
+        <value xml:lang="en">Flexible Report</value>
+        <value xml:lang="fr">Rapport configurable</value>
+    </property>
+    <property key="BirtFlexibleReportGeneration">
+        <value xml:lang="en">Generate report</value>
+        <value xml:lang="fr">Générer un rapport</value>
+    </property>
+    <property key="BirtFlexibleReportInformation">
+        <value xml:lang="en">Report information</value>
+        <value xml:lang="fr">Informations du rapport</value>
+    </property>
+    <property key="BirtFlexibleReportManagement">
+        <value xml:lang="en">Reports management</value>
+        <value xml:lang="fr">Gestion des rapports</value>
+    </property>
+    <property key="BirtFlexibleReportSuccessfullyDeleted">
+        <value xml:lang="en">The report has been successfully deleted</value>
+        <value xml:lang="fr">Le rapport a été supprimé avec succès</value>
+    </property>
+    <property key="BirtFlexibleReportsSuccessfullyDeleted">
+        <value xml:lang="en">All reports have been successfully deleted</value>
+        <value xml:lang="fr">Tous les rapports ont été supprimés avec 
succès</value>
+    </property>
+    <property key="BirtFlexibleReportSuccessfullyGenerated">
+        <value xml:lang="en">Report has been successfully generated under the 
name: </value>
+        <value xml:lang="fr">Le rapport a été généré avec succès sous le 
nom : </value>
+    </property>
+    <property key="BirtFlexibleRptDesignSuccessfullyUploaded">
+        <value xml:lang="en">Report file successfully uploaded</value>
+        <value xml:lang="fr">Le fichier de rapport a été uploadé avec 
succès</value>
+    </property>
+    <property key="BirtGenericReport">
+        <value xml:lang="en">Use a report</value>
+        <value xml:lang="fr">Utiliser un rapport</value>
+    </property>
+    <property key="BirtManageReports">
+        <value xml:lang="en">Manage reports</value>
+        <value xml:lang="fr">Gérer les rapports</value>
+    </property>
+    <property key="BirtNoKnownFlexibleReport">
+        <value xml:lang="en">You have no report yet</value>
+        <value xml:lang="fr">Vous n'avez aucun rapport pour l'instant</value>
+    </property>
     <property key="BirtOrderReportAllOrderItemsWithDiscountCode">
         <value xml:lang="en">All order items with discount code</value>
         <value xml:lang="fr">Tous les lignes de commandes ayant des codes 
promotionels</value>
@@ -138,6 +215,26 @@
         <value xml:lang="fr">Quatre tableau créés par Birt (Ventes des 3 
derniers mois, Ventes, Ventes par codes promotionels, Demandes par produit) 
nécessitent d'alimenter la base de données d'Inform. décis. (notez aussi la 
nécessaire màj du fichier bi.properties après septembre 2023). Ensuite 
seules les commandes nouvellement approuvées seront prises en compte.</value>
         <value 
xml:lang="zh">4个Birt报告(最近3个月销售、销售、销售订单折扣优æƒ
 ç 
ã€äº§å“éœ€æ±‚)要求提供BI数据库(注意:bi.properites文件需要在2023å¹´9月后进行更新)。只会统计新批准的那些订单。</value>
     </property>
+    <property key="BirtPermissionError">
+        <value xml:lang="en">Birt Permission Error</value>
+        <value xml:lang="fr">Erreur d'autorisation sur le composant 
Birt</value>
+    </property>
+    <property key="BirtSearchFormSuccessfullyOverridde">
+        <value xml:lang="en">The form has been successfully updated</value>
+        <value xml:lang="fr">Le formulaire a bien été mis à jour</value>
+    </property>
+    <property key="BirtSelectFlexibleReport">
+        <value xml:lang="en">Report choice</value>
+        <value xml:lang="fr">Choix du rapport</value>
+    </property>
+    <property key="BirtSelectMasterFlexibleReport">
+        <value xml:lang="en">Choose report topic</value>
+        <value xml:lang="fr">Choix du sujet du rapport</value>
+    </property>
+    <property key="BirtUploadRptDesign">
+        <value xml:lang="en">Upload rptdesign file</value>
+        <value xml:lang="fr">Importer le fichier rptdesign</value>
+    </property>
     <property key="ExampleBirtChartReport">
         <value xml:lang="en">HTML chart report</value>
         <value xml:lang="fr">Graphiques HTML</value>
@@ -154,6 +251,7 @@
     </property>
     <property key="ExampleBirtExamples">
         <value xml:lang="en">BIRT Examples</value>
+        <value xml:lang="fr">Exemples BIRT</value>
         <value xml:lang="ja">BIRT サンプル</value>
         <value xml:lang="th">ตัวอย่าง BIRT</value>
         <value xml:lang="zh">BIRT样例</value>
@@ -161,18 +259,27 @@
     </property>
     <property key="ExampleBirtMail">
         <value xml:lang="en">Send any format through Mail</value>
+        <value xml:lang="fr">Envoyer différents formats par mail</value>
         <value xml:lang="ja">任意の書式をメールで送信する</value>
         <value xml:lang="zh">通过邮件发送任一格式</value>
         <value xml:lang="zh-TW">通過郵件發送任一格式</value>
     </property>
     <property key="ExampleBirtReport">
         <value xml:lang="en">HTML</value>
-        <value xml:lang="zh">HTML</value>
-        <value xml:lang="zh-TW">HTML</value>
     </property>
     <property key="ExampleBirtViewHandler">
         <value xml:lang="en">PDF</value>
-        <value xml:lang="zh">PDF</value>
-        <value xml:lang="zh-TW">PDF</value>
+    </property>
+    <property key="FormFieldTitle_birtContentType">
+        <value xml:lang="en">Birt export format</value>
+        <value xml:lang="fr">Format d'export Birt</value>
+    </property>
+    <property key="FormFieldTitle_reportName">
+        <value xml:lang="en">Report name</value>
+        <value xml:lang="fr">Nom du rapport</value>
+    </property>
+    <property key="FormFieldTitle_writeFilters">
+        <value xml:lang="en">Generate filters in design</value>
+        <value xml:lang="fr">Générer les filtres dans le design</value>
     </property>
 </resource>

Added: ofbiz/trunk/plugins/birt/data/BirtMasterData.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/data/BirtMasterData.xml?rev=1780683&view=auto
==============================================================================
--- ofbiz/trunk/plugins/birt/data/BirtMasterData.xml (added)
+++ ofbiz/trunk/plugins/birt/data/BirtMasterData.xml Sat Jan 28 13:22:55 2017
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<entity-engine-xml>
+    <DataResource dataResourceId="DR_MASTER_EXAMPLE" 
dataResourceTypeId="ELECTRONIC_TEXT" dataTemplateTypeId="FORM_COMBINED" />
+    <ElectronicText dataResourceId="DR_MASTER_EXAMPLE">
+        <textData><![CDATA[<!--default domain form-->
+<form name="${masterContentId}_${contentId}" type="single" 
extends="${masterContentId}" 
extends-resource="component://birt/widget/birt/BirtMasterForms.xml">
+</form>]]>
+        </textData>
+    </ElectronicText>
+    <Content contentId="CTNT_MASTER_EXAMPLE" contentTypeId="REPORT_MASTER"  
dataResourceId="DR_MASTER_EXAMPLE" statusId="CTNT_PUBLISHED" 
contentName="Example" description="Master Content for Example" />
+    <!-- Data retrieval will be done using perform find on entity Example-->
+    <ContentAttribute contentId="CTNT_MASTER_EXAMPLE" attrName="Entity" 
attrValue="Example"/>
+
+    <CustomMethod customMethodId="CM_FB_TURNOVER" 
customMethodTypeId="FLEXIBLE_BIRT" customMethodName="flexibleReportTurnOver" 
description="service to resolve invoice for turnover report domain"/>
+    <DataResource dataResourceId="DR_MASTER_TURNOVER" 
dataResourceTypeId="ELECTRONIC_TEXT" dataTemplateTypeId="FORM_COMBINED" />
+    <ElectronicText dataResourceId="DR_MASTER_TURNOVER">
+        <textData><![CDATA[<!--default domain form-->
+<form name="${masterContentId}_${contentId}" type="single" 
extends="${masterContentId}" 
extends-resource="component://birt/widget/birt/BirtMasterForms.xml">
+</form>]]>
+        </textData>
+    </ElectronicText>
+    <Content contentId="CTNT_MASTER_TURNOVER" customMethodId="CM_FB_TURNOVER" 
contentTypeId="REPORT_MASTER" dataResourceId="DR_MASTER_TURNOVER" 
statusId="CTNT_PUBLISHED" contentName="Turnover" description="Master Content 
for TURNOVER domain" />
+    <!-- Data retrieval will be done using two service call. First the 
contentAttribute Service give the service that will define which data and label 
will be retrieved,
+    and which filter and label are supported by the report design (default 
value will call the second service with "prepareField" suffix).
+    Second, the custom method give the service to retrieve all data in the 
report design.
+    Here : flexibleReportTurnOverPrepareFields (customMethodName + 
"prepareFields") then flexibleReportTurnOver-->
+    <ContentAttribute contentId="CTNT_MASTER_TURNOVER" attrName="Service" 
attrValue="default"/>
+
+</entity-engine-xml>
\ No newline at end of file

Added: ofbiz/trunk/plugins/birt/data/BirtSecurityGroupDemoData.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/data/BirtSecurityGroupDemoData.xml?rev=1780683&view=auto
==============================================================================
--- ofbiz/trunk/plugins/birt/data/BirtSecurityGroupDemoData.xml (added)
+++ ofbiz/trunk/plugins/birt/data/BirtSecurityGroupDemoData.xml Sat Jan 28 
13:22:55 2017
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<entity-engine-xml>
+    <SecurityPermission permissionId="BIRT_ADMIN" description="ALL Birt 
component operations"/>
+    <SecurityPermission permissionId="BIRT_CREATE" description="Create report 
from master"/>
+    <SecurityPermission permissionId="BIRT_UPDATE" description="Update 
operations for reports"/>
+    <SecurityPermission permissionId="BIRT_DELETE" description="Delete 
reports"/>
+    <SecurityPermission permissionId="BIRT_VIEW" description="View and use all 
birt reports"/>
+
+    <SecurityGroup groupId="BIRTADMIN" description="Birt - admin"/>
+    <SecurityGroup groupId="BIRTUSER" description="Birt - user"/>
+
+    <SecurityGroupPermission groupId="BIRTADMIN" permissionId="BIRT_CREATE"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" permissionId="BIRT_UPDATE"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" permissionId="BIRT_DELETE"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" permissionId="BIRT_VIEW"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" permissionId="OFBTOOLS_VIEW"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" 
permissionId="CONTENTMGR_ROLE_VIEW"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" 
permissionId="CONTENTMGR_VIEW"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" 
permissionId="CONTENTMGR_ROLE_CREATE"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" 
permissionId="CONTENTMGR_CREATE"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" 
permissionId="CONTENTMGR_ROLE_UPDATE"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" 
permissionId="CONTENTMGR_UPDATE"/>
+    <SecurityGroupPermission groupId="BIRTADMIN" 
permissionId="CONTENTMGR_DELETE"/>
+
+    <SecurityGroupPermission groupId="BIRTUSER" permissionId="BIRT_VIEW"/>
+    <SecurityGroupPermission groupId="BIRTUSER" permissionId="OFBTOOLS_VIEW"/>
+
+    <SecurityGroupPermission groupId="FULLADMIN" permissionId="BIRT_CREATE"/>
+    <SecurityGroupPermission groupId="FULLADMIN" permissionId="BIRT_UPDATE"/>
+    <SecurityGroupPermission groupId="FULLADMIN" permissionId="BIRT_DELETE"/>
+    <SecurityGroupPermission groupId="FULLADMIN" permissionId="BIRT_VIEW"/>
+    <SecurityGroupPermission groupId="FLEXADMIN" permissionId="BIRT_CREATE"/>
+    <SecurityGroupPermission groupId="FLEXADMIN" permissionId="BIRT_UPDATE"/>
+    <SecurityGroupPermission groupId="FLEXADMIN" permissionId="BIRT_DELETE"/>
+    <SecurityGroupPermission groupId="FLEXADMIN" permissionId="BIRT_VIEW"/>
+</entity-engine-xml>
\ No newline at end of file

Added: ofbiz/trunk/plugins/birt/data/BirtTypeData.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/data/BirtTypeData.xml?rev=1780683&view=auto
==============================================================================
--- ofbiz/trunk/plugins/birt/data/BirtTypeData.xml (added)
+++ ofbiz/trunk/plugins/birt/data/BirtTypeData.xml Sat Jan 28 13:22:55 2017
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<entity-engine-xml>
+    <ContentType contentTypeId="REPORT_MASTER" description="Report Master" />
+    <ContentType contentTypeId="FLEXIBLE_REPORT" description="Report" />
+    <ContentType contentTypeId="RPTDESIGN" description="Birt report 
(.rptDesign) file" />
+    <DataTemplateType dataTemplateTypeId="FORM_COMBINED" description="Form 
widget" extension="xml" />
+
+    <CustomMethodType customMethodTypeId="FLEXIBLE_BIRT" description="Service 
calling from a birt rptDesign file to populate the data source"/>
+    <CustomMethod customMethodId="CM_FB_PERFORM_FIND" 
customMethodTypeId="FLEXIBLE_BIRT" customMethodName="callPerformFindFromBirt" 
description="Generic service to call the standard performFind service from birt 
rptDesign file"/>
+
+    <EnumerationType enumTypeId="FLEXIBLE_BIRT" description="Mime Type Format 
available for flexible birt system"/>
+
+    <Enumeration enumId="FB_ODS" enumTypeId="FLEXIBLE_BIRT" 
description="application/vnd.oasis.opendocument.spreadsheet" sequenceId="01" 
enumCode="LibreOffice Calc (.ods)"/>
+    <Enumeration enumId="FB_ODT" enumTypeId="FLEXIBLE_BIRT" 
description="application/vnd.oasis.opendocument.text" sequenceId="02" 
enumCode="LibreOffice Writer (.odt)"/>
+    <Enumeration enumId="FB_ODP" enumTypeId="FLEXIBLE_BIRT" 
description="application/vnd.oasis.opendocument.presentation" sequenceId="03" 
enumCode="LibreOffice Impress (.odp)"/>
+    <Enumeration enumId="FB_PDF" enumTypeId="FLEXIBLE_BIRT" 
description="application/pdf" sequenceId="04" enumCode="Pdf (.pdf)"/>
+    <Enumeration enumId="FB_PS" enumTypeId="FLEXIBLE_BIRT" 
description="application/postscript" sequenceId="05" enumCode="Postscript 
(.ps)"/>
+    <Enumeration enumId="FB_HTML" enumTypeId="FLEXIBLE_BIRT" 
description="text/html" sequenceId="06" enumCode="Text (.html)"/>
+    <Enumeration enumId="FB_XSLX" enumTypeId="FLEXIBLE_BIRT" 
description="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 
sequenceId="07" enumCode="Excel (.xlsx)"/>
+    <Enumeration enumId="FB_DOCX" enumTypeId="FLEXIBLE_BIRT" 
description="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
 sequenceId="08" enumCode="Word (.docx)"/>
+    <Enumeration enumId="FB_PPTX" enumTypeId="FLEXIBLE_BIRT" 
description="application/vnd.openxmlformats-officedocument.presentationml.presentation"
 sequenceId="09" enumCode="Powerpoint (.pptx)"/>
+    <Enumeration enumId="FB_XLS" enumTypeId="FLEXIBLE_BIRT" 
description="application/vnd.ms-excel" sequenceId="10" enumCode="Excel (.xls)"/>
+    <Enumeration enumId="FB_DOC" enumTypeId="FLEXIBLE_BIRT" 
description="application/vnd.ms-word" sequenceId="11" enumCode="Word (.doc)"/>
+    <Enumeration enumId="FB_PPT" enumTypeId="FLEXIBLE_BIRT" 
description="application/vnd.ms-powerpoint" sequenceId="12" 
enumCode="Powerpoint (.ppt)"/>
+</entity-engine-xml>
\ No newline at end of file

Added: ofbiz/trunk/plugins/birt/groovyScripts/report/PrepareBirtCall.groovy
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/groovyScripts/report/PrepareBirtCall.groovy?rev=1780683&view=auto
==============================================================================
--- ofbiz/trunk/plugins/birt/groovyScripts/report/PrepareBirtCall.groovy (added)
+++ ofbiz/trunk/plugins/birt/groovyScripts/report/PrepareBirtCall.groovy Sat 
Jan 28 13:22:55 2017
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+def birtParameters = [:];
+
+birtParameters.parameters = parameters
+birtParameters.modelElementName = parameters.modelElementName
+birtParameters.userLogin = context.userLogin
+birtParameters.locale = locale
+
+request.setAttribute("birtParameters", birtParameters);
+return "success";

Added: ofbiz/trunk/plugins/birt/minilang/BirtPermissionServices.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/minilang/BirtPermissionServices.xml?rev=1780683&view=auto
==============================================================================
--- ofbiz/trunk/plugins/birt/minilang/BirtPermissionServices.xml (added)
+++ ofbiz/trunk/plugins/birt/minilang/BirtPermissionServices.xml Sat Jan 28 
13:22:55 2017
@@ -0,0 +1,106 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  -->
+
+<simple-methods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+                xmlns="http://ofbiz.apache.org/Simple-Method"; 
xsi:schemaLocation="http://ofbiz.apache.org/Simple-Method 
http://ofbiz.apache.org/dtds/simple-methods.xsd";>
+
+    <simple-method method-name="genericBirtPermission" 
short-description="Generic Service for Birt Permissions">
+        <set field="primaryPermission" value="BIRT"/>
+        <call-simple-method method-name="genericBasePermissionCheck" 
xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/>
+
+        <!-- mainAction based call outs -->
+        <if>
+            <condition>
+                <not>
+                    <if-compare field="hasPermission" value="true" 
type="Boolean" operator="equals"/>
+                </not>
+            </condition>
+            <then>
+                <if>
+                    <!-- view data resource -->
+                    <condition>
+                        <if-compare field="parameters.mainAction" value="VIEW" 
operator="equals"/>
+                    </condition>
+                    <then>
+                        <call-simple-method method-name="viewBirtPermission"/>
+                    </then>
+                    <else-if>
+                        <!-- create data resource -->
+                        <condition>
+                            <if-compare field="parameters.mainAction" 
value="CREATE" operator="equals"/>
+                        </condition>
+                        <then>
+                            <call-simple-method 
method-name="createBirtPermission"/>
+                        </then>
+                    </else-if>
+                    <else-if>
+                        <!-- update data resource -->
+                        <condition>
+                            <if-compare field="parameters.mainAction" 
value="UPDATE" operator="equals"/>
+                        </condition>
+                        <then>
+                            <call-simple-method 
method-name="updateBirtPermission"/>
+                        </then>
+                    </else-if>
+                    <!-- all other actions use main base check -->
+                </if>
+            </then>
+            <else>
+                <log level="info" message="Admin permission found: 
${primaryPermission}_${mainAction}"/>
+            </else>
+        </if>
+
+        <log level="info" message="Permission service [${mainAction} / 
${parameters.contentId}] completed; returning hasPermission = 
${hasPermission}"/>
+        <field-to-result field="hasPermission"/>
+    </simple-method>
+
+    <!-- Birt View Permission -->
+    <simple-method method-name="viewBirtPermission" short-description="Check 
user can view Birt reports">
+        <!-- if called directly check the main permission -->
+        <if-empty field="hasPermission">
+            <set field="primaryPermission" value="BIRT"/>
+            <set field="mainAction" value="VIEW"/>
+            <call-simple-method method-name="genericBasePermissionCheck"
+                                
xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/>
+        </if-empty>
+    </simple-method>
+
+    <!-- Birt Create Permission -->
+    <simple-method method-name="createBirtPermission" short-description="Check 
user can create new Birt report">
+        <!-- if called directly check the main permission -->
+        <if-empty field="hasPermission">
+            <set field="primaryPermission" value="BIRT"/>
+            <set field="mainAction" value="CREATE"/>
+            <call-simple-method method-name="genericBasePermissionCheck"
+                                
xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/>
+        </if-empty>
+        <!-- this is about the same as the VIEW permission; but left as a 
unique service for extending purposes -->
+    </simple-method>
+
+    <!-- Birt Update Permission -->
+    <simple-method method-name="updateBirtPermission" short-description="Check 
user can update existing Birt report">
+        <!-- if called directly check the main permission -->
+        <if-empty field="hasPermission">
+            <set field="primaryPermission" value="BIRT"/>
+            <set field="mainAction" value="UPDATE"/>
+            <call-simple-method method-name="genericBasePermissionCheck"
+                                
xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/>
+        </if-empty>
+    </simple-method>
+</simple-methods>
\ No newline at end of file

Modified: ofbiz/trunk/plugins/birt/ofbiz-component.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/ofbiz-component.xml?rev=1780683&r1=1780682&r2=1780683&view=diff
==============================================================================
--- ofbiz/trunk/plugins/birt/ofbiz-component.xml (original)
+++ ofbiz/trunk/plugins/birt/ofbiz-component.xml Sat Jan 28 13:22:55 2017
@@ -26,7 +26,10 @@ under the License.
 
     <classpath type="dir" location="config"/>
     <entity-resource type="data" reader-name="seed" loader="main" 
location="data/BirtHelpData.xml"/>
-    <entity-resource type="data" reader-name="seed" loader="main" 
location="data/OrderPortletData.xml"/>
+    <entity-resource type="data" reader-name="seed" loader="main" 
location="data/BirtTypeData.xml"/>
+    <entity-resource type="data" reader-name="demo" loader="main" 
location="data/BirtSecurityGroupDemoData.xml"/>
+    <entity-resource type="data" reader-name="demo" loader="main" 
location="data/BirtMasterData.xml"/>
+
     <service-resource type="model" loader="main" 
location="servicedef/services.xml"/>
    
     <webapp name="accounting"

Modified: ofbiz/trunk/plugins/birt/servicedef/services.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/servicedef/services.xml?rev=1780683&r1=1780682&r2=1780683&view=diff
==============================================================================
--- ofbiz/trunk/plugins/birt/servicedef/services.xml (original)
+++ ofbiz/trunk/plugins/birt/servicedef/services.xml Sat Jan 28 13:22:55 2017
@@ -35,8 +35,132 @@ under the License.
         <attribute name="bodyParameters" type="Map" mode="IN" optional="true"/>
         <attribute name="birtParameters" type="Map" mode="IN" optional="true"/>
         <attribute name="birtLocale" type="Locale" mode="IN" optional="true"/>
-        <attribute name="birtContentType" type="String" mode="IN" 
optional="true"></attribute>
+        <attribute name="birtContentType" type="String" mode="IN" 
optional="true"/>
         <attribute name="webSiteId" type="String" mode="IN" optional="true"/>
         <attribute name="body" type="String" mode="OUT" optional="false"/>
     </service>
+
+    <!-- SERVICES FOR REPORTS -->
+    <service name="genericBirtPermission" engine="simple" auth="true"
+            location="component://birt/minilang/BirtPermissionServices.xml" 
invoke="genericBirtPermission">
+        <description>Generic Birt Permission Service; Takes mainAction to 
determine the mode.</description>
+        <implements service="permissionInterface"/>
+    </service>
+
+    <!-- Interfaces -->
+    <service name="createFlexibleReportFromMasterInterface" engine="interface">
+        <attribute name="reportName" type="String" mode="IN" optional="false" 
/>
+        <attribute name="description" type="String" mode="IN" optional="true" 
/>
+        <attribute name="writeFilters" type="String" mode="IN" optional="true" 
/>
+        <attribute name="masterContentId" type="String" mode="IN" 
optional="false" />
+        <attribute name="contentId" type="String" mode="OUT" optional="false" 
/>
+    </service>
+    <service name="prepareFieldsForFlexibleReportInterface" engine="interface">
+        <attribute name="dataMap" type="Map" mode="OUT" optional="false" />
+        <attribute name="fieldDisplayLabels" type="Map" mode="OUT" 
optional="true"/>
+        <attribute name="filterMap" type="Map" mode="OUT" optional="true" />
+        <attribute name="filterDisplayLabels" type="Map" mode="OUT" 
optional="true"/>
+    </service>
+    <service name="searchRecordsForFlexibleReportInterface" engine="interface">
+        <attribute name="reportContext" type="Object" mode="IN" 
optional="false" />
+        <attribute name="records" type="List" mode="OUT" />
+    </service>
+
+    <service name="createFlexibleReport" engine="java" auth="true" 
location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="createFlexibleReport">
+        <description>BIRT report generation</description>
+        <required-permissions join-type="AND"><check-permission 
permission="BIRT_CREATE"/></required-permissions>
+        <attribute name="dataMap" type="Map" mode="IN" optional="false" />
+        <attribute name="fieldDisplayLabels" type="Map" mode="IN" 
optional="true" />
+        <attribute name="filterMap" type="Map" mode="IN" optional="true" />
+        <attribute name="filterDisplayLabels" type="Map" mode="IN" 
optional="true" />
+        <attribute name="writeFilters" type="String" mode="IN" optional="true" 
/>
+        <attribute name="serviceName" type="String" mode="IN" optional="false" 
/>
+        <attribute name="rptDesignName" type="String" mode="IN" 
optional="false" />
+    </service>
+
+    <service name="createFlexibleReportFromMaster" auth="true" engine="java" 
location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="createFlexibleReportFromMaster">
+        <description>Call report generator with appropriate workflow required 
by the given master report</description>
+        <required-permissions join-type="AND"><check-permission 
permission="BIRT_CREATE"/></required-permissions>
+        <attribute name="contentId" type="String" mode="IN" optional="false" />
+        <attribute name="reportName" type="String" mode="IN" optional="false" 
/>
+        <attribute name="description" type="String" mode="IN" optional="false" 
/>
+        <attribute name="writeFilters" type="String" mode="IN" optional="true" 
/>
+        <attribute name="reportContentId" type="String" mode="OUT" 
optional="false"/>
+        <attribute name="textForm" type="String" mode="OUT" optional="false" 
allow-html="any"/>
+    </service>
+    <service name="createFlexibleReportFromMasterEntityWorkflow" engine="java" 
location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="createFlexibleReportFromMasterEntityWorkflow">
+        <description>Create and save in db content, a new report design 
following entity workflow</description>
+        <required-permissions join-type="AND"><check-permission 
permission="BIRT_CREATE"/></required-permissions>
+        <implements service="createFlexibleReportFromMasterInterface"/>
+        <attribute name="entityViewName" type="String" mode="IN" 
optional="false" />
+    </service>
+    <service name="createFlexibleReportFromMasterServiceWorkflow" 
engine="java" location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="createFlexibleReportFromMasterServiceWorkflow">
+        <description>Create and save in db content, a new report following 
service workflow</description>
+        <required-permissions join-type="AND"><check-permission 
permission="BIRT_CREATE"/></required-permissions>
+        <implements service="createFlexibleReportFromMasterInterface"/>
+        <attribute name="serviceName" type="String" mode="IN" optional="false" 
/>
+    </service>
+    <service name="deleteAllFlexibleReports" auth="true" engine="java" 
location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="deleteAllReports">
+        <description>Delete all reports (admin purposes)</description>
+        <required-permissions join-type="AND"><check-permission 
permission="BIRT_DELETE"/></required-permissions>
+    </service>
+    <service name="deleteFlexibleReport" auth="true" engine="java" 
location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="deleteFlexibleReport">
+        <description>Delete a report</description>
+        <required-permissions join-type="AND"><check-permission 
permission="BIRT_DELETE"/></required-permissions>
+        <attribute name="contentId" type="String" mode="IN" optional="false" />
+    </service>
+
+    <service name="prepareFlexibleReportOptionFieldsFromEntity" engine="java" 
location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="prepareFlexibleReportOptionFieldsFromEntity">
+        <description>Get fields corresponding to an entity or view, including 
_op _value and so on depending on type.</description>
+        <required-permissions join-type="AND"><check-permission 
permission="BIRT_CREATE"/></required-permissions>
+        <attribute name="entityViewName" type="String" mode="IN" 
optional="false" />
+        <attribute name="listMultiFields" type="List" mode="OUT" 
optional="false" />
+    </service>
+    <service name="prepareFlexibleReportFieldsFromEntity" engine="java" 
location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="prepareFlexibleReportFieldsFromEntity">
+        <description>prepare maps fields for 
ReportDesignGenerator</description>
+        <required-permissions join-type="AND"><check-permission 
permission="BIRT_CREATE"/></required-permissions>
+        <implements service="prepareFieldsForFlexibleReportInterface"/>
+        <attribute name="modelEntity" mode="IN" type="Object"/>
+    </service>
+
+    <service name="uploadFlexibleReportRptDesign" auth="true" engine="java" 
location="org.apache.ofbiz.birt.flexible.BirtServices" invoke="uploadRptDesign">
+        <description>Upload design-modified rptdesign file</description>
+        <required-permissions join-type="AND"><check-permission 
permission="BIRT_UPDATE"/></required-permissions>
+        <attribute name="dataResourceIdRpt" type="String" mode="IN" 
optional="false" />
+        <attribute name="uploadRptDesign" type="java.nio.ByteBuffer" mode="IN" 
optional="false" />
+    </service>
+
+    <service name="updateFlexibleReportSearchForm" auth="true" engine="java" 
location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="overrideReportForm">
+        <description>Override report form</description>
+        <required-permissions join-type="OR">
+            <check-permission permission="BIRT_CREATE"/>
+            <check-permission permission="BIRT_UPDATE"/>
+        </required-permissions>
+        <attribute name="reportContentId" type="String" mode="IN" 
optional="false" />
+        <attribute name="overrideFilters" type="String" mode="IN" 
optional="true" allow-html="any"/>
+    </service>
+    <service name="prepareFlexibleReportSearchFormToEdit" auth="true" 
engine="java" location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="createFormForDisplay">
+        <description>Prepare from DB report form for display</description>
+        <required-permissions join-type="OR">
+            <check-permission permission="BIRT_CREATE"/>
+            <check-permission permission="BIRT_UPDATE"/>
+        </required-permissions>
+        <attribute name="reportContentId" type="String" mode="IN" 
optional="false" />
+        <attribute name="textForm" type="String" mode="OUT" optional="false" 
allow-html="any"/>
+    </service>
+
+    <!-- Service example for flexible report-->
+    <service name="callPerformFindFromBirt" engine="java" auth="true" 
location="org.apache.ofbiz.birt.flexible.BirtServices" 
invoke="callPerformFindFromBirt" transaction-timeout="7200">
+        <description>Manages performFind calling from Birt. Flexible Report 
from entity workflow. (Default search service)</description>
+        <required-permissions join-type="AND"><check-permission 
permission="BIRT_VIEW"/></required-permissions>
+        <implements service="searchRecordsForFlexibleReportInterface"/>
+    </service>
+    <service name="flexibleReportTurnOver" auth="true" engine="java" 
location="org.apache.ofbiz.birt.flexible.BirtMasterReportServices" 
invoke="turnOver">
+        <description>Service getting data for report. Turnover 
report</description>
+        <implements service="searchRecordsForFlexibleReportInterface"/>
+    </service>
+    <service name="flexibleReportTurnOverPrepareFields" auth="true" 
engine="java" 
location="org.apache.ofbiz.birt.flexible.BirtMasterReportServices" 
invoke="turnOverPrepareFields">
+        <description>Service configuring data for report (works in duo!). 
Turnover report.</description>
+        <implements service="prepareFieldsForFlexibleReportInterface"/>
+    </service>
 </services>

Modified: 
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/BirtWorker.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/BirtWorker.java?rev=1780683&r1=1780682&r2=1780683&view=diff
==============================================================================
--- 
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/BirtWorker.java 
(original)
+++ 
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/BirtWorker.java 
Sat Jan 28 13:22:55 2017
@@ -18,8 +18,12 @@
  
*******************************************************************************/
 package org.apache.ofbiz.birt;
 
+import java.io.File;
+import java.io.IOException;
 import java.io.OutputStream;
+import java.io.StringWriter;
 import java.sql.SQLException;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
@@ -28,6 +32,21 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
+import org.apache.ofbiz.base.util.Debug;
+import org.apache.ofbiz.base.util.GeneralException;
+import org.apache.ofbiz.base.util.UtilGenerics;
+import org.apache.ofbiz.base.util.UtilMisc;
+import org.apache.ofbiz.base.util.UtilProperties;
+import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.base.util.string.FlexibleStringExpander;
+import org.apache.ofbiz.birt.flexible.BirtUtil;
+import org.apache.ofbiz.entity.Delegator;
+import org.apache.ofbiz.entity.GenericValue;
+import org.apache.ofbiz.entity.condition.EntityCondition;
+import org.apache.ofbiz.service.GenericServiceException;
+import org.apache.ofbiz.service.LocalDispatcher;
+import org.apache.ofbiz.service.ServiceUtil;
+import org.apache.ofbiz.webapp.WebAppUtil;
 import org.eclipse.birt.report.engine.api.EXCELRenderOption;
 import org.eclipse.birt.report.engine.api.EngineException;
 import org.eclipse.birt.report.engine.api.HTMLRenderOption;
@@ -38,13 +57,6 @@ import org.eclipse.birt.report.engine.ap
 import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
 import org.eclipse.birt.report.engine.api.PDFRenderOption;
 import org.eclipse.birt.report.engine.api.RenderOption;
-import org.apache.ofbiz.base.util.Debug;
-import org.apache.ofbiz.base.util.GeneralException;
-import org.apache.ofbiz.base.util.UtilGenerics;
-import org.apache.ofbiz.base.util.UtilValidate;
-import org.apache.ofbiz.entity.Delegator;
-import org.apache.ofbiz.security.Security;
-import org.apache.ofbiz.service.LocalDispatcher;
 
 public final class BirtWorker {
 
@@ -55,10 +67,11 @@ public final class BirtWorker {
     private final static String BIRT_IMAGE_DIRECTORY = "birtImageDirectory";
     private final static String BIRT_CONTENT_TYPE = "birtContentType";
     private final static String BIRT_OUTPUT_FILE_NAME = "birtOutputFileName";
+    private static final String resourceError = "BirtErrorUiLabels";
 
     private final static HTMLServerImageHandler imageHandler = new 
HTMLServerImageHandler();
 
-    private BirtWorker () {}
+    private BirtWorker() {}
 
     /**
      * export report
@@ -71,16 +84,18 @@ public final class BirtWorker {
      * @throws SQLException
      */
     public static void exportReport(IReportRunnable design, Map<String, ? 
extends Object> context, String contentType, OutputStream output)
-        throws EngineException, GeneralException, SQLException {
+            throws EngineException, GeneralException, SQLException {
 
-        Locale birtLocale = (Locale)context.get(BIRT_LOCALE);
-        String birtImageDirectory = (String)context.get(BIRT_IMAGE_DIRECTORY);
+        Locale birtLocale = (Locale) context.get(BIRT_LOCALE);
+        String birtImageDirectory = (String) context.get(BIRT_IMAGE_DIRECTORY);
 
         if (contentType == null) {
             contentType = "text/html";
+        } else {
+            contentType = contentType.toLowerCase();
         }
         if (birtImageDirectory == null) {
-             birtImageDirectory = "/";
+            birtImageDirectory = "/";
         }
         Debug.logInfo("Get report engine", module);
         IReportEngine engine = BirtFactory.getReportEngine();
@@ -92,107 +107,65 @@ public final class BirtWorker {
         }
 
         // set parameters if exists
-        Map<String, Object> parameters = 
UtilGenerics.cast(context.get(BirtWorker.BIRT_PARAMETERS));
+        Map<String, Object> parameters = 
UtilGenerics.cast(context.get(BirtWorker.getBirtParameters()));
         if (parameters != null) {
-            Debug.logInfo("Set BIRT parameters:" + parameters, module);
+            //Debug.logInfo("Set BIRT parameters:" + parameters, module);
             task.setParameterValues(parameters);
         }
 
         // set output options
+        if (! BirtUtil.isSupportedMimeType(contentType)) {
+            throw new GeneralException("Unknown content type : " + 
contentType);
+        }
         RenderOption options = new RenderOption();
-        if ("text/html".equalsIgnoreCase(contentType)) { // HTML
-            options.setOutputFormat(RenderOption.OUTPUT_FORMAT_HTML);
+        options.setOutputFormat(BirtUtil.getMimeTypeOutputFormat(contentType));
+
+        //specific process for mimetype
+        if ("text/html".equals(contentType)) { // HTML
             HTMLRenderOption htmlOptions = new HTMLRenderOption(options);
             htmlOptions.setImageDirectory(birtImageDirectory);
             htmlOptions.setBaseImageURL(birtImageDirectory);
             options.setImageHandler(imageHandler);
-        } else if ("application/postscript".equalsIgnoreCase(contentType)) { 
// Post Script
-            options.setOutputFormat("postscript");
-        } else if ("application/pdf".equalsIgnoreCase(contentType)) { // PDF
-            options.setOutputFormat(RenderOption.OUTPUT_FORMAT_PDF);
+        } else if ("application/pdf".equals(contentType)) { // PDF
             PDFRenderOption pdfOptions = new PDFRenderOption(options);
-            pdfOptions.setOption(IPDFRenderOption.PAGE_OVERFLOW, Boolean.TRUE 
);
-        } else if ("application/vnd.ms-word".equalsIgnoreCase(contentType)) { 
// MS Word
-            options.setOutputFormat("doc");
-        }  else if ("application/vnd.ms-excel".equalsIgnoreCase(contentType)) 
{ // MS Excel
-            options.setOutputFormat("xls");
+            pdfOptions.setOption(IPDFRenderOption.PAGE_OVERFLOW, Boolean.TRUE);
+        } else if ("application/vnd.ms-excel".equals(contentType)) { // MS 
Excel
             new EXCELRenderOption(options);
-        } else if 
("application/vnd.ms-powerpoint".equalsIgnoreCase(contentType)) { // MS Power 
Point
-            options.setOutputFormat("ppt");
-        } else if 
("application/vnd.oasis.opendocument.text".equalsIgnoreCase(contentType)) { // 
Open Document Text
-            options.setOutputFormat("odt");
-        } else if 
("application/vnd.oasis.opendocument.spreadsheet".equalsIgnoreCase(contentType))
 { // Open Document Spreadsheet
-            options.setOutputFormat("ods");
-        } else if 
("application/vnd.oasis.opendocument.presentation".equalsIgnoreCase(contentType))
 { // Open Document Presentation
-            options.setOutputFormat("odp");
-        } else if 
("application/vnd.openxmlformats-officedocument.wordprocessingml.document".equalsIgnoreCase(contentType))
 { // MS Word 2007
-            options.setOutputFormat("docx");
-        } else if 
("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".equalsIgnoreCase(contentType))
 { // MS Excel 2007
-            options.setOutputFormat("xlsx");
-        } else if 
("application/vnd.openxmlformats-officedocument.presentationml.presentation".equalsIgnoreCase(contentType))
 { // MS Word 2007
-            options.setOutputFormat("pptx");
-        } else {
-            throw new GeneralException("Unknown content type : " + 
contentType);
         }
 
         options.setOutputStream(output);
         task.setRenderOption(options);
 
         // run report
-        Debug.logInfo("BIRT's locale is: " + task.getLocale(), module);
-        Debug.logInfo("Run report's task", module);
+        if (Debug.infoOn()) {
+            Debug.logInfo("BIRT's locale is: " + task.getLocale(), module);
+            Debug.logInfo("Run report's task", module);
+        }
         task.run();
         task.close();
     }
-    
+
     /**
      * set web context objects
      * @param appContext
      * @param request
      * @param response
      */
-    public static void setWebContextObjects(Map<String, Object> appContext, 
HttpServletRequest request, HttpServletResponse response) {
+    public static void setWebContextObjects(Map<String, Object> appContext, 
HttpServletRequest request, HttpServletResponse response)
+    throws GeneralException {
         HttpSession session = request.getSession();
         ServletContext servletContext = session.getServletContext();
-        
-        // set delegator
-        Delegator delegator = (Delegator) session.getAttribute("delegator");
-        if (UtilValidate.isEmpty(delegator)) {
-            delegator = (Delegator) servletContext.getAttribute("delegator");
-        }
-        if (UtilValidate.isEmpty(delegator)) {
-            delegator = (Delegator) request.getAttribute("delegator");
-        }
-        if (UtilValidate.isNotEmpty(delegator)) {
-            appContext.put("delegator", delegator);
-        }
 
-        // set JDBC connection
-        //appContext.put("OdaJDBCDriverPassInConnection", connection);
-
-        // set dispatcher
-        LocalDispatcher dispatcher = (LocalDispatcher) 
session.getAttribute("dispatcher");
-        if (UtilValidate.isEmpty(dispatcher)) {
-            dispatcher = (LocalDispatcher) 
servletContext.getAttribute("dispatcher");
-        }
-        if (UtilValidate.isEmpty(dispatcher)) {
-            dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
-        }
-        if (UtilValidate.isNotEmpty(dispatcher)) {
-            appContext.put("dispatcher", dispatcher);
+        if (appContext == null || servletContext == null) {
+            throw new GeneralException("The context reporting is empty, check 
your configuration");
         }
 
-        // set security
-        Security security = (Security) session.getAttribute("security");
-        if (UtilValidate.isEmpty(security)) {
-            security = (Security) servletContext.getAttribute("security");
-        }
-        if (UtilValidate.isEmpty(security)) {
-            security = (Security) request.getAttribute("security");
-        }
-        if (UtilValidate.isNotEmpty(security)) {
-            appContext.put("security", security);
-        }
+        // initialize the delegator
+        appContext.put("delegator", WebAppUtil.getDelegator(servletContext));
+        // initialize security
+        appContext.put("security", WebAppUtil.getSecurity(servletContext));
+        // initialize the services dispatcher
+        appContext.put("dispatcher", WebAppUtil.getDispatcher(servletContext));
     }
 
     public static String getBirtParameters () {
@@ -214,4 +187,93 @@ public final class BirtWorker {
     public static String getBirtOutputFileName () {
         return BIRT_OUTPUT_FILE_NAME;
     }
+
+    //TODO documentation
+    public static String recordReportContent(Delegator delegator, 
LocalDispatcher dispatcher, Map<String, Object> context) throws 
GeneralException {
+        Locale locale = (Locale) context.get("locale");
+        String description = (String) context.get("description");
+        String reportName = (String) context.get("reportName");
+        String writeFilters = (String) context.get("writeFilters");
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+        String entityViewName = (String) context.get("entityViewName");
+        String serviceName = (String) context.get("serviceName");
+        String masterContentId = (String) context.get("masterContentId");
+        String dataResourceId = delegator.getNextSeqId("DataResource");
+        String contentId = delegator.getNextSeqId("Content");
+        context.put("contentId", contentId);
+
+        if (UtilValidate.isEmpty(serviceName) && 
UtilValidate.isEmpty(entityViewName)) {
+            throw new GenericServiceException("Service and entity name cannot 
be both empty");
+        }
+
+        String modelType = null;
+        String modelElementName = null;
+        String workflowType = null;
+        if (UtilValidate.isEmpty(serviceName)) {
+            modelElementName = entityViewName;
+            workflowType = "Entity";
+        } else {
+            modelElementName = serviceName;
+            workflowType = "Service";
+        }
+
+        //resolve the path location to store the RptDesign file, check if the 
file already exists under this name and increment index name if needed
+        List<GenericValue> listRptDesigns = null;
+        EntityCondition entityConditionRpt = 
EntityCondition.makeCondition("contentTypeId", "RPTDESIGN");
+        String templatePathLocation = BirtUtil.resolveTemplatePathLocation();
+        File templatePathLocationDir = new File(templatePathLocation);
+            if (!templatePathLocationDir.exists()) {
+                boolean created = templatePathLocationDir.mkdirs();
+                if (!created) {
+                    new 
GeneralException(UtilProperties.getMessage(resourceError, 
"BirtErrorCannotLocateReportFolder", locale));
+                }
+            }
+        int i = 0;
+        String templateFileLocation = null;
+        EntityCondition ecl = null;
+        do {
+            StringBuffer rptDesignNameSb = new 
StringBuffer(templatePathLocation);
+            rptDesignNameSb.append(BirtUtil.encodeReportName(reportName));
+            rptDesignNameSb.append("_").append(i);
+            rptDesignNameSb.append(".rptdesign");
+            templateFileLocation = rptDesignNameSb.toString();
+            EntityCondition entityConditionOnName = 
EntityCondition.makeCondition("drObjectInfo", templateFileLocation);
+            ecl = 
EntityCondition.makeCondition(UtilMisc.toList(entityConditionRpt, 
entityConditionOnName));
+            i++;
+        } while (delegator.findCountByCondition("ContentDataResourceView", 
ecl, null, null) > 0);
+
+        //resolve the initial form structure from master content
+        Map<String, Object> resultElectronicText = 
dispatcher.runSync("getElectronicText", UtilMisc.toMap("contentId", 
masterContentId, "locale", locale, "userLogin", userLogin));
+        if (ServiceUtil.isError(resultElectronicText)) {
+            new 
GeneralException(ServiceUtil.getErrorMessage(resultElectronicText));
+        }
+        String reportForm = (String) resultElectronicText.get("textData");
+        if (! reportForm.startsWith("<?xml")) {
+            StringBuffer xmlHeaderForm = new StringBuffer("<?xml 
version=\"1.0\" encoding=\"UTF-8\"?>");
+            xmlHeaderForm.append("<forms 
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"; 
xsi:noNamespaceSchemaLocation=\"http://ofbiz.apache.org/dtds/widget-form.xsd\";>");
+            xmlHeaderForm.append(reportForm);
+            xmlHeaderForm.append("</forms>");
+            reportForm = xmlHeaderForm.toString();
+        }
+        FlexibleStringExpander reportFormExpd = 
FlexibleStringExpander.getInstance(reportForm);
+        reportForm = reportFormExpd.expandString(context);
+
+        //create content and dataressource strucutre
+        dispatcher.runSync("createDataResource", 
UtilMisc.toMap("dataResourceId", dataResourceId, "dataResourceTypeId", 
"ELECTRONIC_TEXT", "dataTemplateTypeId", "FORM_COMBINED", "userLogin", 
userLogin));
+        dispatcher.runSync("createElectronicTextForm", 
UtilMisc.toMap("dataResourceId", dataResourceId, "textData", reportForm, 
"userLogin", userLogin));
+        dispatcher.runSync("createContent", UtilMisc.toMap("contentId", 
contentId, "contentTypeId", "FLEXIBLE_REPORT", "dataResourceId", 
dataResourceId, "statusId", "CTNT_IN_PROGRESS", "contentName", reportName, 
"description", description, "userLogin", userLogin));
+        String dataResourceIdRpt = delegator.getNextSeqId("DataResource");
+        String contentIdRpt = delegator.getNextSeqId("Content");
+        String rptDesignName = BirtUtil.encodeReportName(reportName);
+        if (! rptDesignName.endsWith(".rptdesign")) {
+            rptDesignName = rptDesignName.concat(".rptdesign");
+        }
+        dispatcher.runSync("createDataResource", 
UtilMisc.toMap("dataResourceId", dataResourceIdRpt, "dataResourceTypeId", 
"LOCAL_FILE", "mimeTypeId", "text/rptdesign", "dataResourceName", 
rptDesignName, "objectInfo", templateFileLocation, "userLogin", userLogin));
+        dispatcher.runSync("createContent", UtilMisc.toMap("contentId", 
contentIdRpt, "contentTypeId", "RPTDESIGN", "dataResourceId", 
dataResourceIdRpt, "statusId", "CTNT_PUBLISHED", "contentName", reportName, 
"description", description + " (.rptDesign file)", "userLogin", userLogin));
+        dispatcher.runSync("createContentAssoc", UtilMisc.toMap("contentId", 
masterContentId, "contentIdTo", contentId, "contentAssocTypeId", "SUB_CONTENT", 
"userLogin", userLogin));
+        dispatcher.runSync("createContentAssoc", UtilMisc.toMap("contentId", 
contentId, "contentIdTo", contentIdRpt, "contentAssocTypeId", "SUB_CONTENT", 
"userLogin", userLogin));
+        dispatcher.runSync("createContentAttribute", 
UtilMisc.toMap("contentId", contentId, "attrName", workflowType, "attrValue", 
modelElementName, "userLogin", userLogin));
+        return contentId;
+    }
+
 }

Added: 
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtMasterReportServices.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtMasterReportServices.java?rev=1780683&view=auto
==============================================================================
--- 
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtMasterReportServices.java
 (added)
+++ 
ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtMasterReportServices.java
 Sat Jan 28 13:22:55 2017
@@ -0,0 +1,294 @@
+package org.apache.ofbiz.birt.flexible;
+
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ofbiz.base.util.UtilDateTime;
+import org.apache.ofbiz.base.util.UtilMisc;
+import org.apache.ofbiz.base.util.UtilProperties;
+import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.entity.Delegator;
+import org.apache.ofbiz.entity.GenericEntityException;
+import org.apache.ofbiz.entity.GenericValue;
+import org.apache.ofbiz.entity.condition.EntityCondition;
+import org.apache.ofbiz.entity.condition.EntityExpr;
+import org.apache.ofbiz.entity.condition.EntityOperator;
+import org.apache.ofbiz.entity.util.EntityUtil;
+import org.apache.ofbiz.party.party.PartyHelper;
+import org.apache.ofbiz.service.DispatchContext;
+import org.apache.ofbiz.service.ServiceUtil;
+import org.eclipse.birt.report.engine.api.script.IReportContext;
+
+public class BirtMasterReportServices {
+
+    public static final String module = BirtServices.class.getName();
+    public static final String resource = "BirtUiLabels";
+    public static final String resource_error = "BirtErrorUiLabels";
+
+    // The following funtion are flexible service as example for reporting
+    public static Map<String, Object> 
workEffortPerPersonPrepareDate(DispatchContext dctx, Map<String, Object> 
context) {
+        Map<String, String> dataMap = UtilMisc.toMap("lastName", "name", 
"firstName", "name", "hours", "floating-point", "fromDate", "date-time", 
"thruDate", "date-time");
+        LinkedHashMap<String, String> filterMap = new LinkedHashMap<String, 
String>();
+        filterMap.put("firstName", "name");
+        filterMap.put("lastName", "name");
+        filterMap.put("fromDate", "date-time");
+        filterMap.put("thruDate", "date-time");
+        Map<String, String> fieldDisplayLabels = UtilMisc.toMap("lastName", 
"Last name", "firstName", "First name", "hours", "Hours", "fromDate", "From 
date", "thruDate", "Thru date");
+        LinkedHashMap<String, String> filterDisplayLabels = new 
LinkedHashMap<String, String>();
+        filterDisplayLabels.put("firstName", "First name");
+        filterDisplayLabels.put("lastName", "Last name");
+        filterDisplayLabels.put("fromDate", "From date");
+        filterDisplayLabels.put("thruDate", "Thru date");
+        Map<String, Object> result = ServiceUtil.returnSuccess();
+        result.put("dataMap", dataMap);
+        result.put("filterMap", filterMap);
+        result.put("fieldDisplayLabels", fieldDisplayLabels);
+        result.put("filterDisplayLabels", filterDisplayLabels);
+        return result;
+    }
+
+    public static Map<String, Object> workEffortPerPerson(DispatchContext 
dctx, Map<String, Object> context) {
+        Delegator delegator = (Delegator) dctx.getDelegator();
+        IReportContext reportContext = (IReportContext) 
context.get("reportContext");
+        Map<String, Object> parameters = (Map<String, Object>) 
reportContext.getParameterValue("parameters");
+        List<GenericValue> listWorkEffortTime = null;
+
+        if (UtilValidate.isEmpty(parameters.get("firstName")) && 
UtilValidate.isEmpty(parameters.get("lastName"))) {
+            return ServiceUtil.returnError("First and last name can not be 
both empty");
+        }
+        List<GenericValue> listPersons = null;
+        try {
+            // TODO: translate labels
+            List<EntityExpr> listConditions = new ArrayList<EntityExpr>();
+            if (UtilValidate.isNotEmpty(parameters.get("firstName"))) {
+                EntityExpr conditionFirstName = 
EntityCondition.makeCondition("firstName", parameters.get("firstName"));
+                listConditions.add(conditionFirstName);
+            }
+            if (UtilValidate.isNotEmpty(parameters.get("lastName"))) {
+                EntityExpr conditionLastName = 
EntityCondition.makeCondition("lastName", parameters.get("lastName"));
+                listConditions.add(conditionLastName);
+            }
+            EntityCondition ecl = 
EntityCondition.makeCondition(listConditions, EntityOperator.AND);
+            listPersons = delegator.findList("Person", ecl, 
UtilMisc.toSet("partyId", "firstName", "lastName"), null, null, true);
+            GenericValue person = null;
+            if (listPersons.size() > 1) {
+                return ServiceUtil.returnError("Your criteria match with 
several people");
+            } else if (listPersons.size() == 1) {
+                person = listPersons.get(0);
+            } else {
+                return ServiceUtil.returnError("Could not find this person");
+            }
+            String partyId = person.getString("partyId");
+
+            List<EntityExpr> listConditionsWorkEffort = new 
ArrayList<EntityExpr>();
+            Timestamp thruDate = null;
+            Timestamp fromDate = null;
+            if (UtilValidate.isEmpty(parameters.get("fromDate"))) {
+                return ServiceUtil.returnError("The starting date is 
mandatory");
+            } else {
+                fromDate = Timestamp.valueOf((String) 
parameters.get("fromDate"));
+                EntityExpr conditionFromDate = 
EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN_EQUAL_TO, 
fromDate);
+                listConditionsWorkEffort.add(conditionFromDate);
+            }
+            if (UtilValidate.isEmpty(parameters.get("thruDate"))) {
+                thruDate = UtilDateTime.nowTimestamp();
+            } else {
+                thruDate = Timestamp.valueOf((String) 
parameters.get("thruDate"));
+            }
+            EntityExpr conditionThruDate = 
EntityCondition.makeCondition("thruDate", EntityOperator.LESS_THAN_EQUAL_TO, 
thruDate);
+            listConditionsWorkEffort.add(conditionThruDate);
+            EntityExpr conditionParty = 
EntityCondition.makeCondition("partyId", partyId);
+            listConditionsWorkEffort.add(conditionParty);
+            ecl = EntityCondition.makeCondition(listConditionsWorkEffort, 
EntityOperator.AND);
+            listWorkEffortTime = delegator.findList("WorkEffortAndTimeEntry", 
ecl, UtilMisc.toSet("hours", "fromDate", "thruDate"), null, null, true);
+        } catch (GenericEntityException e) {
+            e.printStackTrace();
+            ServiceUtil.returnError("Error getting party from person name.");
+        }
+        List<GenericValue> listCompiled = new ArrayList<GenericValue>();
+        if (UtilValidate.isNotEmpty(listWorkEffortTime)) 
listCompiled.addAll(listWorkEffortTime);
+        if (UtilValidate.isNotEmpty(listPersons)) 
listCompiled.addAll(listPersons);
+        Map<String, Object> result = ServiceUtil.returnSuccess();
+        result.put("records", listCompiled);
+        return result;
+    }
+
+    public static Map<String, Object> turnOverPrepareFields(DispatchContext 
dctx, Map<String, Object> context) {
+        Map<String, String> dataMap = UtilMisc.toMap("invoiceTypeId", 
"short-varchar", "invoicePartyId", "short-varchar", "statusId", 
"short-varchar", "invoiceDate", "date", "dueDate", "date", "currencyUomId", 
"short-varchar", "invoiceItemTypeId", "short-varchar", "invoiceItemSeqId", 
"short-varchar", "productId", "short-varchar", "partyId", "short-varchar", 
"partyName", "short-varchar", "primaryProductCategoryId", "short-varchar", 
"quantity", "numeric", "amount", "currency-amount", "productStoreId", 
"short-varchar", "storeName", "short-varchar");
+        Map<String, String> fieldDisplayLabels = 
UtilMisc.toMap("invoiceTypeId", "invoice Type", "invoicePartyId", "Invoice", 
"statusId", "Status", "invoiceDate", "Date", "dueDate", "Due date ", 
"currencyUomId", "Currency", "invoiceItemTypeId", "Invoice type line", 
"invoiceItemSeqId", "Invoice line", "productId", "Product", "partyId", 
"Customer", "partyName", "Customer name", "primaryProductCategoryId", "Product 
category", "quantity", "Qty", "amount", "Montant", "productStoreId", "Product 
Store", "storeName", "Product store name");
+        LinkedHashMap<String, String> filterMap = new LinkedHashMap<String, 
String>(); 
+        filterMap.put("productCategoryId", "short-varchar");
+        filterMap.put("productStoreId", "short-varchar");
+        filterMap.put("fromDate", "date");
+        filterMap.put("thruDate", "date");
+        LinkedHashMap<String, String> filterDisplayLabels = new 
LinkedHashMap<String, String>();
+        //it's better to use Label Map, maybe an improvement point !
+        filterDisplayLabels.put("productCategoryId", "product Category");
+        filterDisplayLabels.put("productStoreId", "product Store");
+        filterDisplayLabels.put("fromDate", "from Date");
+        filterDisplayLabels.put("thruDate", "through Date");
+        Map<String, Object> result = ServiceUtil.returnSuccess();
+        result.put("dataMap", dataMap);
+        result.put("filterMap", filterMap);
+        result.put("fieldDisplayLabels", fieldDisplayLabels);
+        result.put("filterDisplayLabels", filterDisplayLabels);
+        return result;
+    }
+
+    public static Map<String, Object> turnOver(DispatchContext dctx, 
Map<String, Object> context) {
+        Delegator delegator = (Delegator) dctx.getDelegator();
+        Locale locale = (Locale) context.get("locale");
+        IReportContext reportContext = (IReportContext) 
context.get("reportContext");
+        Map<String, Object> parameters = (Map<String, Object>) 
reportContext.getParameterValue("parameters");
+
+        List<GenericValue> listTurnOver = null;
+        List<Map<String, Object>> listInvoiceEditable = new 
ArrayList<Map<String, Object>>();
+        List<EntityCondition> listAllConditions = new 
ArrayList<EntityCondition>();
+        try {
+            // treating fromDate field condition
+            if (UtilValidate.isNotEmpty(parameters.get("fromDate"))) {
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+                String fromDateString = (String) parameters.get("fromDate");
+                Timestamp fromDate = new 
Timestamp(sdf.parse(fromDateString).getTime());
+                EntityExpr conditionFromDate = 
EntityCondition.makeCondition("invoiceDate", 
EntityOperator.GREATER_THAN_EQUAL_TO, fromDate);
+                listAllConditions.add(conditionFromDate);
+            }
+
+            // treating throughDate field condition
+            if (UtilValidate.isNotEmpty(parameters.get("throughDate"))) {
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+                String throughDateString = (String) 
parameters.get("throughDate");
+                Timestamp throughDate = new 
Timestamp(sdf.parse(throughDateString).getTime());
+                EntityExpr conditionThroughDate = 
EntityCondition.makeCondition("invoiceDate", EntityOperator.LESS_THAN_EQUAL_TO, 
throughDate);
+                listAllConditions.add(conditionThroughDate);
+            }
+
+            // product category field condition
+            if (UtilValidate.isNotEmpty(parameters.get("productCategoryId"))) {
+                List<String> productCategoryList = new ArrayList<String>();
+                if (parameters.get("productCategoryId") instanceof String) {
+                    String productCategoryId = (String) 
parameters.get("productCategoryId");
+                    productCategoryList.add(productCategoryId);
+                } else {
+                    productCategoryList = (List<String>) 
parameters.get("productCategoryId");
+                }
+                // getting productIds in these categories
+                EntityExpr conditionProductCategory = 
EntityCondition.makeCondition("primaryProductCategoryId", EntityOperator.IN, 
productCategoryList);
+                EntityExpr conditionFromDate = 
EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN_EQUAL_TO, 
UtilDateTime.nowTimestamp());
+                EntityExpr conditionBeforeDate = 
EntityCondition.makeCondition("thruDate", EntityOperator.LESS_THAN_EQUAL_TO, 
UtilDateTime.nowTimestamp());
+                EntityExpr conditionNull = 
EntityCondition.makeCondition("thruDate", null);
+                EntityCondition conditionThroughDate = 
EntityCondition.makeCondition(EntityOperator.OR, 
UtilMisc.toList(conditionBeforeDate, conditionNull));
+                List<GenericValue> listProductIds = 
delegator.findList("ProductCategoryMember", 
EntityCondition.makeCondition(UtilMisc.toList(conditionProductCategory, 
conditionFromDate, conditionThroughDate)), UtilMisc.toSet("productId"), null, 
null, true);
+                List<String> listProductIdsString = 
EntityUtil.getFieldListFromEntityList(listProductIds, "productId", true);
+
+                EntityExpr conditionProductCat = 
EntityCondition.makeCondition("productId", EntityOperator.IN, 
listProductIdsString);
+                listAllConditions.add(conditionProductCat);
+            }
+
+            // productStoreId condition
+            List<String> productStoreList = new ArrayList<String>();
+            if (UtilValidate.isNotEmpty(parameters.get("productStoreId"))) {
+                if (parameters.get("productStoreId") instanceof String) {
+                    String productStoreId = (String) 
parameters.get("productStoreId");
+                    productStoreList.add(productStoreId);
+                } else {
+                    productStoreList = (List<String>) 
parameters.get("productStoreId");
+                }
+                // getting list of invoice Ids linked to these productStore
+                EntityExpr conditionProductStoreId = 
EntityCondition.makeCondition("productStoreId", EntityOperator.IN, 
productStoreList);
+                List<GenericValue> listOrderAndProductStores = 
delegator.findList("OrderAndProductStore", conditionProductStoreId, 
UtilMisc.toSet("orderId"), null, null, true);
+                List<String> listOrderIds = 
EntityUtil.getFieldListFromEntityList(listOrderAndProductStores, "orderId", 
true);
+                EntityExpr conditionOrderId = 
EntityCondition.makeCondition("orderId", EntityOperator.IN, listOrderIds);
+                List<GenericValue> listInvoices = 
delegator.findList("OrderItemBilling", conditionOrderId, 
UtilMisc.toSet("invoiceId"), null, null, false);
+                List<String> listInvoiceString = 
EntityUtil.getFieldListFromEntityList(listInvoices, "invoiceId", true);
+
+                EntityExpr conditionInvoiceIdProductStore = 
EntityCondition.makeCondition("invoiceId", EntityOperator.IN, 
listInvoiceString);
+                listAllConditions.add(conditionInvoiceIdProductStore);
+            }
+
+            // adding mandatory conditions
+            // condition on invoice item type
+            List<String> listInvoiceItemType = 
UtilMisc.toList("ITM_PROMOTION_ADJ", "INV_PROD_ITEM", "INV_FPROD_ITEM", 
"INV_DPROD_ITEM", "INV_FDPROD_ITEM", "INV_PROD_FEATR_ITEM");
+            listInvoiceItemType.add("ITM_DISCOUNT_ADJ");
+            listInvoiceItemType.add("CRT_FPROD_ITEM");
+            listInvoiceItemType.add("CRT_DPROD_ITEM");
+            listInvoiceItemType.add("CRT_FDPROD_ITEM");
+            listInvoiceItemType.add("CRT_SPROD_ITEM");
+            listInvoiceItemType.add("CRT_PROMOTION_ADJ");
+            listInvoiceItemType.add("CRT_DISCOUNT_ADJ");
+            listInvoiceItemType.add("CRT_MAN_ADJ");
+            listInvoiceItemType.add("INV_SPROD_ITEM");
+            EntityExpr conditionInvoiceItemType = 
EntityCondition.makeCondition("invoiceItemTypeId", EntityOperator.IN, 
listInvoiceItemType);
+            listAllConditions.add(conditionInvoiceItemType);
+
+            // condition on invoice ((not cancelled) or null)
+            EntityExpr conditionStatusNotCancelled = 
EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, 
"INVOICE_CANCELLED");
+            EntityExpr conditionStatusNull = 
EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, null);
+            EntityCondition conditionStatus = 
EntityCondition.makeCondition(UtilMisc.toList(conditionStatusNotCancelled, 
conditionStatusNull), EntityOperator.OR);
+            listAllConditions.add(conditionStatus);
+
+            // condition sales invoice or customer return invoice
+            EntityExpr conditionSalesInvoice = 
EntityCondition.makeCondition("invoiceTypeId", EntityOperator.IN, 
UtilMisc.toList("SALES_INVOICE", "CUST_RTN_INVOICE"));
+            listAllConditions.add(conditionSalesInvoice);
+
+            // retrieving all invoices
+            Set<String> fieldsToSelect = UtilMisc.toSet("invoiceId");
+            fieldsToSelect.add("invoiceTypeId");
+            fieldsToSelect.add("invoicePartyId");
+            fieldsToSelect.add("statusId");
+            fieldsToSelect.add("invoiceDate");
+            fieldsToSelect.add("dueDate");
+            fieldsToSelect.add("currencyUomId");
+            fieldsToSelect.add("invoiceItemTypeId");
+            fieldsToSelect.add("invoiceItemSeqId");
+            fieldsToSelect.add("quantity");
+            fieldsToSelect.add("amount");
+            fieldsToSelect.add("productId");
+            fieldsToSelect.add("partyId");
+            fieldsToSelect.add("primaryProductCategoryId");
+            listTurnOver = delegator.findList("InvoiceItemProductAndParty", 
EntityCondition.makeCondition(listAllConditions), fieldsToSelect, null, null, 
true);
+
+            // adding missing fields
+            for (GenericValue invoice : listTurnOver) {
+                Map<String, Object> invoiceEditableTemp = (Map<String, 
Object>) invoice.clone();
+                invoiceEditableTemp.remove("GenericEntity");
+                Map<String, Object> invoiceEditable = new HashMap<String, 
Object>();
+                invoiceEditable.putAll(invoiceEditableTemp);
+                invoiceEditable.put("partyName", 
PartyHelper.getPartyName(delegator, invoice.getString("partyId"), false));
+
+                // adding productStoreId and productStoreName
+                EntityExpr conditionInvoiceId = 
EntityCondition.makeCondition("invoiceId", invoice.getString("invoiceId"));
+//                EntityExpr conditionInvoiceItemSeqId = 
EntityCondition.makeCondition("invoiceItemSeqId", 
invoice.getString("invoiceItemSeqId"));
+//                List<GenericValue> listOrderBilling = 
delegator.findList("OrderItemBilling", 
EntityCondition.makeCondition(UtilMisc.toList(conditionInvoiceId, 
conditionInvoiceItemSeqId)), UtilMisc.toSet("orderId"), null, null, false);
+                List<GenericValue> listOrderBilling = 
delegator.findList("OrderItemBilling", conditionInvoiceId, 
UtilMisc.toSet("orderId"), null, null, false);
+                if (UtilValidate.isNotEmpty(listOrderBilling)) {
+                    GenericValue orderBilling = 
EntityUtil.getFirst(listOrderBilling);
+                    EntityExpr conditionOrderId = 
EntityCondition.makeCondition("orderId", orderBilling.getString("orderId"));
+                    List<GenericValue> listProductStore = 
delegator.findList("OrderAndProductStore", conditionOrderId, null, null, null, 
true);
+                    GenericValue productStore = 
EntityUtil.getFirst(listProductStore);
+                    if (UtilValidate.isNotEmpty(productStoreList) && ! 
productStoreList.contains(productStore.getString("productStoreId"))) {
+                        continue; // pretty ugly... but had problems with the 
rare case where an invoice matches with several orders with more than one 
productStore
+                    }
+                    invoiceEditable.put("productStoreId", 
productStore.getString("productStoreId"));
+                    invoiceEditable.put("storeName", 
productStore.getString("storeName"));
+                } else {
+                    invoiceEditable.put("productStoreId", "_NA_");
+                    invoiceEditable.put("storeName", "_NA_");
+                }
+                listInvoiceEditable.add(invoiceEditable);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"BirtErrorRetrievingTurnOver", locale));
+        }
+        Map<String, Object> result = ServiceUtil.returnSuccess();
+        result.put("records", listInvoiceEditable);
+        return result;
+    }
+}


Reply via email to