From a48920976d451e90a1cb02066abe9ab97efc745e Mon Sep 17 00:00:00 2001
From: Johannes Hoermann <j.hoermann@adito.de>
Date: Fri, 21 Dec 2018 13:38:56 +0100
Subject: [PATCH] Chart fixed

---
 entity/Turnover_entity/Turnover_entity.aod    |  19 +-
 .../recordcontainers/jdito/contentProcess.js  |  98 +++++++--
 .../_____LANGUAGE_EXTRA.aod                   |  69 ++++++
 .../_____LANGUAGE_de/_____LANGUAGE_de.aod     |  70 ++++++-
 .../_____LANGUAGE_en/_____LANGUAGE_en.aod     |  70 +++++++
 .../Turnover_context/Turnover_context.aod     |   1 +
 .../TurnoverChart_view/TurnoverChart_view.aod |  16 +-
 .../example_salesproject/SALESPROJECT_gfk.xml |  65 +++++-
 process/Chart_lib/Chart_lib.aod               |   6 +
 process/Chart_lib/process.js                  | 196 ++++++++++++++++++
 process/Date_lib/process.js                   |  27 +++
 11 files changed, 609 insertions(+), 28 deletions(-)
 create mode 100644 process/Chart_lib/Chart_lib.aod
 create mode 100644 process/Chart_lib/process.js

diff --git a/entity/Turnover_entity/Turnover_entity.aod b/entity/Turnover_entity/Turnover_entity.aod
index a89194ea0f..566034b4f7 100644
--- a/entity/Turnover_entity/Turnover_entity.aod
+++ b/entity/Turnover_entity/Turnover_entity.aod
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.1.0">
   <name>Turnover_entity</name>
+  <title>Turnover</title>
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <recordContainer>jdito</recordContainer>
   <entityFields>
@@ -12,10 +13,22 @@
       <title>Year</title>
     </entityField>
     <entityField>
-      <name>VALUE</name>
+      <name>Y</name>
+      <title>Turnover</title>
     </entityField>
     <entityField>
       <name>PARENT</name>
+      <title>Parent</title>
+    </entityField>
+    <entityField>
+      <name>CATEGORY</name>
+      <title>Category</title>
+    </entityField>
+    <entityField>
+      <name>X</name>
+      <title>Year</title>
+      <contentType>NUMBER</contentType>
+      <outputFormat>0.00#.##</outputFormat>
     </entityField>
   </entityFields>
   <recordContainers>
@@ -26,7 +39,9 @@
       <recordFields>
         <element>UID.value</element>
         <element>PARENT.value</element>
-        <element>VALUE.value</element>
+        <element>CATEGORY.value</element>
+        <element>Y.value</element>
+        <element>X.value</element>
       </recordFields>
     </jDitoRecordContainer>
   </recordContainers>
diff --git a/entity/Turnover_entity/recordcontainers/jdito/contentProcess.js b/entity/Turnover_entity/recordcontainers/jdito/contentProcess.js
index 6c49763a7c..bae3bd0c71 100644
--- a/entity/Turnover_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/Turnover_entity/recordcontainers/jdito/contentProcess.js
@@ -1,22 +1,94 @@
-import("system.logging");
+import("system.datetime");
 import("system.db");
 import("system.result");
+import("system.translate");
+   
+var sumOfMonthTurnover = db.table("select year(SALESORDERDATE) yearNum, 'turnover', month(SALESORDERDATE) monthNum, sum(NET + VAT) from SALESORDER group by year(SALESORDERDATE), month(SALESORDERDATE) order by yearNum, monthNum");
+var sumOfMonthForecast = db.table("select year(DATE_START) yearNum, 'forecast', month(DATE_START) monthNum, sum(VOLUME) from SALESPROJECT_FORECAST group by year(DATE_START), month(DATE_START) order by yearNum, monthNum");
 
-var turnoverData = db.table("select year(SALESORDERDATE) yearNum, 0 monthNum, sum(NET + VAT) from SALESORDER group by year(SALESORDERDATE) "
-                          + " union "
-                          + " select year(SALESORDERDATE) yearNum, month(SALESORDERDATE) monthNum, sum(NET + VAT) from SALESORDER group by year(SALESORDERDATE), month(SALESORDERDATE) "
-                          + " order by yearNum, monthNum");
 
