svn commit: r1781219 [4/14] - in /ofbiz/trunk: applications/accounting/data/ applications/accounting/groovyScripts/ap/invoices/ applications/accounting/groovyScripts/fixedasset/ applications/accounting/groovyScripts/invoice/ applications/accounting/gro...

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1781219 [4/14] - in /ofbiz/trunk: applications/accounting/data/ applications/accounting/groovyScripts/ap/invoices/ applications/accounting/groovyScripts/fixedasset/ applications/accounting/groovyScripts/invoice/ applications/accounting/gro...

jleroux@apache.org
Modified: ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtServices.java?rev=1781219&r1=1781218&r2=1781219&view=diff
==============================================================================
--- ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtServices.java (original)
+++ ofbiz/trunk/plugins/birt/src/main/java/org/apache/ofbiz/birt/flexible/BirtServices.java Wed Feb  1 10:58:46 2017
@@ -1,825 +1,825 @@
-/*******************************************************************************
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.
- *******************************************************************************/
-package org.apache.ofbiz.birt.flexible;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.ofbiz.base.util.Debug;
-import org.apache.ofbiz.base.util.GeneralException;
-import org.apache.ofbiz.base.util.StringUtil;
-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.UtilXml;
-import org.apache.ofbiz.base.util.string.FlexibleStringExpander;
-import org.apache.ofbiz.birt.BirtWorker;
-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.EntityConditionList;
-import org.apache.ofbiz.entity.condition.EntityExpr;
-import org.apache.ofbiz.entity.condition.EntityOperator;
-import org.apache.ofbiz.entity.model.ModelEntity;
-import org.apache.ofbiz.entity.model.ModelField;
-import org.apache.ofbiz.entity.util.EntityListIterator;
-import org.apache.ofbiz.entity.util.EntityQuery;
-import org.apache.ofbiz.entity.util.EntityUtil;
-import org.apache.ofbiz.service.DispatchContext;
-import org.apache.ofbiz.service.GenericServiceException;
-import org.apache.ofbiz.service.LocalDispatcher;
-import org.apache.ofbiz.service.ModelService;
-import org.apache.ofbiz.service.ServiceUtil;
-import org.eclipse.birt.core.exception.BirtException;
-import org.eclipse.birt.core.framework.Platform;
-import org.eclipse.birt.report.engine.api.script.IReportContext;
-import org.eclipse.birt.report.model.api.DesignConfig;
-import org.eclipse.birt.report.model.api.DesignElementHandle;
-import org.eclipse.birt.report.model.api.DesignFileException;
-import org.eclipse.birt.report.model.api.IDesignEngine;
-import org.eclipse.birt.report.model.api.IDesignEngineFactory;
-import org.eclipse.birt.report.model.api.ReportDesignHandle;
-import org.eclipse.birt.report.model.api.SessionHandle;
-import org.eclipse.birt.report.model.api.SimpleMasterPageHandle;
-import org.eclipse.birt.report.model.api.SlotHandle;
-import org.eclipse.birt.report.model.api.VariableElementHandle;
-import org.eclipse.birt.report.model.api.activity.SemanticException;
-import org.eclipse.birt.report.model.elements.SimpleMasterPage;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-import com.ibm.icu.util.ULocale;
-
-
-/**
- * Birt Services
- */
-
-public class BirtServices {
-
-    public static final String module = BirtServices.class.getName();
-    public static final String resource = "BirtUiLabels";
-    public static final String resource_error = "BirtErrorUiLabels";
-    public static final String resourceProduct = "BirtUiLabels";
-
-    /**
-     * Instantiate a new Flexible report, using the data given in parameters and <code>ReportDesignGenerator</code> class.
-     */
-    public static Map<String, Object> createFlexibleReport(DispatchContext dctx, Map<String, Object> context) {
-        ReportDesignGenerator rptGenerator;
-        try {
-            rptGenerator = new ReportDesignGenerator(context, dctx);
-        } catch (Exception e1) {
-            e1.printStackTrace();
-            return ServiceUtil.returnError(e1.getMessage());
-        }
-        try {
-            rptGenerator.buildReport();
-        } catch (Exception e) {
-            Debug.logError(e, module);
-            return ServiceUtil.returnError(e.getMessage());
-        }
-        return ServiceUtil.returnSuccess();
-    }
-
-    @Deprecated
-    public static Map<String, Object> prepareFlexibleReportOptionFieldsFromEntity(DispatchContext dctx, Map<String, Object> context) {
-        String entityViewName = (String) context.get("entityViewName");
-        GenericValue userLogin = (GenericValue) context.get("userLogin");
-        List<String> listMultiFields = new ArrayList<String>();
-        Delegator delegator = dctx.getDelegator();
-        LocalDispatcher dispatcher = dctx.getDispatcher();
-        Map<String, Object> result = new HashMap<String, Object>();
-        Locale locale = (Locale) context.get("locale");
-
-        ModelEntity modelEntity = delegator.getModelEntity(entityViewName);
-        List<String> listFieldsEntity = modelEntity.getAllFieldNames();
-
-        for (String field : listFieldsEntity) {
-            listMultiFields.add(field);
-            ModelField mField = modelEntity.getField(field);
-            String fieldType = mField.getType();
-            String birtType = null;
-            try {
-                Map<String, Object> convertRes = dispatcher.runSync("convertFieldTypeToBirtType", UtilMisc.toMap("fieldType", fieldType, "userLogin", userLogin));
-                birtType = (String) convertRes.get("birtType");
-                if (UtilValidate.isEmpty(birtType)) {
-                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorConversionFieldToBirtFailed", locale));
-                }
-            } catch (GenericServiceException e) {
-                e.printStackTrace();
-            }
-            // make more general when report forms have been made so too.
-            if (birtType.equalsIgnoreCase("date-time") || birtType.equalsIgnoreCase("date") || birtType.equalsIgnoreCase("time")) {
-                listMultiFields.add(field + "_fld0_op");
-                listMultiFields.add(field + "_fld0_value");
-                listMultiFields.add(field + "_fld1_op");
-                listMultiFields.add(field + "_fld1_value");
-            }
-        }
-        result.put("listMultiFields", listMultiFields);
-        return result;
-    }
-
-    /**
-     * Perform find data on given view/entity and return these into birt compatible format.
-     * This service is meant to be used as default for View/entity report design
-     *
-     */
-    public static Map<String, Object> callPerformFindFromBirt(DispatchContext dctx, Map<String, Object> context) {
-        LocalDispatcher dispatcher = dctx.getDispatcher();
-        IReportContext reportContext = (IReportContext) context.get("reportContext");
-        Locale locale = (Locale) context.get("locale");
-        GenericValue userLogin = (GenericValue) context.get("userLogin");
-        String entityViewName = (String) reportContext.getParameterValue("modelElementName");
-        Map<String, Object> inputFields = (Map<String, Object>) reportContext.getParameterValue("parameters");
-        Map<String, Object> resultPerformFind = new HashMap<String, Object>();
-        Map<String, Object> resultToBirt = null;
-        List<GenericValue> list = null;
-
-        if (UtilValidate.isEmpty(entityViewName)) {
-            entityViewName = (String) inputFields.get("modelElementName");
-            if (UtilValidate.isEmpty(entityViewName)) {
-                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorEntityViewNotFound", locale));
-            }
-        }
-
-        try {
-            resultPerformFind = dispatcher.runSync("performFind", UtilMisc.<String, Object>toMap("entityName", entityViewName, "inputFields", inputFields, "userLogin", userLogin, "noConditionFind", "Y", "locale", locale));
-            if (ServiceUtil.isError(resultPerformFind)) {
-                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorRunningPerformFind", locale));
-            }
-        } catch (GenericServiceException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-
-        EntityListIterator listIt = (EntityListIterator) resultPerformFind.get("listIt");
-        try {
-            if (UtilValidate.isNotEmpty(listIt)) {
-                list = listIt.getCompleteList();
-                listIt.close();
-            } else {
-                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorRunningPerformFind", locale));
-            }
-        } catch (GenericEntityException e) {
-            e.printStackTrace();
-        }
-        resultToBirt = ServiceUtil.returnSuccess();
-        resultToBirt.put("records", list);
-        return resultToBirt;
-    }
-
-    /**
-     * Analyse given master and create report design from its data
-     * Two cases are implemented :
-     * <ul>
-     *     <li>Entity : data retieval is based on a simple view/entity</li>
-     *     <li>Service : data retrieval is based on service</li>
-     * </ul>
-     */
-    public static Map<String, Object> createFlexibleReportFromMaster(DispatchContext dctx, Map<String, Object> context) {
-        Delegator delegator = dctx.getDelegator();
-        LocalDispatcher dispatcher = dctx.getDispatcher();
-        Locale locale = (Locale) context.get("locale");
-
-        String reportName = (String) context.get("reportName");
-        String masterContentId = (String) context.get("contentId");
-        String description = (String) context.get("description");
-        String writeFilters = (String) context.get("writeFilters");
-        GenericValue userLogin = (GenericValue) context.get("userLogin");
-
-        GenericValue masterContentAttribute = null;
-        try {
-            EntityCondition entityCondition = EntityCondition.makeCondition("contentId", masterContentId);
-            masterContentAttribute = EntityQuery.use(delegator).from("ContentAttribute").where(entityCondition).queryFirst();
-        } catch (GenericEntityException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-
-        if (masterContentAttribute == null) {
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorNoAttributeFound", locale));
-        }
-        String attrName = masterContentAttribute.getString("attrName");
-        String reportContentId;
-        if (attrName.equalsIgnoreCase("Entity")) {
-            String entityViewName = masterContentAttribute.getString("attrValue");
-                ModelEntity modelEntity = delegator.getModelEntity(entityViewName);
-                if (modelEntity == null) {
-                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorEntityViewNotExist", locale) + " " + entityViewName);
-                }
-            try {
-                Map<String, Object> resultContent = dispatcher.runSync("createFlexibleReportFromMasterEntityWorkflow", UtilMisc.toMap("entityViewName", entityViewName, "reportName", reportName, "description", description, "writeFilters", writeFilters, "masterContentId", masterContentId, "userLogin", userLogin, "locale", locale));
-                if(ServiceUtil.isError(resultContent)) {
-                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resultContent));
-                }
-                reportContentId = (String) resultContent.get("contentId");
-            } catch (GenericServiceException e) {
-                e.printStackTrace();
-                return ServiceUtil.returnError(e.getMessage());
-            }
-        } else if (attrName.equalsIgnoreCase("Service")) {
-            String serviceName = masterContentAttribute.getString("attrValue");
-            try {
-                Map<String, Object> resultContent = dispatcher.runSync("createFlexibleReportFromMasterServiceWorkflow", UtilMisc.toMap("serviceName", serviceName, "reportName", reportName, "description", description, "writeFilters", writeFilters, "masterContentId", masterContentId, "userLogin", userLogin, "locale", locale));
-                if (ServiceUtil.isError(resultContent)) {
-                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resultContent));
-                }
-                reportContentId = (String) resultContent.get("contentId");
-            } catch (GenericServiceException e) {
-                e.printStackTrace();
-                return ServiceUtil.returnError(e.getMessage());
-            }
-        } else {
-            // could create other workflows. WebService? Does it need to be independent from Service workflow?
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCannotDetermineDataSource", locale));
-        }
-
-        // prepare report form to display to allow override
-        String textForm;
-        Map<String, Object> resultFormDisplay;
-        try {
-            resultFormDisplay = dispatcher.runSync("prepareFlexibleReportSearchFormToEdit", UtilMisc.toMap("reportContentId", reportContentId, "userLogin", userLogin, "locale", locale));
-            textForm = (String) resultFormDisplay.get("textForm");
-        } catch (GenericServiceException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCreatingDefaultSearchForm", locale).concat(": ").concat(e.getMessage()));
-        }
-
-        Map<String, Object> result = ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtFlexibleReportSuccessfullyGenerated", locale).concat(" ").concat(reportName));
-        result.put("textForm", textForm);
-        result.put("reportContentId", reportContentId);
-        return result;
-    }
-
-    // I'm not a big fan of how I did the createFormForDisplay / overrideReportForm. Could probably be improved using a proper formForReport object or something similar.
-
-    /**
-     * Update search form of a report design
-     */
-    public static Map<String, Object> overrideReportForm(DispatchContext dctx, Map<String, Object> context) {
-        LocalDispatcher dispatcher = dctx.getDispatcher();
-        Delegator delegator = dctx.getDelegator();
-        Locale locale = (Locale) context.get("locale");
-        String reportContentId = (String) context.get("reportContentId");
-        String overrideFilters = (String) context.get("overrideFilters");
-        GenericValue userLogin = (GenericValue) context.get("userLogin");
-
-        // safety check : do not accept "${groovy", "${bsh" and "javascript"
-        String overideFiltersNoWhiteSpace = overrideFilters.replaceAll("\\s", "");
-        if (overideFiltersNoWhiteSpace.contains("${groovy:") || overideFiltersNoWhiteSpace.contains("${bsh:") || overideFiltersNoWhiteSpace.contains("javascript:")) {
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorUnauthorisedCharacter", locale));
-        }
-
-        try {
-            GenericValue content = EntityQuery.use(delegator).from("Content").where("contentId", reportContentId).queryOne();
-            String dataResourceId = content.getString("dataResourceId");
-            StringBuffer newForm = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?> <forms xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://ofbiz.apache.org/dtds/widget-form.xsd\">");
-            newForm.append(overrideFilters);
-            newForm.append("</forms>");
-            Document xmlForm = UtilXml.readXmlDocument(newForm.toString());
-            dispatcher.runSync("updateElectronicTextForm", UtilMisc.toMap("dataResourceId", dataResourceId, "textData", UtilXml.writeXmlDocument(xmlForm), "userLogin", userLogin, "locale", locale));
-        } catch (GeneralException | SAXException | ParserConfigurationException | IOException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-        return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtSearchFormSuccessfullyOverridde", locale));
-    }
-
-    /**
-     * Create report design from View/Entity master report
-     */
-    public static Map<String, Object> createFlexibleReportFromMasterEntityWorkflow(DispatchContext dctx, Map<String, Object> context) {
-        LocalDispatcher dispatcher = dctx.getDispatcher();
-        Delegator delegator = dctx.getDelegator();
-        Locale locale = (Locale) context.get("locale");
-        String writeFilters = (String) context.get("writeFilters");
-        GenericValue userLogin = (GenericValue) context.get("userLogin");
-        String entityViewName = (String) context.get("entityViewName");
-
-        ModelEntity modelEntity = delegator.getModelEntity(entityViewName);
-        String contentId = null;
-        Map<String, Object> result = ServiceUtil.returnSuccess();
-        try {
-            Map<String, Object> resultMapsForGeneration = dispatcher.runSync("prepareFlexibleReportFieldsFromEntity", UtilMisc.toMap("modelEntity", modelEntity, "userLogin", userLogin, "locale", locale));
-            if (ServiceUtil.isError(resultMapsForGeneration)) {
-                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resultMapsForGeneration));
-            }
-            Map<String, String> dataMap = (Map<String, String>) resultMapsForGeneration.get("dataMap");
-            Map<String, String> fieldDisplayLabels = null;
-            if (UtilValidate.isNotEmpty(resultMapsForGeneration.get("fieldDisplayLabels"))) {
-                fieldDisplayLabels = (Map<String, String>) resultMapsForGeneration.get("fieldDisplayLabels");
-            }
-            Map<String, String> filterMap = null;
-            if (UtilValidate.isNotEmpty(resultMapsForGeneration.get("filterMap"))) {
-                filterMap = (Map<String, String>) resultMapsForGeneration.get("filterMap");
-            }
-            Map<String, String> filterDisplayLabels = null;
-            if (UtilValidate.isNotEmpty(resultMapsForGeneration.get("filterDisplayLabels"))) {
-                filterDisplayLabels = (Map<String, String>) resultMapsForGeneration.get("filterDisplayLabels");
-            }
-            contentId = BirtWorker.recordReportContent(delegator, dispatcher, context);
-            // callPerformFindFromBirt is the customMethod for Entity workflow
-            String rptDesignFileName = BirtUtil.resolveRptDesignFilePathFromContent(delegator, contentId);
-            GenericValue content = EntityQuery.use(delegator).from("Content").where("contentId", contentId).queryOne();
-            String customMethodId = content.getString("customMethodId");
-            if (UtilValidate.isEmpty(customMethodId)) customMethodId = "CM_FB_PERFORM_FIND";
-            GenericValue customMethod = EntityQuery.use(delegator).from("CustomMethod").where("customMethodId", customMethodId).cache().queryOne();
-            if (customMethod == null) {
-                return ServiceUtil.returnError("CustomMethod not exist : " + customMethodId); //todo labelise
-            }
-            result = dispatcher.runSync("createFlexibleReport", UtilMisc.toMap(
-                    "locale", locale,
-                    "dataMap", dataMap,
-                    "userLogin", userLogin,
-                    "filterMap", filterMap,
-                    "serviceName", customMethod.get("customMethodName"),
-                    "writeFilters", writeFilters,
-                    "rptDesignName", rptDesignFileName,
-                    "fieldDisplayLabels", fieldDisplayLabels,
-                    "filterDisplayLabels", filterDisplayLabels));
-            if (ServiceUtil.isError(result)) {
-                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
-            }
-        } catch (GeneralException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-        result.put("contentId", contentId);
-        return result;
-    }
-
-    /**
-     * Create report design from service master report
-     */
-    public static Map<String, Object> createFlexibleReportFromMasterServiceWorkflow(DispatchContext dctx, Map<String, Object> context) {
-        LocalDispatcher dispatcher = dctx.getDispatcher();
-        Delegator delegator = dctx.getDelegator();
-        Locale locale = (Locale) context.get("locale");
-        String writeFilters = (String) context.get("writeFilters");
-        String serviceName = (String) context.get("serviceName");
-        GenericValue userLogin = (GenericValue) context.get("userLogin");
-        String masterContentId = (String) context.get("masterContentId");
-        String contentId = null;
-        Map<String, Object> result = ServiceUtil.returnSuccess();
-
-        try {
-            GenericValue masterContent = EntityQuery.use(delegator).from("Content").where("contentId", masterContentId).cache().queryOne();
-            String customMethodId = masterContent.getString("customMethodId");
-            if (UtilValidate.isEmpty(customMethodId)) {
-                throw new GeneralException("The master content " + masterContentId + " haven't a customMethod");
-            }
-            GenericValue customMethod = EntityQuery.use(delegator).from("CustomMethod").where("customMethodId", customMethodId).cache().queryOne();
-            if (customMethod == null) {
-                return ServiceUtil.returnError("CustomMethod not exist : " + customMethodId); //todo labelise
-            }
-            String customMethodName = (String) customMethod.getString("customMethodName");
-            if ("default".equalsIgnoreCase(serviceName)) {
-                serviceName = customMethodName + "PrepareFields";
-            }
-            try {
-                ModelService modelService = dctx.getModelService(serviceName);
-            } catch (GenericServiceException e) {
-                return ServiceUtil.returnError("No service define with name " + serviceName); //TODO labelise
-            }
-            contentId = BirtWorker.recordReportContent(delegator, dispatcher, context);
-            String rptDesignFileName = BirtUtil.resolveRptDesignFilePathFromContent(delegator, contentId);
-            Map<String, Object> resultService = dispatcher.runSync(serviceName, UtilMisc.toMap("locale", locale, "userLogin", userLogin));
-            Map<String, String> dataMap = (Map<String, String>) resultService.get("dataMap");
-            Map<String, String> filterMap = (Map<String, String>) resultService.get("filterMap");
-            Map<String, String> fieldDisplayLabels = (Map<String, String>) resultService.get("fieldDisplayLabels");
-            Map<String, String> filterDisplayLabels = (Map<String, String>) resultService.get("filterDisplayLabels");
-            Map<String, Object> resultGeneration = dispatcher.runSync("createFlexibleReport", UtilMisc.toMap(
-                    "locale", locale,
-                    "dataMap", dataMap,
-                    "userLogin", userLogin,
-                    "filterMap", filterMap,
-                    "serviceName", customMethodName,
-                    "writeFilters", writeFilters,
-                    "rptDesignName", rptDesignFileName,
-                    "fieldDisplayLabels", fieldDisplayLabels,
-                    "filterDisplayLabels", filterDisplayLabels));
-            if (ServiceUtil.isError(resultGeneration)) {
-                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCreatingFlexibleReport", locale));
-            }
-        } catch (GeneralException e) {
-            return ServiceUtil.returnError(e.getMessage());
-        }
-        result.put("contentId", contentId);
-        return result;
-    }
-
-    /**
-     * Define which data fields and its label, filter fields and label that will be supported by the View/Entity report design
-     */
-    public static Map<String, Object> prepareFlexibleReportFieldsFromEntity(DispatchContext dctx, Map<String, Object> context) {
-        Locale locale = (Locale) context.get("locale");
-        ModelEntity modelEntity = (ModelEntity) context.get("modelEntity");
-
-        Map<String, String> dataMap = new HashMap<String, String>();
-        Map<String, String> fieldDisplayLabels = new HashMap<String, String>();
-        LinkedHashMap<String, String> filterMap = new LinkedHashMap<String, String>();
-        LinkedHashMap<String, String> filterDisplayLabels = new LinkedHashMap<String, String>();
-
-        List<String> listEntityFields = modelEntity.getAllFieldNames();
-        Map<Object, Object> uiLabelMap = new HashMap<Object, Object>();
-        final String[] resourceGlob = {"OrderUiLabels", "ProductUiLabels", "PartyUiLabels", "ContentUiLabels", "AccountingUiLabels", "CommonUiLabels", "BirtUiLabels"};
-        for (String res : resourceGlob) {
-            uiLabelMap.putAll(UtilProperties.getProperties(res, locale));
-        }
-
-        List<String> excludeFields = modelEntity.getAutomaticFieldNames();
-        for (String field : listEntityFields) {
-            ModelField mField = modelEntity.getField(field);
-            //ignore stamps fields
-            if (excludeFields.contains(mField.getName())) continue;
-            dataMap.put(field, mField.getType());
-
-            String localizedName = null;
-            String interpretedFieldName = null;
-            FlexibleStringExpander.getInstance(mField.getDescription()).expandString(context);
-            String titleFieldName = "FormFieldTitle_".concat(field);
-            localizedName = (String) uiLabelMap.get(titleFieldName);
-            if (UtilValidate.isEmpty(localizedName) || localizedName.equals(titleFieldName)) {
-                interpretedFieldName = FlexibleStringExpander.getInstance(field).expandString(context);
-                fieldDisplayLabels.put(field, interpretedFieldName);
-            } else {
-                fieldDisplayLabels.put(field, localizedName);
-            }
-
-            List<String> fieldTypeWithRangeList = UtilMisc.toList("date", "date-time", "time", "floating-point", "currency-amount", "numeric");
-            if (fieldTypeWithRangeList.contains(mField.getType())) {
-                filterMap.put(field.concat("_fld0_value"), mField.getType());
-                filterMap.put(field.concat("_fld0_op"), "short-varchar");
-                filterMap.put(field.concat("_fld1_value"), mField.getType());
-                filterMap.put(field.concat("_fld1_op"), "short-varchar");
-                filterDisplayLabels.put(field.concat("_fld0_value"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue0", locale)));
-                filterDisplayLabels.put(field.concat("_fld0_op"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue0", locale).concat(UtilProperties.getMessage(resource, "BirtFindCompareOperator", locale))));
-                filterDisplayLabels.put(field.concat("_fld1_value"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue1", locale)));
-                filterDisplayLabels.put(field.concat("_fld1_op"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue1", locale).concat(UtilProperties.getMessage(resource, "BirtFindCompareOperator", locale))));
-            } else { // remaining types need 4 fields (fld0-1_op-value)
-                filterMap.put(field, mField.getType());
-                filterMap.put(field.concat("_op"), "short-varchar");
-                filterDisplayLabels.put(field, fieldDisplayLabels.get(field));
-                filterDisplayLabels.put(field.concat("_op"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindCompareOperator", locale)));
-            }
-        }
-        Map<String, Object> result = ServiceUtil.returnSuccess();
-        result.put("dataMap", dataMap);
-        if (UtilValidate.isNotEmpty(fieldDisplayLabels)) {
-            result.put("fieldDisplayLabels", fieldDisplayLabels);
-        }
-        if (UtilValidate.isNotEmpty(filterMap)) {
-            result.put("filterMap", filterMap);
-        }
-        if (UtilValidate.isNotEmpty(filterDisplayLabels)) {
-            result.put("filterDisplayLabels", filterDisplayLabels);
-        }
-        return result;
-    }
-
-    /**
-     * Prepare and return search form of a report design
-     */
-    public static Map<String, Object> createFormForDisplay(DispatchContext dctx, Map<String, Object> context) {
-        String reportContentId = (String) context.get("reportContentId");
-        Delegator delegator = dctx.getDelegator();
-        Map<String, Object> result = ServiceUtil.returnSuccess();
-
-        String textData = null;
-        try {
-            GenericValue content = EntityQuery.use(delegator).from("Content").where("contentId", reportContentId).cache().queryOne();
-            String dataResourceId = content.getString("dataResourceId");
-            GenericValue electronicText = EntityQuery.use(delegator).from("ElectronicText").where("dataResourceId", dataResourceId).cache().queryOne();
-            textData = electronicText.getString("textData");
-        } catch (GenericEntityException e) {
-            return ServiceUtil.returnError(e.getMessage());
-        }
-
-        if (Debug.infoOn()) Debug.logInfo(textData, module);
-        textData = textData.substring(textData.indexOf("<form "), textData.length());
-        if (textData.contains("</form>")) {
-            textData = textData.substring(0, textData.indexOf("</form>") + 7);
-        } else {
-            textData = textData.substring(0, textData.indexOf("/>") + 2);
-        }
-        textData = StringUtil.replaceString(textData, "$", "&#36;");
-        result.put("textForm", textData);
-        return result;
-    }
-
-    /**
-     * delete all non-master report design
-     */
-    public static Map<String, Object> deleteAllReports(DispatchContext dctx, Map<String, Object> context) {
-        Delegator delegator = dctx.getDelegator();
-        LocalDispatcher dispatcher = dctx.getDispatcher();
-        Locale locale = (Locale) context.get("locale");
-        GenericValue userLogin = (GenericValue) context.get("userLogin");
-
-        List<String> listContentId = null;
-        List<GenericValue> listContent = null;
-        EntityCondition entityConditionContent = EntityCondition.makeCondition("contentTypeId", "FLEXIBLE_REPORT");
-        try {
-            listContent = EntityQuery.use(delegator).from("Content").where(entityConditionContent).select("contentId").queryList();
-        } catch (GenericEntityException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-        if (UtilValidate.isEmpty(listContent)) {
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorNoFlexibleReportToDelete", locale));
-        }
-        listContentId = EntityUtil.getFieldListFromEntityList(listContent, "contentId", true);
-
-        try {
-            for (String contentId : listContentId) {
-                Map<String, Object> returnMap = dispatcher.runSync("deleteFlexibleReport", UtilMisc.toMap("contentId", contentId, "userLogin", userLogin, "locale", locale));
-                ServiceUtil.isError(returnMap);
-            }
-        } catch (GenericServiceException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-        return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtFlexibleReportsSuccessfullyDeleted", locale));
-    }
-
-    /**
-     * Delete a flexible report design
-     */
-    public static Map<String, Object> deleteFlexibleReport(DispatchContext dctx, Map<String, Object> context) {
-        Delegator delegator = dctx.getDelegator();
-        LocalDispatcher dispatcher = dctx.getDispatcher();
-        Locale locale = (Locale) context.get("locale");
-        GenericValue userLogin = (GenericValue) context.get("userLogin");
-        String contentId = (String) context.get("contentId");
-
-        List<GenericValue> listContentRpt = null;
-        List<GenericValue> listRptDesignFileGV = null;
-        String contentIdRpt;
-        try {
-            listContentRpt = EntityQuery.use(delegator).from("ContentAssoc").where("contentId", contentId).select("contentIdTo").queryList();
-            contentIdRpt = listContentRpt.get(0).getString("contentIdTo");
-            List<EntityExpr> listConditions = UtilMisc.toList(EntityCondition.makeCondition("contentTypeId", EntityOperator.EQUALS, "RPTDESIGN"), EntityCondition.makeCondition("contentId", EntityOperator.EQUALS, contentIdRpt));
-            EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(listConditions, EntityOperator.AND);
-            listRptDesignFileGV = EntityQuery.use(delegator).from("ContentDataResourceView").where(ecl).select("drObjectInfo").queryList();
-        } catch (GenericEntityException e1) {
-            e1.printStackTrace();
-            return ServiceUtil.returnError(e1.getMessage());
-        }
-        if (listRptDesignFileGV.size() > 1) {
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorUnexpectedNumberReportToDelete", locale));
-        }
-        List<String> listRptDesignFile = EntityUtil.getFieldListFromEntityList(listRptDesignFileGV, "drObjectInfo", false);
-        String rptfileName = listRptDesignFile.get(0);
-        Path path = Paths.get(rptfileName);
-        try {
-            if (! Files.deleteIfExists(path)) {
-                ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCannotLocateReportFile", locale));
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-        try {
-            delegator.removeByAnd("ContentAttribute", UtilMisc.toMap("contentId", contentId));
-            dispatcher.runSync("removeContentAndRelated", UtilMisc.toMap("contentId", contentId, "userLogin", userLogin, "locale", locale));
-            dispatcher.runSync("removeContentAndRelated", UtilMisc.toMap("contentId", contentIdRpt, "userLogin", userLogin, "locale", locale));
-        } catch (GenericServiceException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        } catch (GenericEntityException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-        return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtFlexibleReportSuccessfullyDeleted", locale));
-    }
-
-    /**
-     * Update birt rptdesign file from uploaded one.
-     * <p>This will update only STYLES, BODY, MASTERPAGE AND CUBES from existing rptdesign with uploaded ones.</p>
-     *
-     */
-    public static Map<String, Object> uploadRptDesign(DispatchContext dctx, Map<String, Object> context) {
-        String dataResourceId = (String) context.get("dataResourceIdRpt");
-        Locale locale = (Locale) context.get("locale");
-        Delegator delegator = dctx.getDelegator();
-        Map<String, Object> result = null;
-        List<String> listSuccessMessage = new ArrayList<String>();
-
-        // the idea is to allow only design to be uploaded. We use the stored file and add the new design from the uploaded file within.
-        DesignConfig config = new DesignConfig();
-        IDesignEngine engine = null;
-        try {
-            Platform.startup();
-            IDesignEngineFactory factory = (IDesignEngineFactory) Platform.createFactoryObject(IDesignEngineFactory.EXTENSION_DESIGN_ENGINE_FACTORY);
-            engine = factory.createDesignEngine(config);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        SessionHandle session = engine.newSessionHandle(ULocale.forLocale(locale));
-
-        // get old file to restore dataset and datasource
-        ByteBuffer newRptDesignBytes = (ByteBuffer) context.get("uploadRptDesign");
-        if (newRptDesignBytes == null) {
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCannotFindUploadedFile", locale));
-        }
-
-        GenericValue dataResource = null;
-        try {
-            dataResource = EntityQuery.use(delegator).from("DataResource").where("dataResourceId", dataResourceId).queryOne();
-        } catch (GenericEntityException e1) {
-            e1.printStackTrace();
-            return ServiceUtil.returnError(e1.getMessage());
-        }
-        String rptDesignName = dataResource.getString("objectInfo");
-        // start Birt API platfrom
-        try {
-            Platform.startup();
-        } catch (BirtException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError("Cannot start Birt platform");
-        }
-
-        // get database design
-        ReportDesignHandle designStored;
-        try {
-            designStored = session.openDesign(rptDesignName);
-        } catch (DesignFileException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-
-        // check if design stored already has a body and delete it to avoid conflicts (taking into account only newly designed body)
-        if (UtilValidate.isNotEmpty(designStored.getBody())) {
-            SlotHandle bodyStored = designStored.getBody();
-
-            Iterator<DesignElementHandle> iter = bodyStored.iterator();
-            while (iter.hasNext()) {
-                try {
-                    iter.remove();
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    return ServiceUtil.returnError(e.getMessage());
-                }
-            }
-        }
-
-        // NEED TO COPY STYLES, BODY, MASTERPAGE AND CUBES; existing elements (in case I missed one):
-        //[styles, parameters, dataSources, dataSets, pageSetup, components, body, scratchPad, templateParameterDefinitions, cubes, themes]
-        // get user design
-        String nameTempRpt = rptDesignName.substring(0, rptDesignName.lastIndexOf('.')).concat("_TEMP_.rptdesign");
-        File file = new File(nameTempRpt);
-        RandomAccessFile out;
-        ReportDesignHandle designFromUser;
-        try {
-            out = new RandomAccessFile(file, "rw");
-            out.write(newRptDesignBytes.array());
-            out.close();
-            designFromUser = session.openDesign(nameTempRpt);
-            // user file is deleted straight away to prevent the use of the report as script entry (security)
-            Path path = Paths.get(nameTempRpt);
-            Files.deleteIfExists(path);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-
-        //copy cube
-        SlotHandle cubesFromUser = designFromUser.getCubes();
-        Iterator<DesignElementHandle> iterCube = cubesFromUser.iterator();
-
-        while (iterCube.hasNext()) {
-            DesignElementHandle item = (DesignElementHandle) iterCube.next();
-            DesignElementHandle copy = item.copy().getHandle(item.getModule());
-            try {
-                designStored.getCubes().add(copy);
-            } catch (Exception e) {
-                e.printStackTrace();
-                return ServiceUtil.returnError(e.getMessage());
-            }
-        }
-
-        // copy body
-        SlotHandle bodyFromUser = designFromUser.getBody();
-        Iterator<DesignElementHandle> iter = bodyFromUser.iterator();
-
-        while (iter.hasNext()) {
-            DesignElementHandle item = (DesignElementHandle) iter.next();
-            DesignElementHandle copy = item.copy().getHandle(item.getModule());
-            try {
-                designStored.getBody().add(copy);
-            } catch (Exception e) {
-                e.printStackTrace();
-                return ServiceUtil.returnError(e.getMessage());
-            }
-        }
-
-        // deleting simple master page from design stored
-        try {
-            List<DesignElementHandle> listMasterPagesStored = designStored.getMasterPages().getContents();
-            for (Object masterPage : listMasterPagesStored) {
-                if (masterPage instanceof SimpleMasterPageHandle) {
-                    designStored.getMasterPages().drop((DesignElementHandle) masterPage);
-                }
-            }
-
-            // adding simple master page => tous ces casts et autres instanceof... c'est laid, mais c'est tellement galère que quand je trouve une solution qui marche... :s
-            List<DesignElementHandle> listMasterPages = designFromUser.getMasterPages().getContents();
-            for (DesignElementHandle masterPage : listMasterPages) {
-                if (masterPage instanceof SimpleMasterPageHandle) {
-                    designStored.getMasterPages().add((SimpleMasterPage) ((SimpleMasterPageHandle) masterPage).copy());
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-
-        // page variables
-        List<VariableElementHandle> pageVariablesUser = designFromUser.getPageVariables();
-        for (VariableElementHandle pageVariable : pageVariablesUser) {
-            try {
-                designStored.setPageVariable(pageVariable.getName(), pageVariable.getPropertyBindingExpression(pageVariable.getName()));
-            } catch (SemanticException e) {
-                e.printStackTrace();
-                return ServiceUtil.returnError(e.getMessage());
-            }
-        }
-
-        // copy styles
-        SlotHandle stylesFromUser = designFromUser.getStyles();
-        SlotHandle stylesStored = designStored.getStyles();
-
-        // getting style names from stored report
-        List<String> listStyleNames = new ArrayList<String>();
-        Iterator<DesignElementHandle> iterStored = stylesStored.iterator();
-        while (iterStored.hasNext()) {
-            DesignElementHandle item = (DesignElementHandle) iterStored.next();
-            listStyleNames.add(item.getName());
-        }
-
-        Iterator<DesignElementHandle> iterUser = stylesFromUser.iterator();
-
-        // adding to styles those which are not already present
-        while (iterUser.hasNext()) {
-            DesignElementHandle item = (DesignElementHandle) iterUser.next();
-            if (! listStyleNames.contains(item.getName())) {
-                DesignElementHandle copy = item.copy().getHandle(item.getModule());
-                try {
-                    designStored.getStyles().add(copy);
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    return ServiceUtil.returnError(e.getMessage());
-                }
-            }
-        }
-
-        try {
-            designStored.saveAs(rptDesignName);
-        } catch (IOException e) {
-            e.printStackTrace();
-            return ServiceUtil.returnError(e.getMessage());
-        }
-        designFromUser.close();
-        designStored.close();
-        if (Debug.infoOn()) Debug.logInfo("####### Design uploaded: ".concat(rptDesignName), module);
-
-        // should we as a secondary safety precaution delete any file finishing with _TEMP_.rptdesign?
-        listSuccessMessage.add(UtilProperties.getMessage(resource, "BirtFlexibleRptDesignSuccessfullyUploaded", locale));
-        result = ServiceUtil.returnSuccess(listSuccessMessage);
-        return result;
-    }
-
+/*******************************************************************************
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ *******************************************************************************/
+package org.apache.ofbiz.birt.flexible;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.ofbiz.base.util.Debug;
+import org.apache.ofbiz.base.util.GeneralException;
+import org.apache.ofbiz.base.util.StringUtil;
+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.UtilXml;
+import org.apache.ofbiz.base.util.string.FlexibleStringExpander;
+import org.apache.ofbiz.birt.BirtWorker;
+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.EntityConditionList;
+import org.apache.ofbiz.entity.condition.EntityExpr;
+import org.apache.ofbiz.entity.condition.EntityOperator;
+import org.apache.ofbiz.entity.model.ModelEntity;
+import org.apache.ofbiz.entity.model.ModelField;
+import org.apache.ofbiz.entity.util.EntityListIterator;
+import org.apache.ofbiz.entity.util.EntityQuery;
+import org.apache.ofbiz.entity.util.EntityUtil;
+import org.apache.ofbiz.service.DispatchContext;
+import org.apache.ofbiz.service.GenericServiceException;
+import org.apache.ofbiz.service.LocalDispatcher;
+import org.apache.ofbiz.service.ModelService;
+import org.apache.ofbiz.service.ServiceUtil;
+import org.eclipse.birt.core.exception.BirtException;
+import org.eclipse.birt.core.framework.Platform;
+import org.eclipse.birt.report.engine.api.script.IReportContext;
+import org.eclipse.birt.report.model.api.DesignConfig;
+import org.eclipse.birt.report.model.api.DesignElementHandle;
+import org.eclipse.birt.report.model.api.DesignFileException;
+import org.eclipse.birt.report.model.api.IDesignEngine;
+import org.eclipse.birt.report.model.api.IDesignEngineFactory;
+import org.eclipse.birt.report.model.api.ReportDesignHandle;
+import org.eclipse.birt.report.model.api.SessionHandle;
+import org.eclipse.birt.report.model.api.SimpleMasterPageHandle;
+import org.eclipse.birt.report.model.api.SlotHandle;
+import org.eclipse.birt.report.model.api.VariableElementHandle;
+import org.eclipse.birt.report.model.api.activity.SemanticException;
+import org.eclipse.birt.report.model.elements.SimpleMasterPage;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.ibm.icu.util.ULocale;
+
+
+/**
+ * Birt Services
+ */
+
+public class BirtServices {
+
+    public static final String module = BirtServices.class.getName();
+    public static final String resource = "BirtUiLabels";
+    public static final String resource_error = "BirtErrorUiLabels";
+    public static final String resourceProduct = "BirtUiLabels";
+
+    /**
+     * Instantiate a new Flexible report, using the data given in parameters and <code>ReportDesignGenerator</code> class.
+     */
+    public static Map<String, Object> createFlexibleReport(DispatchContext dctx, Map<String, Object> context) {
+        ReportDesignGenerator rptGenerator;
+        try {
+            rptGenerator = new ReportDesignGenerator(context, dctx);
+        } catch (Exception e1) {
+            e1.printStackTrace();
+            return ServiceUtil.returnError(e1.getMessage());
+        }
+        try {
+            rptGenerator.buildReport();
+        } catch (Exception e) {
+            Debug.logError(e, module);
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        return ServiceUtil.returnSuccess();
+    }
+
+    @Deprecated
+    public static Map<String, Object> prepareFlexibleReportOptionFieldsFromEntity(DispatchContext dctx, Map<String, Object> context) {
+        String entityViewName = (String) context.get("entityViewName");
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+        List<String> listMultiFields = new ArrayList<String>();
+        Delegator delegator = dctx.getDelegator();
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        Map<String, Object> result = new HashMap<String, Object>();
+        Locale locale = (Locale) context.get("locale");
+
+        ModelEntity modelEntity = delegator.getModelEntity(entityViewName);
+        List<String> listFieldsEntity = modelEntity.getAllFieldNames();
+
+        for (String field : listFieldsEntity) {
+            listMultiFields.add(field);
+            ModelField mField = modelEntity.getField(field);
+            String fieldType = mField.getType();
+            String birtType = null;
+            try {
+                Map<String, Object> convertRes = dispatcher.runSync("convertFieldTypeToBirtType", UtilMisc.toMap("fieldType", fieldType, "userLogin", userLogin));
+                birtType = (String) convertRes.get("birtType");
+                if (UtilValidate.isEmpty(birtType)) {
+                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorConversionFieldToBirtFailed", locale));
+                }
+            } catch (GenericServiceException e) {
+                e.printStackTrace();
+            }
+            // make more general when report forms have been made so too.
+            if (birtType.equalsIgnoreCase("date-time") || birtType.equalsIgnoreCase("date") || birtType.equalsIgnoreCase("time")) {
+                listMultiFields.add(field + "_fld0_op");
+                listMultiFields.add(field + "_fld0_value");
+                listMultiFields.add(field + "_fld1_op");
+                listMultiFields.add(field + "_fld1_value");
+            }
+        }
+        result.put("listMultiFields", listMultiFields);
+        return result;
+    }
+
+    /**
+     * Perform find data on given view/entity and return these into birt compatible format.
+     * This service is meant to be used as default for View/entity report design
+     *
+     */
+    public static Map<String, Object> callPerformFindFromBirt(DispatchContext dctx, Map<String, Object> context) {
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        IReportContext reportContext = (IReportContext) context.get("reportContext");
+        Locale locale = (Locale) context.get("locale");
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+        String entityViewName = (String) reportContext.getParameterValue("modelElementName");
+        Map<String, Object> inputFields = (Map<String, Object>) reportContext.getParameterValue("parameters");
+        Map<String, Object> resultPerformFind = new HashMap<String, Object>();
+        Map<String, Object> resultToBirt = null;
+        List<GenericValue> list = null;
+
+        if (UtilValidate.isEmpty(entityViewName)) {
+            entityViewName = (String) inputFields.get("modelElementName");
+            if (UtilValidate.isEmpty(entityViewName)) {
+                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorEntityViewNotFound", locale));
+            }
+        }
+
+        try {
+            resultPerformFind = dispatcher.runSync("performFind", UtilMisc.<String, Object>toMap("entityName", entityViewName, "inputFields", inputFields, "userLogin", userLogin, "noConditionFind", "Y", "locale", locale));
+            if (ServiceUtil.isError(resultPerformFind)) {
+                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorRunningPerformFind", locale));
+            }
+        } catch (GenericServiceException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+
+        EntityListIterator listIt = (EntityListIterator) resultPerformFind.get("listIt");
+        try {
+            if (UtilValidate.isNotEmpty(listIt)) {
+                list = listIt.getCompleteList();
+                listIt.close();
+            } else {
+                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorRunningPerformFind", locale));
+            }
+        } catch (GenericEntityException e) {
+            e.printStackTrace();
+        }
+        resultToBirt = ServiceUtil.returnSuccess();
+        resultToBirt.put("records", list);
+        return resultToBirt;
+    }
+
+    /**
+     * Analyse given master and create report design from its data
+     * Two cases are implemented :
+     * <ul>
+     *     <li>Entity : data retieval is based on a simple view/entity</li>
+     *     <li>Service : data retrieval is based on service</li>
+     * </ul>
+     */
+    public static Map<String, Object> createFlexibleReportFromMaster(DispatchContext dctx, Map<String, Object> context) {
+        Delegator delegator = dctx.getDelegator();
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        Locale locale = (Locale) context.get("locale");
+
+        String reportName = (String) context.get("reportName");
+        String masterContentId = (String) context.get("contentId");
+        String description = (String) context.get("description");
+        String writeFilters = (String) context.get("writeFilters");
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+
+        GenericValue masterContentAttribute = null;
+        try {
+            EntityCondition entityCondition = EntityCondition.makeCondition("contentId", masterContentId);
+            masterContentAttribute = EntityQuery.use(delegator).from("ContentAttribute").where(entityCondition).queryFirst();
+        } catch (GenericEntityException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+
+        if (masterContentAttribute == null) {
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorNoAttributeFound", locale));
+        }
+        String attrName = masterContentAttribute.getString("attrName");
+        String reportContentId;
+        if (attrName.equalsIgnoreCase("Entity")) {
+            String entityViewName = masterContentAttribute.getString("attrValue");
+                ModelEntity modelEntity = delegator.getModelEntity(entityViewName);
+                if (modelEntity == null) {
+                    return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorEntityViewNotExist", locale) + " " + entityViewName);
+                }
+            try {
+                Map<String, Object> resultContent = dispatcher.runSync("createFlexibleReportFromMasterEntityWorkflow", UtilMisc.toMap("entityViewName", entityViewName, "reportName", reportName, "description", description, "writeFilters", writeFilters, "masterContentId", masterContentId, "userLogin", userLogin, "locale", locale));
+                if(ServiceUtil.isError(resultContent)) {
+                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resultContent));
+                }
+                reportContentId = (String) resultContent.get("contentId");
+            } catch (GenericServiceException e) {
+                e.printStackTrace();
+                return ServiceUtil.returnError(e.getMessage());
+            }
+        } else if (attrName.equalsIgnoreCase("Service")) {
+            String serviceName = masterContentAttribute.getString("attrValue");
+            try {
+                Map<String, Object> resultContent = dispatcher.runSync("createFlexibleReportFromMasterServiceWorkflow", UtilMisc.toMap("serviceName", serviceName, "reportName", reportName, "description", description, "writeFilters", writeFilters, "masterContentId", masterContentId, "userLogin", userLogin, "locale", locale));
+                if (ServiceUtil.isError(resultContent)) {
+                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resultContent));
+                }
+                reportContentId = (String) resultContent.get("contentId");
+            } catch (GenericServiceException e) {
+                e.printStackTrace();
+                return ServiceUtil.returnError(e.getMessage());
+            }
+        } else {
+            // could create other workflows. WebService? Does it need to be independent from Service workflow?
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCannotDetermineDataSource", locale));
+        }
+
+        // prepare report form to display to allow override
+        String textForm;
+        Map<String, Object> resultFormDisplay;
+        try {
+            resultFormDisplay = dispatcher.runSync("prepareFlexibleReportSearchFormToEdit", UtilMisc.toMap("reportContentId", reportContentId, "userLogin", userLogin, "locale", locale));
+            textForm = (String) resultFormDisplay.get("textForm");
+        } catch (GenericServiceException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCreatingDefaultSearchForm", locale).concat(": ").concat(e.getMessage()));
+        }
+
+        Map<String, Object> result = ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtFlexibleReportSuccessfullyGenerated", locale).concat(" ").concat(reportName));
+        result.put("textForm", textForm);
+        result.put("reportContentId", reportContentId);
+        return result;
+    }
+
+    // I'm not a big fan of how I did the createFormForDisplay / overrideReportForm. Could probably be improved using a proper formForReport object or something similar.
+
+    /**
+     * Update search form of a report design
+     */
+    public static Map<String, Object> overrideReportForm(DispatchContext dctx, Map<String, Object> context) {
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        Delegator delegator = dctx.getDelegator();
+        Locale locale = (Locale) context.get("locale");
+        String reportContentId = (String) context.get("reportContentId");
+        String overrideFilters = (String) context.get("overrideFilters");
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+
+        // safety check : do not accept "${groovy", "${bsh" and "javascript"
+        String overideFiltersNoWhiteSpace = overrideFilters.replaceAll("\\s", "");
+        if (overideFiltersNoWhiteSpace.contains("${groovy:") || overideFiltersNoWhiteSpace.contains("${bsh:") || overideFiltersNoWhiteSpace.contains("javascript:")) {
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorUnauthorisedCharacter", locale));
+        }
+
+        try {
+            GenericValue content = EntityQuery.use(delegator).from("Content").where("contentId", reportContentId).queryOne();
+            String dataResourceId = content.getString("dataResourceId");
+            StringBuffer newForm = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?> <forms xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://ofbiz.apache.org/dtds/widget-form.xsd\">");
+            newForm.append(overrideFilters);
+            newForm.append("</forms>");
+            Document xmlForm = UtilXml.readXmlDocument(newForm.toString());
+            dispatcher.runSync("updateElectronicTextForm", UtilMisc.toMap("dataResourceId", dataResourceId, "textData", UtilXml.writeXmlDocument(xmlForm), "userLogin", userLogin, "locale", locale));
+        } catch (GeneralException | SAXException | ParserConfigurationException | IOException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtSearchFormSuccessfullyOverridde", locale));
+    }
+
+    /**
+     * Create report design from View/Entity master report
+     */
+    public static Map<String, Object> createFlexibleReportFromMasterEntityWorkflow(DispatchContext dctx, Map<String, Object> context) {
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        Delegator delegator = dctx.getDelegator();
+        Locale locale = (Locale) context.get("locale");
+        String writeFilters = (String) context.get("writeFilters");
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+        String entityViewName = (String) context.get("entityViewName");
+
+        ModelEntity modelEntity = delegator.getModelEntity(entityViewName);
+        String contentId = null;
+        Map<String, Object> result = ServiceUtil.returnSuccess();
+        try {
+            Map<String, Object> resultMapsForGeneration = dispatcher.runSync("prepareFlexibleReportFieldsFromEntity", UtilMisc.toMap("modelEntity", modelEntity, "userLogin", userLogin, "locale", locale));
+            if (ServiceUtil.isError(resultMapsForGeneration)) {
+                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(resultMapsForGeneration));
+            }
+            Map<String, String> dataMap = (Map<String, String>) resultMapsForGeneration.get("dataMap");
+            Map<String, String> fieldDisplayLabels = null;
+            if (UtilValidate.isNotEmpty(resultMapsForGeneration.get("fieldDisplayLabels"))) {
+                fieldDisplayLabels = (Map<String, String>) resultMapsForGeneration.get("fieldDisplayLabels");
+            }
+            Map<String, String> filterMap = null;
+            if (UtilValidate.isNotEmpty(resultMapsForGeneration.get("filterMap"))) {
+                filterMap = (Map<String, String>) resultMapsForGeneration.get("filterMap");
+            }
+            Map<String, String> filterDisplayLabels = null;
+            if (UtilValidate.isNotEmpty(resultMapsForGeneration.get("filterDisplayLabels"))) {
+                filterDisplayLabels = (Map<String, String>) resultMapsForGeneration.get("filterDisplayLabels");
+            }
+            contentId = BirtWorker.recordReportContent(delegator, dispatcher, context);
+            // callPerformFindFromBirt is the customMethod for Entity workflow
+            String rptDesignFileName = BirtUtil.resolveRptDesignFilePathFromContent(delegator, contentId);
+            GenericValue content = EntityQuery.use(delegator).from("Content").where("contentId", contentId).queryOne();
+            String customMethodId = content.getString("customMethodId");
+            if (UtilValidate.isEmpty(customMethodId)) customMethodId = "CM_FB_PERFORM_FIND";
+            GenericValue customMethod = EntityQuery.use(delegator).from("CustomMethod").where("customMethodId", customMethodId).cache().queryOne();
+            if (customMethod == null) {
+                return ServiceUtil.returnError("CustomMethod not exist : " + customMethodId); //todo labelise
+            }
+            result = dispatcher.runSync("createFlexibleReport", UtilMisc.toMap(
+                    "locale", locale,
+                    "dataMap", dataMap,
+                    "userLogin", userLogin,
+                    "filterMap", filterMap,
+                    "serviceName", customMethod.get("customMethodName"),
+                    "writeFilters", writeFilters,
+                    "rptDesignName", rptDesignFileName,
+                    "fieldDisplayLabels", fieldDisplayLabels,
+                    "filterDisplayLabels", filterDisplayLabels));
+            if (ServiceUtil.isError(result)) {
+                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
+            }
+        } catch (GeneralException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        result.put("contentId", contentId);
+        return result;
+    }
+
+    /**
+     * Create report design from service master report
+     */
+    public static Map<String, Object> createFlexibleReportFromMasterServiceWorkflow(DispatchContext dctx, Map<String, Object> context) {
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        Delegator delegator = dctx.getDelegator();
+        Locale locale = (Locale) context.get("locale");
+        String writeFilters = (String) context.get("writeFilters");
+        String serviceName = (String) context.get("serviceName");
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+        String masterContentId = (String) context.get("masterContentId");
+        String contentId = null;
+        Map<String, Object> result = ServiceUtil.returnSuccess();
+
+        try {
+            GenericValue masterContent = EntityQuery.use(delegator).from("Content").where("contentId", masterContentId).cache().queryOne();
+            String customMethodId = masterContent.getString("customMethodId");
+            if (UtilValidate.isEmpty(customMethodId)) {
+                throw new GeneralException("The master content " + masterContentId + " haven't a customMethod");
+            }
+            GenericValue customMethod = EntityQuery.use(delegator).from("CustomMethod").where("customMethodId", customMethodId).cache().queryOne();
+            if (customMethod == null) {
+                return ServiceUtil.returnError("CustomMethod not exist : " + customMethodId); //todo labelise
+            }
+            String customMethodName = (String) customMethod.getString("customMethodName");
+            if ("default".equalsIgnoreCase(serviceName)) {
+                serviceName = customMethodName + "PrepareFields";
+            }
+            try {
+                ModelService modelService = dctx.getModelService(serviceName);
+            } catch (GenericServiceException e) {
+                return ServiceUtil.returnError("No service define with name " + serviceName); //TODO labelise
+            }
+            contentId = BirtWorker.recordReportContent(delegator, dispatcher, context);
+            String rptDesignFileName = BirtUtil.resolveRptDesignFilePathFromContent(delegator, contentId);
+            Map<String, Object> resultService = dispatcher.runSync(serviceName, UtilMisc.toMap("locale", locale, "userLogin", userLogin));
+            Map<String, String> dataMap = (Map<String, String>) resultService.get("dataMap");
+            Map<String, String> filterMap = (Map<String, String>) resultService.get("filterMap");
+            Map<String, String> fieldDisplayLabels = (Map<String, String>) resultService.get("fieldDisplayLabels");
+            Map<String, String> filterDisplayLabels = (Map<String, String>) resultService.get("filterDisplayLabels");
+            Map<String, Object> resultGeneration = dispatcher.runSync("createFlexibleReport", UtilMisc.toMap(
+                    "locale", locale,
+                    "dataMap", dataMap,
+                    "userLogin", userLogin,
+                    "filterMap", filterMap,
+                    "serviceName", customMethodName,
+                    "writeFilters", writeFilters,
+                    "rptDesignName", rptDesignFileName,
+                    "fieldDisplayLabels", fieldDisplayLabels,
+                    "filterDisplayLabels", filterDisplayLabels));
+            if (ServiceUtil.isError(resultGeneration)) {
+                return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCreatingFlexibleReport", locale));
+            }
+        } catch (GeneralException e) {
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        result.put("contentId", contentId);
+        return result;
+    }
+
+    /**
+     * Define which data fields and its label, filter fields and label that will be supported by the View/Entity report design
+     */
+    public static Map<String, Object> prepareFlexibleReportFieldsFromEntity(DispatchContext dctx, Map<String, Object> context) {
+        Locale locale = (Locale) context.get("locale");
+        ModelEntity modelEntity = (ModelEntity) context.get("modelEntity");
+
+        Map<String, String> dataMap = new HashMap<String, String>();
+        Map<String, String> fieldDisplayLabels = new HashMap<String, String>();
+        LinkedHashMap<String, String> filterMap = new LinkedHashMap<String, String>();
+        LinkedHashMap<String, String> filterDisplayLabels = new LinkedHashMap<String, String>();
+
+        List<String> listEntityFields = modelEntity.getAllFieldNames();
+        Map<Object, Object> uiLabelMap = new HashMap<Object, Object>();
+        final String[] resourceGlob = {"OrderUiLabels", "ProductUiLabels", "PartyUiLabels", "ContentUiLabels", "AccountingUiLabels", "CommonUiLabels", "BirtUiLabels"};
+        for (String res : resourceGlob) {
+            uiLabelMap.putAll(UtilProperties.getProperties(res, locale));
+        }
+
+        List<String> excludeFields = modelEntity.getAutomaticFieldNames();
+        for (String field : listEntityFields) {
+            ModelField mField = modelEntity.getField(field);
+            //ignore stamps fields
+            if (excludeFields.contains(mField.getName())) continue;
+            dataMap.put(field, mField.getType());
+
+            String localizedName = null;
+            String interpretedFieldName = null;
+            FlexibleStringExpander.getInstance(mField.getDescription()).expandString(context);
+            String titleFieldName = "FormFieldTitle_".concat(field);
+            localizedName = (String) uiLabelMap.get(titleFieldName);
+            if (UtilValidate.isEmpty(localizedName) || localizedName.equals(titleFieldName)) {
+                interpretedFieldName = FlexibleStringExpander.getInstance(field).expandString(context);
+                fieldDisplayLabels.put(field, interpretedFieldName);
+            } else {
+                fieldDisplayLabels.put(field, localizedName);
+            }
+
+            List<String> fieldTypeWithRangeList = UtilMisc.toList("date", "date-time", "time", "floating-point", "currency-amount", "numeric");
+            if (fieldTypeWithRangeList.contains(mField.getType())) {
+                filterMap.put(field.concat("_fld0_value"), mField.getType());
+                filterMap.put(field.concat("_fld0_op"), "short-varchar");
+                filterMap.put(field.concat("_fld1_value"), mField.getType());
+                filterMap.put(field.concat("_fld1_op"), "short-varchar");
+                filterDisplayLabels.put(field.concat("_fld0_value"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue0", locale)));
+                filterDisplayLabels.put(field.concat("_fld0_op"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue0", locale).concat(UtilProperties.getMessage(resource, "BirtFindCompareOperator", locale))));
+                filterDisplayLabels.put(field.concat("_fld1_value"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue1", locale)));
+                filterDisplayLabels.put(field.concat("_fld1_op"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindFieldOptionValue1", locale).concat(UtilProperties.getMessage(resource, "BirtFindCompareOperator", locale))));
+            } else { // remaining types need 4 fields (fld0-1_op-value)
+                filterMap.put(field, mField.getType());
+                filterMap.put(field.concat("_op"), "short-varchar");
+                filterDisplayLabels.put(field, fieldDisplayLabels.get(field));
+                filterDisplayLabels.put(field.concat("_op"), fieldDisplayLabels.get(field).concat(UtilProperties.getMessage(resource, "BirtFindCompareOperator", locale)));
+            }
+        }
+        Map<String, Object> result = ServiceUtil.returnSuccess();
+        result.put("dataMap", dataMap);
+        if (UtilValidate.isNotEmpty(fieldDisplayLabels)) {
+            result.put("fieldDisplayLabels", fieldDisplayLabels);
+        }
+        if (UtilValidate.isNotEmpty(filterMap)) {
+            result.put("filterMap", filterMap);
+        }
+        if (UtilValidate.isNotEmpty(filterDisplayLabels)) {
+            result.put("filterDisplayLabels", filterDisplayLabels);
+        }
+        return result;
+    }
+
+    /**
+     * Prepare and return search form of a report design
+     */
+    public static Map<String, Object> createFormForDisplay(DispatchContext dctx, Map<String, Object> context) {
+        String reportContentId = (String) context.get("reportContentId");
+        Delegator delegator = dctx.getDelegator();
+        Map<String, Object> result = ServiceUtil.returnSuccess();
+
+        String textData = null;
+        try {
+            GenericValue content = EntityQuery.use(delegator).from("Content").where("contentId", reportContentId).cache().queryOne();
+            String dataResourceId = content.getString("dataResourceId");
+            GenericValue electronicText = EntityQuery.use(delegator).from("ElectronicText").where("dataResourceId", dataResourceId).cache().queryOne();
+            textData = electronicText.getString("textData");
+        } catch (GenericEntityException e) {
+            return ServiceUtil.returnError(e.getMessage());
+        }
+
+        if (Debug.infoOn()) Debug.logInfo(textData, module);
+        textData = textData.substring(textData.indexOf("<form "), textData.length());
+        if (textData.contains("</form>")) {
+            textData = textData.substring(0, textData.indexOf("</form>") + 7);
+        } else {
+            textData = textData.substring(0, textData.indexOf("/>") + 2);
+        }
+        textData = StringUtil.replaceString(textData, "$", "&#36;");
+        result.put("textForm", textData);
+        return result;
+    }
+
+    /**
+     * delete all non-master report design
+     */
+    public static Map<String, Object> deleteAllReports(DispatchContext dctx, Map<String, Object> context) {
+        Delegator delegator = dctx.getDelegator();
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        Locale locale = (Locale) context.get("locale");
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+
+        List<String> listContentId = null;
+        List<GenericValue> listContent = null;
+        EntityCondition entityConditionContent = EntityCondition.makeCondition("contentTypeId", "FLEXIBLE_REPORT");
+        try {
+            listContent = EntityQuery.use(delegator).from("Content").where(entityConditionContent).select("contentId").queryList();
+        } catch (GenericEntityException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        if (UtilValidate.isEmpty(listContent)) {
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorNoFlexibleReportToDelete", locale));
+        }
+        listContentId = EntityUtil.getFieldListFromEntityList(listContent, "contentId", true);
+
+        try {
+            for (String contentId : listContentId) {
+                Map<String, Object> returnMap = dispatcher.runSync("deleteFlexibleReport", UtilMisc.toMap("contentId", contentId, "userLogin", userLogin, "locale", locale));
+                ServiceUtil.isError(returnMap);
+            }
+        } catch (GenericServiceException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtFlexibleReportsSuccessfullyDeleted", locale));
+    }
+
+    /**
+     * Delete a flexible report design
+     */
+    public static Map<String, Object> deleteFlexibleReport(DispatchContext dctx, Map<String, Object> context) {
+        Delegator delegator = dctx.getDelegator();
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        Locale locale = (Locale) context.get("locale");
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+        String contentId = (String) context.get("contentId");
+
+        List<GenericValue> listContentRpt = null;
+        List<GenericValue> listRptDesignFileGV = null;
+        String contentIdRpt;
+        try {
+            listContentRpt = EntityQuery.use(delegator).from("ContentAssoc").where("contentId", contentId).select("contentIdTo").queryList();
+            contentIdRpt = listContentRpt.get(0).getString("contentIdTo");
+            List<EntityExpr> listConditions = UtilMisc.toList(EntityCondition.makeCondition("contentTypeId", EntityOperator.EQUALS, "RPTDESIGN"), EntityCondition.makeCondition("contentId", EntityOperator.EQUALS, contentIdRpt));
+            EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(listConditions, EntityOperator.AND);
+            listRptDesignFileGV = EntityQuery.use(delegator).from("ContentDataResourceView").where(ecl).select("drObjectInfo").queryList();
+        } catch (GenericEntityException e1) {
+            e1.printStackTrace();
+            return ServiceUtil.returnError(e1.getMessage());
+        }
+        if (listRptDesignFileGV.size() > 1) {
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorUnexpectedNumberReportToDelete", locale));
+        }
+        List<String> listRptDesignFile = EntityUtil.getFieldListFromEntityList(listRptDesignFileGV, "drObjectInfo", false);
+        String rptfileName = listRptDesignFile.get(0);
+        Path path = Paths.get(rptfileName);
+        try {
+            if (! Files.deleteIfExists(path)) {
+                ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCannotLocateReportFile", locale));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        try {
+            delegator.removeByAnd("ContentAttribute", UtilMisc.toMap("contentId", contentId));
+            dispatcher.runSync("removeContentAndRelated", UtilMisc.toMap("contentId", contentId, "userLogin", userLogin, "locale", locale));
+            dispatcher.runSync("removeContentAndRelated", UtilMisc.toMap("contentId", contentIdRpt, "userLogin", userLogin, "locale", locale));
+        } catch (GenericServiceException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        } catch (GenericEntityException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        return ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "BirtFlexibleReportSuccessfullyDeleted", locale));
+    }
+
+    /**
+     * Update birt rptdesign file from uploaded one.
+     * <p>This will update only STYLES, BODY, MASTERPAGE AND CUBES from existing rptdesign with uploaded ones.</p>
+     *
+     */
+    public static Map<String, Object> uploadRptDesign(DispatchContext dctx, Map<String, Object> context) {
+        String dataResourceId = (String) context.get("dataResourceIdRpt");
+        Locale locale = (Locale) context.get("locale");
+        Delegator delegator = dctx.getDelegator();
+        Map<String, Object> result = null;
+        List<String> listSuccessMessage = new ArrayList<String>();
+
+        // the idea is to allow only design to be uploaded. We use the stored file and add the new design from the uploaded file within.
+        DesignConfig config = new DesignConfig();
+        IDesignEngine engine = null;
+        try {
+            Platform.startup();
+            IDesignEngineFactory factory = (IDesignEngineFactory) Platform.createFactoryObject(IDesignEngineFactory.EXTENSION_DESIGN_ENGINE_FACTORY);
+            engine = factory.createDesignEngine(config);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        SessionHandle session = engine.newSessionHandle(ULocale.forLocale(locale));
+
+        // get old file to restore dataset and datasource
+        ByteBuffer newRptDesignBytes = (ByteBuffer) context.get("uploadRptDesign");
+        if (newRptDesignBytes == null) {
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "BirtErrorCannotFindUploadedFile", locale));
+        }
+
+        GenericValue dataResource = null;
+        try {
+            dataResource = EntityQuery.use(delegator).from("DataResource").where("dataResourceId", dataResourceId).queryOne();
+        } catch (GenericEntityException e1) {
+            e1.printStackTrace();
+            return ServiceUtil.returnError(e1.getMessage());
+        }
+        String rptDesignName = dataResource.getString("objectInfo");
+        // start Birt API platfrom
+        try {
+            Platform.startup();
+        } catch (BirtException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError("Cannot start Birt platform");
+        }
+
+        // get database design
+        ReportDesignHandle designStored;
+        try {
+            designStored = session.openDesign(rptDesignName);
+        } catch (DesignFileException e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+
+        // check if design stored already has a body and delete it to avoid conflicts (taking into account only newly designed body)
+        if (UtilValidate.isNotEmpty(designStored.getBody())) {
+            SlotHandle bodyStored = designStored.getBody();
+
+            Iterator<DesignElementHandle> iter = bodyStored.iterator();
+            while (iter.hasNext()) {
+                try {
+                    iter.remove();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return ServiceUtil.returnError(e.getMessage());
+                }
+            }
+        }
+
+        // NEED TO COPY STYLES, BODY, MASTERPAGE AND CUBES; existing elements (in case I missed one):
+        //[styles, parameters, dataSources, dataSets, pageSetup, components, body, scratchPad, templateParameterDefinitions, cubes, themes]
+        // get user design
+        String nameTempRpt = rptDesignName.substring(0, rptDesignName.lastIndexOf('.')).concat("_TEMP_.rptdesign");
+        File file = new File(nameTempRpt);
+        RandomAccessFile out;
+        ReportDesignHandle designFromUser;
+        try {
+            out = new RandomAccessFile(file, "rw");
+            out.write(newRptDesignBytes.array());
+            out.close();
+            designFromUser = session.openDesign(nameTempRpt);
+            // user file is deleted straight away to prevent the use of the report as script entry (security)
+            Path path = Paths.get(nameTempRpt);
+            Files.deleteIfExists(path);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+
+        //copy cube
+        SlotHandle cubesFromUser = designFromUser.getCubes();
+        Iterator<DesignElementHandle> iterCube = cubesFromUser.iterator();
+
+        while (iterCube.hasNext()) {
+            DesignElementHandle item = (DesignElementHandle) iterCube.next();
+            DesignElementHandle copy = item.copy().getHandle(item.getModule());
+            try {
+                designStored.getCubes().add(copy);
+            } catch (Exception e) {
+                e.printStackTrace();
+                return ServiceUtil.returnError(e.getMessage());
+            }
+        }
+
+        // copy body
+        SlotHandle bodyFromUser = designFromUser.getBody();
+        Iterator<DesignElementHandle> iter = bodyFromUser.iterator();
+
+        while (iter.hasNext()) {
+            DesignElementHandle item = (DesignElementHandle) iter.next();
+            DesignElementHandle copy = item.copy().getHandle(item.getModule());
+            try {
+                designStored.getBody().add(copy);
+            } catch (Exception e) {
+                e.printStackTrace();
+                return ServiceUtil.returnError(e.getMessage());
+            }
+        }
+
+        // deleting simple master page from design stored
+        try {
+            List<DesignElementHandle> listMasterPagesStored = designStored.getMasterPages().getContents();
+            for (Object masterPage : listMasterPagesStored) {
+                if (masterPage instanceof SimpleMasterPageHandle) {
+                    designStored.getMasterPages().drop((DesignElementHandle) masterPage);
+                }
+            }
+
+            // adding simple master page => tous ces casts et autres instanceof... c'est laid, mais c'est tellement galère que quand je trouve une solution qui marche... :s
+            List<DesignElementHandle> listMasterPages = designFromUser.getMasterPages().getContents();
+            for (DesignElementHandle masterPage : listMasterPages) {
+                if (masterPage instanceof SimpleMasterPageHandle) {
+                    designStored.getMasterPages().add((SimpleMasterPage) ((SimpleMasterPageHandle) masterPage).copy());
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ServiceUtil.returnError(e.getMessage());
+        }
+
+        // page variables
+        List<VariableElementHandle> pageVariablesUser = designFromUser.getPageVariables();
+        for (VariableElementHandle pageVariable : pageVariablesUser) {
+            try {
+                designStored.setPageVariable(pageVariable.getName(), pageVariable.getPropertyBindingExpression(pageVariable.getName()));
+            } catch (SemanticException e) {
+                e.printStackTrace();
+                return ServiceUtil.returnError(e.getMessage());
+            }
+        }
+
+        // copy styles
+        SlotHandle stylesFromUser = designFromUser.getStyles();
+        SlotHandle stylesStored = designStored.getStyles();
+
+        // getting style names from stored report
+        List<String> listStyleNames = new ArrayList<String>();
+        Iterator<DesignElementHandle> iterStored = stylesStored.iterator();
+        while (iterStored.hasNext()) {
+            DesignElementHandle item = (DesignElementHandle) iterStored.next();
+            listStyleNames.add(item.getName());
+        }
+
+        Iterator<DesignElementHandle> iterUser = stylesFromUser.iterator();
+
+        // adding to styles those which are not already present
+        while (iterUser.hasNext()) {
+            DesignElementHandle item = (DesignElementHandle) iterUser.next();
+            if (! listStyleNames.contains(item.getName())) {

[... 29 lines stripped ...]