-logging.log(turnoverData.toSource())
+var chartData = [];
 
+var turnoverSkippedCount = 0;
+var forecastSkippedCount = 0;
 
-var chartData = [];                        
-turnoverData.forEach(function(rowData) 
+for (let i = 0; i < 4; i++)
 {
-    var parent = (rowData[1] == 0) ? "" : rowData[0] + "0";
+    var year = i + 2016;
+    
+    _addMonthRows(year);
+}
 
-    chartData.push([rowData[0] + rowData[1], parent, parseFloat(rowData[2])]);
-})
+result.object(chartData);
 
-logging.log(chartData.toSource())
-result.object(chartData);
\ No newline at end of file
+function _addRow(pRow) 
+{
+    //logging.log(pRow.toSource())
+    // month = 0 --> sum of the whole year
+    var parent = "";
+    var dateDisplay = pRow[0];
+    
+    if (pRow[2] != 0) 
+    {
+        parent = pRow[0] + "0" + pRow[1].trim();
+
+        var rowDate = new Date(pRow[0], pRow[2]-1);
+        dateDisplay = datetime.toDate(rowDate.getTime(), "MMM yyyy", "UTC")
+    }
+    
+    chartData.push([pRow[0] + pRow[2] + pRow[1].trim(), parent, 
+                    ((pRow[1].trim() == "turnover") ? translate.text("Turnover") : translate.text("Forecast")), parseFloat(pRow[3]), dateDisplay]);
+}
+
+function _addMonthRows(pYear) 
+{
+    var turnoverSkippedCount = 0;
+    
+    var forecastSkippedCount = 0;
+
+    var turnoverYearSum = 0;
+    var forecastYearSum = 0;
+
+    var filteredTurnover = sumOfMonthTurnover.filter(function(row)
+    {
+        return row[0] == pYear
+    });
+    
+    var filteredForecast = sumOfMonthForecast.filter(function(row)
+    {
+        return row[0] == pYear
+    });
+
+    for (let i = 1; i <= 12; i++) 
+    {
+        var turnoverSum = filteredTurnover[i - turnoverSkippedCount - 1];
+        var forecastSum = filteredForecast[i - forecastSkippedCount - 1];
+        
+        if (turnoverSum != undefined && turnoverSum[0] == pYear && turnoverSum[2] == i.toString()) 
+        {
+            _addRow(turnoverSum);
+            turnoverYearSum += turnoverSum[3];
+        }
+        else
+        {
+            _addRow([year.toString(), 'turnover', i, 0.0]);
+            
+            turnoverSkippedCount++;
+        }
+        
+        if (forecastSum != undefined && forecastSum[0] == pYear && forecastSum[2] == i) 
+        {
+            _addRow(forecastSum);
+            forecastYearSum += forecastSum[3];
+        }
+        else
+        {
+            _addRow([year.toString(), 'forecast', i, 0.0]);
+            
+            forecastSkippedCount++;
+        }
+    }
+    
+    _addRow([year.toString(), 'turnover', 0, turnoverYearSum]);
+    _addRow([year.toString(), 'forecast', 0, forecastYearSum]);
+}
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index 8421659974..7a003b3111 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -1257,6 +1257,75 @@
     <entry>
       <key>Receipt</key>
     </entry>
+    <entry>
+      <key>Receipt number</key>
+    </entry>
+    <entry>
+      <key>Year</key>
+    </entry>
+    <entry>
+      <key>New receipt version</key>
+    </entry>
+    <entry>
+      <key>Orderitems</key>
+    </entry>
+    <entry>
+      <key>Nur Eigene anzeigen</key>
+    </entry>
+    <entry>
+      <key>Sent receipts</key>
+    </entry>
+    <entry>
+      <key>asdfgsdfg</key>
+    </entry>
+    <entry>
+      <key>Copy receipt</key>
+    </entry>
+    <entry>
+      <key>Orderitem</key>
+    </entry>
+    <entry>
+      <key>The order number already exists!</key>
+    </entry>
+    <entry>
+      <key>July</key>
+    </entry>
+    <entry>
+      <key>June</key>
+    </entry>
+    <entry>
+      <key>October</key>
+    </entry>
+    <entry>
+      <key>November</key>
+    </entry>
+    <entry>
+      <key>December</key>
+    </entry>
+    <entry>
+      <key>Turnover</key>
+    </entry>
+    <entry>
+      <key>May</key>
+    </entry>
+    <entry>
+      <key>April</key>
+    </entry>
+    <entry>
+      <key>January</key>
+    </entry>
+    <entry>
+      <key>March</key>
+    </entry>
+    <entry>
+      <key>September</key>
+    </entry>
+    <entry>
+      <key>August</key>
+    </entry>
+    <entry>
+      <key>February</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
   <sqlModels>
diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
index f71aaa1d7c..4dcd088702 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -14,6 +14,10 @@
       <key>German (Austria)</key>
       <value>Deutsch (Österreich)</value>
     </entry>
+    <entry>
+      <key>Turnover</key>
+      <value>Umsatz</value>
+    </entry>
     <entry>
       <key>E-Mail</key>
       <value>E-Mail</value>
@@ -1106,7 +1110,7 @@
     </entry>
     <entry>
       <key>Forecast</key>
-      <value>Vorhersage</value>
+      <value>Forecast</value>
     </entry>
     <entry>
       <key>Vorschau</key>
@@ -1554,6 +1558,70 @@
     <entry>
       <key>My histories</key>
     </entry>
+    <entry>
+      <key>Year</key>
+      <value>Jahr</value>
+    </entry>
+    <entry>
+      <key>New receipt version</key>
+    </entry>
+    <entry>
+      <key>Orderitems</key>
+    </entry>
+    <entry>
+      <key>Nur Eigene anzeigen</key>
+    </entry>
+    <entry>
+      <key>Sent receipts</key>
+    </entry>
+    <entry>
+      <key>asdfgsdfg</key>
+    </entry>
+    <entry>
+      <key>Copy receipt</key>
+    </entry>
+    <entry>
+      <key>Orderitem</key>
+    </entry>
+    <entry>
+      <key>The order number already exists!</key>
+    </entry>
+    <entry>
+      <key>July</key>
+    </entry>
+    <entry>
+      <key>June</key>
+    </entry>
+    <entry>
+      <key>October</key>
+    </entry>
+    <entry>
+      <key>November</key>
+    </entry>
+    <entry>
+      <key>December</key>
+    </entry>
+    <entry>
+      <key>May</key>
+    </entry>
+    <entry>
+      <key>April</key>
+    </entry>
+    <entry>
+      <key>January</key>
+    </entry>
+    <entry>
+      <key>March</key>
+    </entry>
+    <entry>
+      <key>September</key>
+    </entry>
+    <entry>
+      <key>August</key>
+    </entry>
+    <entry>
+      <key>February</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index 6d2ac1196d..b006353a0a 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -1274,6 +1274,76 @@
     <entry>
       <key>Receipt</key>
     </entry>
+    <entry>
+      <key>Receipt number</key>
+    </entry>
+    <entry>
+      <key>Year</key>
+    </entry>
+    <entry>
+      <key>New receipt version</key>
+    </entry>
+    <entry>
+      <key>Orderitems</key>
+    </entry>
+    <entry>
+      <key>Nur Eigene anzeigen</key>
+    </entry>
+    <entry>
+      <key>Sent receipts</key>
+    </entry>
+    <entry>
+      <key>asdfgsdfg</key>
+    </entry>
+    <entry>
+      <key>Copy receipt</key>
+    </entry>
+    <entry>
+      <key>Orderitem</key>
+    </entry>
+    <entry>
+      <key>Turnover</key>
+      <value></value>
+    </entry>
+    <entry>
+      <key>The order number already exists!</key>
+    </entry>
+    <entry>
+      <key>July</key>
+    </entry>
+    <entry>
+      <key>June</key>
+    </entry>
+    <entry>
+      <key>October</key>
+    </entry>
+    <entry>
+      <key>November</key>
+    </entry>
+    <entry>
+      <key>December</key>
+    </entry>
+    <entry>
+      <key>May</key>
+    </entry>
+    <entry>
+      <key>April</key>
+    </entry>
+    <entry>
+      <key>January</key>
+    </entry>
+    <entry>
+      <key>March</key>
+    </entry>
+    <entry>
+      <key>September</key>
+    </entry>
+    <entry>
+      <key>August</key>
+    </entry>
+    <entry>
+      <key>February</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/neonContext/Turnover_context/Turnover_context.aod b/neonContext/Turnover_context/Turnover_context.aod
index eaffc6c207..ce98896be7 100644
--- a/neonContext/Turnover_context/Turnover_context.aod
+++ b/neonContext/Turnover_context/Turnover_context.aod
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.0.0">
   <name>Turnover_context</name>
+  <title>Turnover</title>
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <mainview>TurnoverChart_view</mainview>
   <entity>Turnover_entity</entity>
diff --git a/neonView/TurnoverChart_view/TurnoverChart_view.aod b/neonView/TurnoverChart_view/TurnoverChart_view.aod
index 3b35909f66..059902b9df 100644
--- a/neonView/TurnoverChart_view/TurnoverChart_view.aod
+++ b/neonView/TurnoverChart_view/TurnoverChart_view.aod
@@ -10,10 +10,22 @@
   <children>
     <multiDataChartViewTemplate>
       <name>TurnoverChart_template</name>
+      <chartTitle>Turnover</chartTitle>
       <chartType>COLUMN</chartType>
-      <xAxis>UID</xAxis>
-      <yAxis>VALUE</yAxis>
+      <xAxis>X</xAxis>
+      <yAxis>Y</yAxis>
       <parentField>PARENT</parentField>
+      <categoryField>CATEGORY</categoryField>
+      <entityField>#ENTITY</entityField>
+    </multiDataChartViewTemplate>
+    <multiDataChartViewTemplate>
+      <name>TurnoverLinesChart_template</name>
+      <chartTitle>Turnover</chartTitle>
+      <chartType>SPLINE</chartType>
+      <xAxis>X</xAxis>
+      <yAxis>Y</yAxis>
+      <parentField>PARENT</parentField>
+      <categoryField>CATEGORY</categoryField>
       <entityField>#ENTITY</entityField>
     </multiDataChartViewTemplate>
   </children>
diff --git a/others/db_changes/data/example_salesproject/SALESPROJECT_gfk.xml b/others/db_changes/data/example_salesproject/SALESPROJECT_gfk.xml
index 94038760b1..76a6018c9d 100644
--- a/others/db_changes/data/example_salesproject/SALESPROJECT_gfk.xml
+++ b/others/db_changes/data/example_salesproject/SALESPROJECT_gfk.xml
@@ -4,7 +4,7 @@
     <insert tableName="SALESPROJECT">
         <column name="SALESPROJECTID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
         <column name="USER_NEW" value="admin"/>
-        <column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
+        <column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
         <column name="PROJECTCODE" valueNumeric="1000"/>
         <column name="PROJECTTITLE" value="GfK"/>
         <column name="RELATION_ID" value="b219b58a-f120-42d8-9a64-0b176501eac7"/>
@@ -23,7 +23,7 @@
     <insert tableName="SALESPROJECT_SOURCE">
         <column name="SALESPROJECT_SOURCEID" value="1c1f83ad-9e4b-4d0f-b820-98e724e34aec"/>
         <column name="USER_NEW" value="admin"/>
-        <column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
+        <column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
         <column name="ENTRYDATE" valueDate="2017-08-21T09:03:43"/>
         <column name="INFO" value="Initialeintrag"/>
         <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
@@ -33,12 +33,12 @@
     <insert tableName="SALESPROJECT_CYCLE">
         <column name="SALESPROJECT_CYCLEID" value="c1eb7a04-666f-4bb0-8021-3feadff5d5df"/>
         <column name="USER_NEW" value="admin"/>
-        <column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
+        <column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
         <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
         <column name="TYPE" valueNumeric="1"/>
         <column name="VALUE" valueNumeric="1"/>
-        <column name="DATE_START" valueDate="2018-06-13T09:03:43"/>
-        <column name="DATE_END" valueDate="2018-06-13T09:03:43"/>
+        <column name="DATE_START" valueDate="2016-06-13T09:03:43"/>
+        <column name="DATE_END" valueDate="2016-06-13T09:03:43"/>
     </insert>
     
     <insert tableName="SALESPROJECT_FORECAST">
@@ -53,15 +53,60 @@
         <column name="INFO" value="grob abgeschätzt, da große Unsicherheit"/>
 
         <column name="DATE_START" valueDate="2018-06-13T09:03:43"/>
-        <column name="VOLUME" valueNumeric="15"/>
+        <column name="VOLUME" valueNumeric="100"/>
+    </insert>
+
+    <insert tableName="SALESPROJECT_FORECAST">
+        <column name="SALESPROJECT_FORECASTID" value="35f5f997-cc23-4850-8e71-b497bb7d12d6"/>
+        <column name="USER_NEW" value="admin"/>
+        <column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
+        <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
+        <column name="RELATION_ID" value="b219b58a-f120-42d8-9a64-0b176501eac7"/>
+
+        <column name="TYPE" value="PLAN"/>
+        <column name="GROUPCODE" valueNumeric="1"/>
+        <column name="INFO" value="grob abgeschätzt, da große Unsicherheit"/>
+
+        <column name="DATE_START" valueDate="2016-06-13T09:03:43"/>
+        <column name="VOLUME" valueNumeric="150"/>
+    </insert>
+
+    <insert tableName="SALESPROJECT_FORECAST">
+        <column name="SALESPROJECT_FORECASTID" value="625dd1eb-3d60-4818-8e9a-c55650d7fd87"/>
+        <column name="USER_NEW" value="admin"/>
+        <column name="DATE_NEW" valueDate="2017-06-13T09:03:43"/>
+        <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
+        <column name="RELATION_ID" value="b219b58a-f120-42d8-9a64-0b176501eac7"/>
+
+        <column name="TYPE" value="PLAN"/>
+        <column name="GROUPCODE" valueNumeric="1"/>
+        <column name="INFO" value="grob abgeschätzt, da große Unsicherheit"/>
+
+        <column name="DATE_START" valueDate="2017-06-13T09:03:43"/>
+        <column name="VOLUME" valueNumeric="500"/>
+    </insert>
+    
+    <insert tableName="SALESPROJECT_FORECAST">
+        <column name="SALESPROJECT_FORECASTID" value="c2b3303e-4a11-455c-b214-16400f9d8c16"/>
+        <column name="USER_NEW" value="admin"/>
+        <column name="DATE_NEW" valueDate="2017-05-13T09:03:43"/>
+        <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
+        <column name="RELATION_ID" value="b219b58a-f120-42d8-9a64-0b176501eac7"/>
+
+        <column name="TYPE" value="PLAN"/>
+        <column name="GROUPCODE" valueNumeric="1"/>
+        <column name="INFO" value="grob abgeschätzt, da große Unsicherheit"/>
+
+        <column name="DATE_START" valueDate="2017-05-13T09:03:43"/>
+        <column name="VOLUME" valueNumeric="600"/>
     </insert>
 
     <insert tableName="SALESPROJECT_COMPETITION">
         <column name="SALESPROJECT_COMPETITIONID" value="a3ae9702-a3da-4d5f-a3ab-e386c8a0ac40"/>
         <column name="USER_NEW" value="admin"/>
-        <column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
+        <column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
         <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
-        <column name="DATE_CANCELLED" valueDate="2018-06-13T09:03:43"/>
+        <column name="DATE_CANCELLED" valueDate="2016-06-13T09:03:43"/>
         <column name="INFO" value="starkes Prozess Know-How, wird gefährlich für uns. Dazu private Verbindungen"/>
         <column name="RELATION_ID" value="eda61ea6-35ed-4a92-a93c-6118fc67d533"/>
         <column name="STATUS" valueNumeric="1"/>
@@ -70,7 +115,7 @@
     <insert tableName="SALESPROJECT_MEMBER">
         <column name="SALESPROJECT_MEMBERID" value="f9dc15c0-91b8-43d3-ba98-80ca581db3a3"/>
         <column name="USER_NEW" value="admin"/>
-        <column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
+        <column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
         <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
         <column name="RELATION_ID" value="73d731a2-e7f5-11e8-9f32-f2801f1b9fd1"/>
         <column name="SALESPROJECT_ROLE" valueNumeric="1"/>
@@ -79,7 +124,7 @@
     <insert tableName="SALESPROJECT_CLASSIFICATION">
         <column name="SALESPROJECT_CLASSIFICATIONID" value="77da9dcb-b49a-4608-9c7d-68545b0ec29b"/>
         <column name="USER_NEW" value="admin"/>
-        <column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
+        <column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
         <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
         
         <column name="CLASS" valueNumeric="1"/>
diff --git a/process/Chart_lib/Chart_lib.aod b/process/Chart_lib/Chart_lib.aod
new file mode 100644
index 0000000000..311f282232
--- /dev/null
+++ b/process/Chart_lib/Chart_lib.aod
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.7" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.1.7">
+  <name>Chart_lib</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <process>%aditoprj%/process/Chart_lib/process.js</process>
+</process>
diff --git a/process/Chart_lib/process.js b/process/Chart_lib/process.js
new file mode 100644
index 0000000000..ea4a62f24d
--- /dev/null
+++ b/process/Chart_lib/process.js
@@ -0,0 +1,196 @@
+import("system.util");
+import("system.report");
+import("system.neon");
+import("system.vars");
+
+
+
+
+var sumOfMonthTurnover = db.table("select year(SALESORDERDATE) yearNum, 'turnover', month(SALESORDERDATE) monthNum, sum(NET + VAT) from SALESORDER group by year(SALESORDERDATE), month(SALESORDERDATE) order by yearNum, monthNum");
+var sumOfMonthForecast = db.table("select year(DATE_START) yearNum, 'forecast', month(DATE_START) monthNum, sum(VOLUME) from SALESPROJECT_FORECAST group by year(DATE_START), month(DATE_START) order by yearNum, monthNum");
+
+
+var chartData = [];
+
+var turnoverSkippedCount = 0;
+var forecastSkippedCount = 0;
+
+for (let i = 0; i < 4; i++)
+{
+    var year = i + 2016;
+    
+    _addMonthRows(year);
+}
+
+result.object(chartData);
+
+function _addRow(pRow) 
+{
+    //logging.log(pRow.toSource())
+    // month = 0 --> sum of the whole year
+    var parent = "";
+    var dateDisplay = pRow[0];
+    
+    if (pRow[2] != 0) 
+    {
+        parent = pRow[0] + "0" + pRow[1].trim();
+
+        var rowDate = new Date(pRow[0], pRow[2]-1);
+        dateDisplay = datetime.toDate(rowDate.getTime(), "MMM yyyy", "UTC")
+    }
+    
+    chartData.push([pRow[0] + pRow[2] + pRow[1].trim(), parent, 
+                    ((pRow[1].trim() == "turnover") ? translate.text("Turnover") : translate.text("Forecast")), parseFloat(pRow[3]), dateDisplay]);
+}
+
+function _addMonthRows(pYear) 
+{
+    var turnoverSkippedCount = 0;
+   // var turnoverNotCorrectYearCount = 0;
+    
+    var forecastSkippedCount = 0;
+    var forecastNotCorrectYearCount = 0;
+
+    var turnoverYearSum = 0;
+    var forecastYearSum = 0;
+
+    var filteredTurnover = sumOfMonthTurnover.filter(function(row)
+    {
+        return row[0] == pYear
+    });
+    
+    var filteredForecast = sumOfMonthForecast.filter(function(row)
+    {
+        return row[0] == pYear
+    });
+
+    for (let i = 1; i <= 12; i++) 
+    {
+        var turnoverSum = filteredTurnover[i - turnoverSkippedCount - 1];
+        var forecastSum = filteredForecast[i - forecastSkippedCount - 1];
+        
+        if (turnoverSum != undefined && turnoverSum[0] == pYear && turnoverSum[2] == i.toString()) 
+        {
+            _addRow(turnoverSum);
+            turnoverYearSum += turnoverSum[3];
+        }
+        else
+        {
+            _addRow([year.toString(), 'turnover', i, 0.0]);
+            
+            turnoverSkippedCount++;
+        }
+        
+        if (forecastSum != undefined && forecastSum[0] == pYear && forecastSum[2] == i) 
+        {
+            _addRow(forecastSum);
+            forecastYearSum += forecastSum[3];
+        }
+        else
+        {
+            _addRow([year.toString(), 'forecast', i, 0.0]);
+            
+            forecastSkippedCount++;
+        }
+    }
+    
+    _addRow([year.toString(), 'turnover', 0, turnoverYearSum]);
+    _addRow([year.toString(), 'forecast', 0, forecastYearSum]);
+}
+
+
+
+
+/**
+ *  
+ * @class
+ */
+function MultiDataChart() 
+{
+    this._ID = 0;
+    this._GROUP = 1;
+    this._X = 2;
+    this._Y = 3;
+    
+    this.dataSources = {};
+    this.drilldowns = {};
+    this._resultData = [];
+}
+
+MultiDataChart.begin = function() 
+{
+    var chart = new MultiDataChart();    
+    return chart;
+}
+
+/**
+ * Add a new datasource
+ * Has to be an array with [[id, x, y, ...], [id, x, y, ...]]
+ * ... means you can add additional columns, used as identification and naming of drilldowns
+ */
+MultiDataChart.prototype.addDataSource = function(pName, pData) 
+{        
+    this.dataSources[pName] = pData;
+    
+    return this;
+}
+
+/**
+ * 
+ */
+MultiDataChart.prototype.addCumulativeDrillDown = function(pDataSourceName, pGetParentXCallback, pGetCummulationCallback) 
+{        
+    if (this.dataSources[pDataSourceName] != undefined) 
+    {
+        this.drilldowns[pDataSourceName].type = "cumulative";
+        this.drilldowns[pDataSourceName].dataSource = pDataSourceName;
+        this.drilldowns[pDataSourceName].getParentX = pGetParentXCallback;
+        this.drilldowns[pDataSourceName].getCumulation = pGetCummulationCallback;
+    }
+    else 
+    {
+        throw Error("MultiDataChart::addCumulativeDrillDown: Data source " + pDataSourceName + " doesn't exist!");
+    }
+    
+    return this;
+}
+
+/**
+ * 
+ */
+MultiDataChart.prototype.build = function() 
+{        
+    for (dataSource in this.dataSources)
+    {
+        for (let i = 0; i < dataSources[dataSource].length; i++) 
+        {
+            var dataRow = dataSources[dataSource][i];
+            var rowId = util.getNewUUID();
+                                  // id, parent, group,     x,                      y
+            this._resultData.push([rowId, "", dataSource, dataRow[this._X], dataRow[this._Y]]);
+        }
+    }
+    
+}
+
+MultiDataChart.prototype._processDrilldowns = function()
+{
+    for (drilldown in this.drilldowns)
+    {
+        if (drilldown.type == "cumulative")
+        {
+            this._processCumulativeDrilldown(drilldown);
+        }
+    }
+}
+
+MultiDataChart.prototype._processCumulativeDrilldown = function(pDrilldown)
+{
+    var parentId = util.getNewUUID();
+    var data = this.dataSources[pDrilldown.dataSource];
+    
+    
+    
+    
+   
+}
\ No newline at end of file
diff --git a/process/Date_lib/process.js b/process/Date_lib/process.js
index 45a470d898..8f202fd19a 100644
--- a/process/Date_lib/process.js
+++ b/process/Date_lib/process.js
@@ -47,4 +47,31 @@ DateUtils.getDateIncrementedByYears = function(pDate, pYears) {
     var dateObj = new Date(pDate);
 
     return dateObj.setFullYear(dateObj.getFullYear() + pYears);
+}
+
+/**
+ * get Month name
+ * 
+ * @param pMonth {Number} starting with 0 as Janur
+ * 
+ * @result {String} translated name
+ */
+DateUtils.getDateIncrementedByYears = function(pDate, pYears) {
+    var monthNames = [
+        translate.text("January"),
+        translate.text("February"),
+        translate.text("March"),
+        translate.text("April"),
+        translate.text("May"),
+        translate.text("June"),
+        translate.text("July"),
+        translate.text("August"),
+        translate.text("September"),
+        translate.text("October"),
+        translate.text("November"),
+        translate.text("December")
+    ];
+    
+    
+    return 
 }
\ No newline at end of file
-- 
GitLab