diff --git a/entity/Prod2prod_entity/recordcontainers/jdito/contentProcess.js b/entity/Prod2prod_entity/recordcontainers/jdito/contentProcess.js
index cc59867417742782db05363c91d242b7078b4a12..7a8d1f20d335178965e37be3e00f04dfe3ce9c80 100644
--- a/entity/Prod2prod_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/Prod2prod_entity/recordcontainers/jdito/contentProcess.js
@@ -1,16 +1,15 @@
-import("system.logging");
-import("system.result");
-import("system.vars");
-import("system.db");
-import("system.util");
-import("Product_lib");
-
-var prodid = vars.exists("$param.ProductId_param") 
-             && vars.get("$param.ProductId_param") != null ? vars.get("$param.ProductId_param") : "";
-
-if(prodid != "")
-{
-    var p2pUtils = new Prod2ProdUtils(prodid);
-    logging.log("casllllldsfasdf")
-    result.object(p2pUtils.getPartsListForRecordContainer());
+import("system.logging");
+import("system.result");
+import("system.vars");
+import("system.db");
+import("system.util");
+import("Product_lib");
+
+var prodid = vars.exists("$param.ProductId_param") 
+             && vars.get("$param.ProductId_param") != null ? vars.get("$param.ProductId_param") : "";
+
+if(prodid != "")
+{
+    var p2pUtils = new Prod2ProdUtils(prodid);
+    result.object(p2pUtils.getPartsListForRecordContainer());
 }
\ No newline at end of file
diff --git a/entity/Turnover_entity/Turnover_entity.aod b/entity/Turnover_entity/Turnover_entity.aod
index 070f9fbec3fe347a3d33533f85d8bbc43599f7aa..6a0ee256eb1d71d153189fb92dc1930736e91821 100644
--- a/entity/Turnover_entity/Turnover_entity.aod
+++ b/entity/Turnover_entity/Turnover_entity.aod
@@ -1,48 +1,48 @@
-<?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.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.1.1">
-  <name>Turnover_entity</name>
-  <title>Turnover</title>
-  <majorModelMode>DISTRIBUTED</majorModelMode>
-  <iconId>VAADIN:CHART</iconId>
-  <recordContainer>jdito</recordContainer>
-  <entityFields>
-    <entityIncomingField>
-      <name>#INCOMING</name>
-    </entityIncomingField>
-    <entityField>
-      <name>UID</name>
-      <title>Year</title>
-    </entityField>
-    <entityField>
-      <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>TEXT</contentType>
-    </entityField>
-  </entityFields>
-  <recordContainers>
-    <jDitoRecordContainer>
-      <name>jdito</name>
-      <jDitoRecordAlias>Data_alias</jDitoRecordAlias>
-      <contentProcess>%aditoprj%/entity/Turnover_entity/recordcontainers/jdito/contentProcess.js</contentProcess>
-      <recordFields>
-        <element>UID.value</element>
-        <element>PARENT.value</element>
-        <element>CATEGORY.value</element>
-        <element>Y.value</element>
-        <element>X.value</element>
-      </recordFields>
-    </jDitoRecordContainer>
-  </recordContainers>
-</entity>
+<?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.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.1.1">
+  <name>Turnover_entity</name>
+  <title>Turnover</title>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <iconId>VAADIN:CHART</iconId>
+  <recordContainer>jdito</recordContainer>
+  <entityFields>
+    <entityIncomingField>
+      <name>#INCOMING</name>
+    </entityIncomingField>
+    <entityField>
+      <name>UID</name>
+      <title>Year</title>
+    </entityField>
+    <entityField>
+      <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>TEXT</contentType>
+    </entityField>
+  </entityFields>
+  <recordContainers>
+    <jDitoRecordContainer>
+      <name>jdito</name>
+      <jDitoRecordAlias>Data_alias</jDitoRecordAlias>
+      <contentProcess>%aditoprj%/entity/Turnover_entity/recordcontainers/jdito/contentProcess.js</contentProcess>
+      <recordFields>
+        <element>UID.value</element>
+        <element>PARENT.value</element>
+        <element>CATEGORY.value</element>
+        <element>X.value</element>
+        <element>Y.value</element>
+      </recordFields>
+    </jDitoRecordContainer>
+  </recordContainers>
+</entity>
diff --git a/entity/Turnover_entity/recordcontainers/jdito/contentProcess.js b/entity/Turnover_entity/recordcontainers/jdito/contentProcess.js
index 3257897d9afb781e79d83c1472aacc7f9902cfe6..6311570e483af04b989aec396bd9145eed0bd42a 100644
--- a/entity/Turnover_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/Turnover_entity/recordcontainers/jdito/contentProcess.js
@@ -1,112 +1,83 @@
-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 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 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 += parseInt(turnoverSum[3]);
-        }
-        else
-        {
-            _addRow([year.toString(), 'turnover', i, 0.0]);
-            
-            turnoverSkippedCount++;
-        }
-        
-        if (forecastSum != undefined && forecastSum[0] == pYear && forecastSum[2] == i) 
-        {
-            _addRow(forecastSum);
-            forecastYearSum += parseInt(forecastSum[3]);
-        }
-        else
-        {
-            _addRow([year.toString(), 'forecast', i, 0.0]);
-            
-            forecastSkippedCount++;
-        }
-    }
-    
-    _addRow([year.toString(), 'turnover', 0, turnoverYearSum]);
-    _addRow([year.toString(), 'forecast', 0, forecastYearSum]);
-}
-
-
-/*
- * 
- * import("system.datetime");
-import("system.db");
-import("system.result");
-import("system.translate");
-import("Chart_lib");
-// [[id, x, y, ...], [x, y, ...]]
-var sumOfMonthTurnover = db.table("select year(SALESORDERDATE) yearNum, sum(NET + VAT) from SALESORDER where year(SALESORDERDATE) <> 2017 group by year(SALESORDERDATE) order by yearNum");
-var sumOfMonthForecast = db.table("select year(DATE_START) yearNum, sum(VOLUME) from SALESPROJECT_FORECAST group by year(DATE_START) order by yearNum");
-
-var chart = MultiDataChart.begin();
-
-chart.addDataSource(translate.text("Turnover"), sumOfMonthTurnover)
-     .addDataSource(translate.text("Forecast"), sumOfMonthForecast)
- */
\ No newline at end of file
+import("system.logging");
+import("system.datetime");
+import("system.db");
+import("system.result");
+import("system.translate");
+import("Data_lib");
+
+// load data
+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 * 1000) from SALESPROJECT_FORECAST group by year(DATE_START), month(DATE_START) order by yearNum, monthNum");
+
+// build chartData
+var rootNode = "";
+var chartData = ParentingData.begin(rootNode);
+
+var skippedCounts = {};
+
+    
+for (let i = 0; i < 4; i++)
+{
+    // TODO: currently years are hardcoded.
+    var year = i + 2016;
+    
+    var turnoverYearSum = 0;
+    var forecastYearSum = 0;
+    
+    // filter data by current year
+    var turnoverYearData = sumOfMonthTurnover.filter(function(row)
+    {
+        return row[0] == year
+    });
+    
+    var forecastYearData = sumOfMonthForecast.filter(function(row)
+    {
+        return row[0] == year
+    });
+    
+    for (let i = 1; i <= 12; i++) 
+    { 
+        // add months
+        turnoverYearSum += _addMonth(year, i, turnoverYearData, "turnover");
+        forecastYearSum += _addMonth(year, i, forecastYearData, "forecast");
+    }
+    
+    // add year nodes
+    chartData.add("turnover" + year, rootNode, ["turnover", year.toString(), turnoverYearSum]);
+    chartData.add("forecast" + year, rootNode, ["forecast", year.toString(), forecastYearSum]);
+
+}
+
+result.object(chartData.toArray());
+
+function _addMonth(pYear, pMonth, pData, pCategory)
+{
+    var yearSum = 0;
+
+    // count months, which didn't exist in data source.
+    if (pMonth == 1)
+    {
+        skippedCounts[pCategory] = 0;
+    }
+
+
+    var currentMonthData = pData[pMonth - skippedCounts[pCategory] - 1];
+    var monthDate = new Date(pYear, pMonth-1);
+    monthDate = datetime.toDate(monthDate.getTime(), "MMM yyyy", "UTC");
+
+    var monthValue = 0.0;
+    if (currentMonthData != undefined && currentMonthData[2] == pMonth.toString()) 
+    {
+        monthValue = currentMonthData[3];
+        yearSum += parseInt(currentMonthData[3]);
+    }
+    else
+    {
+        // if month didn't exist in data source, use 0.0 as value.
+        skippedCounts[pCategory]++;
+    }
+
+    // add month node
+    chartData.add(pCategory + pYear + pMonth, pCategory + pYear, [pCategory, monthDate, monthValue]);
+    return yearSum;
+}
\ No newline at end of file
diff --git a/others/db_changes/data/example_product/PRODUCT_42154311.xml b/others/db_changes/data/example_product/PRODUCT_42154311.xml
index ff6855c5f85d61bbbc2f5d5bf6f0b558f7085d8a..fa07baac031b7111b16c9b84445384ae771ae0f6 100644
--- a/others/db_changes/data/example_product/PRODUCT_42154311.xml
+++ b/others/db_changes/data/example_product/PRODUCT_42154311.xml
@@ -1,287 +1,297 @@
-<?xml version="1.1" encoding="UTF-8" standalone="no"?>
-<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
-    <changeSet author="m.schroeger" id="7896e3d7-8ecc-4a41-9117-239480c05cb4">
-        <insert tableName="PRODUCT">
-            <column name="PRODUCTID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="ADVERTISING" value="N"/>
-            <column name="GROUPCODEID" valueNumeric="1"/>
-            <column name="MINSTOCK" valueNumeric="5.00"/>
-            <column name="PRODUCTCODE" value="ProduktNr1"/>
-            <column name="PRODUCTNAME" value="AX45"/>
-            <column name="STATUS" valueNumeric="1"/>
-            <column name="UNIT" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:34:29"/>
-        </insert>
-        <insert tableName="PRODUCT">
-            <column name="PRODUCTID" value="f52b1d6e-bf08-4fe1-8d83-ac0728c4b1c4"/>
-            <column name="ADVERTISING" value="N"/>
-            <column name="GROUPCODEID" valueNumeric="5"/>
-            <column name="MINSTOCK" valueNumeric="12.00"/>
-            <column name="PRODUCTCODE" value="ProduktNr1.1"/>
-            <column name="PRODUCTNAME" value="Produktname1.1"/>
-            <column name="STATUS" valueNumeric="1"/>
-            <column name="UNIT" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:02"/>
-        </insert>
-        <insert tableName="PRODUCT">
-            <column name="PRODUCTID" value="b973e3f9-277c-4787-96a0-7cac54472420"/>
-            <column name="ADVERTISING" value="N"/>
-            <column name="GROUPCODEID" valueNumeric="5"/>
-            <column name="MINSTOCK" valueNumeric="10.00"/>
-            <column name="PRODUCTCODE" value="ProduktNr1.2"/>
-            <column name="PRODUCTNAME" value="Produktname1.2"/>
-            <column name="STATUS" valueNumeric="1"/>
-            <column name="UNIT" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:11"/>
-        </insert>
-        <insert tableName="PRODUCT">
-            <column name="PRODUCTID" value="6e52e636-284d-454b-978c-8f58844c5c5b"/>
-            <column name="ADVERTISING" value="N"/>
-            <column name="GROUPCODEID" valueNumeric="5"/>
-            <column name="MINSTOCK" valueNumeric="15.00"/>
-            <column name="PRODUCTCODE" value="ProduktNr4.1"/>
-            <column name="PRODUCTNAME" value="Produktname4.1"/>
-            <column name="STATUS" valueNumeric="1"/>
-            <column name="UNIT" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:14"/>
-        </insert>
-        <insert tableName="PRODUCT">
-            <column name="PRODUCTID" value="072680e3-9e5d-4228-b5a8-f4acef8f2452"/>
-            <column name="ADVERTISING" value="N"/>
-            <column name="GROUPCODEID" valueNumeric="5"/>
-            <column name="MINSTOCK" valueNumeric="50.00"/>
-            <column name="PRODUCTCODE" value="ProduktNr4.2"/>
-            <column name="PRODUCTNAME" value="Produktname4.2a"/>
-            <column name="STATUS" valueNumeric="1"/>
-            <column name="UNIT" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:18"/>
-        </insert>
-        <insert tableName="PRODUCT">
-            <column name="PRODUCTID" value="368aa1c0-b802-4dea-844e-e61bf85a03c9"/>
-            <column name="ADVERTISING" value="N"/>
-            <column name="GROUPCODEID" valueNumeric="4"/>
-            <column name="MINSTOCK" valueNumeric="0.00"/>
-            <column name="PRODUCTCODE" value="R01"/>
-            <column name="PRODUCTNAME" value="Sonderrabatt"/>
-            <column name="STATUS" valueNumeric="1"/>
-            <column name="UNIT" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:23"/>
-        </insert>
-        <insert tableName="PRODUCT">
-            <column name="PRODUCTID" value="feefb3a9-f02a-4536-9ebb-ab7070cc71ba"/>
-            <column name="ADVERTISING" value="N"/>
-            <column name="GROUPCODEID" valueNumeric="1"/>
-            <column name="MINSTOCK" valueNumeric="2.00"/>
-            <column name="PRODUCTCODE" value="AX47-2233"/>
-            <column name="PRODUCTNAME" value="AX47"/>
-            <column name="STATUS" valueNumeric="1"/>
-            <column name="UNIT" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:26"/>
-        </insert>
-        
-        <insert tableName="PROD2PROD">
-            <column name="PROD2PRODID" value="c5288f96-41f0-4b9b-b79f-23da12ad485b"/>
-            <column name="OPTIONAL" valueNumeric="0"/>
-            <column name="TAKEPRICE" valueNumeric="0"/>
-            <column name="QUANTITY" valueNumeric="1.00"/>
-            <column name="SOURCE_ID" value="feefb3a9-f02a-4536-9ebb-ab7070cc71ba"/>
-            <column name="DEST_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:33"/>
-        </insert>
-        <insert tableName="PROD2PROD">
-            <column name="PROD2PRODID" value="f78cf164-3a9d-43a6-a58c-9f462e5ed012"/>
-            <column name="OPTIONAL" valueNumeric="0"/>
-            <column name="TAKEPRICE" valueNumeric="1"/>
-            <column name="QUANTITY" valueNumeric="2.00"/>
-            <column name="SOURCE_ID" value="f52b1d6e-bf08-4fe1-8d83-ac0728c4b1c4"/>
-            <column name="DEST_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:36"/>
-        </insert>
-        <insert tableName="PROD2PROD">
-            <column name="PROD2PRODID" value="cbd0699d-947c-4f6c-8c43-e9dcea72447a"/>
-            <column name="OPTIONAL" valueNumeric="0"/>
-            <column name="TAKEPRICE" valueNumeric="1"/>
-            <column name="QUANTITY" valueNumeric="3.00"/>
-            <column name="SOURCE_ID" value="b973e3f9-277c-4787-96a0-7cac54472420"/>
-            <column name="DEST_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:39"/>
-        </insert>
-        <insert tableName="PROD2PROD">
-            <column name="PROD2PRODID" value="aefd0be1-325d-42f7-9b79-1bab24e7ae23"/>
-            <column name="OPTIONAL" valueNumeric="0"/>
-            <column name="TAKEPRICE" valueNumeric="1"/>
-            <column name="QUANTITY" valueNumeric="3.00"/>
-            <column name="SOURCE_ID" value="6e52e636-284d-454b-978c-8f58844c5c5b"/>
-            <column name="DEST_ID" value="feefb3a9-f02a-4536-9ebb-ab7070cc71ba"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:42"/>
-        </insert>
-        <insert tableName="PROD2PROD">
-            <column name="PROD2PRODID" value="e413c0f8-c953-4380-ad2e-b9c04411baad"/>
-            <column name="OPTIONAL" valueNumeric="0"/>
-            <column name="TAKEPRICE" valueNumeric="0"/>
-            <column name="QUANTITY" valueNumeric="3.00"/>
-            <column name="SOURCE_ID" value="072680e3-9e5d-4228-b5a8-f4acef8f2452"/>
-            <column name="DEST_ID" value="feefb3a9-f02a-4536-9ebb-ab7070cc71ba"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:46"/>
-        </insert>
-        <insert tableName="PROD2PROD">
-            <column name="PROD2PRODID" value="cb43c351-38dc-4b1e-b408-2d9afcfdbb13"/>
-            <column name="OPTIONAL" valueNumeric="0"/>
-            <column name="TAKEPRICE" valueNumeric="0"/>
-            <column name="QUANTITY" valueNumeric="3.00"/>
-            <column name="SOURCE_ID" value="368aa1c0-b802-4dea-844e-e61bf85a03c9"/>
-            <column name="DEST_ID" value="6e52e636-284d-454b-978c-8f58844c5c5b"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:49"/>
-        </insert>
-        <insert tableName="PROD2PROD">
-            <column name="PROD2PRODID" value="a58d73e4-8e5a-4b96-9d39-2a178736bb31"/>
-            <column name="OPTIONAL" valueNumeric="0"/>
-            <column name="TAKEPRICE" valueNumeric="0"/>
-            <column name="QUANTITY" valueNumeric="1.00"/>
-            <column name="SOURCE_ID" value="b973e3f9-277c-4787-96a0-7cac54472420"/>
-            <column name="DEST_ID" value="368aa1c0-b802-4dea-844e-e61bf85a03c9"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:33"/>
-        </insert>
-        
-        <insert tableName="PRODUCTPRICE">
-            <column name="PRODUCTPRICEID" value="12f288ac-f01b-4d20-b1b8-0f4f02e11079"/>
-            <column name="VALID_TO" valueDate="2018-10-31T00:00:00"/>
-            <column name="VALID_FROM" valueDate="2018-02-01T00:00:00"/>
-            <column name="PRICE" valueNumeric="150.00"/>
-            <column name="VAT" valueNumeric="19.00"/>
-            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="FROMQUANTITY" valueNumeric="1.00"/>
-            <column name="CURRENCY" valueNumeric="1"/>
-            <column name="PRICELIST" valueNumeric="1"/>
-            <column name="BUYSELL" value="SP"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:52"/>
-        </insert>
-        <insert tableName="PRODUCTPRICE">
-            <column name="PRODUCTPRICEID" value="409f7c1c-f6bf-44fe-8e63-e650f3807b93"/>
-            <column name="VALID_TO" valueDate="2058-10-31T00:00:00"/>
-            <column name="VALID_FROM" valueDate="2018-11-01T00:00:00"/>
-            <column name="PRICE" valueNumeric="195.00"/>
-            <column name="VAT" valueNumeric="19.00"/>
-            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="FROMQUANTITY" valueNumeric="50.00"/>
-            <column name="CURRENCY" valueNumeric="1"/>
-            <column name="PRICELIST" valueNumeric="1"/>
-            <column name="BUYSELL" value="SP"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:55"/>
-        </insert>
-        <insert tableName="PRODUCTPRICE">
-            <column name="PRODUCTPRICEID" value="4e6b8398-6618-4ceb-ac7c-9ecde9a2d698"/>
-            <column name="VALID_TO" valueDate="2058-10-31T00:00:00"/>
-            <column name="VALID_FROM" valueDate="2018-11-10T00:00:00"/>
-            <column name="PRICE" valueNumeric="210.00"/>
-            <column name="VAT" valueNumeric="19.00"/>
-            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="FROMQUANTITY" valueNumeric="1.00"/>
-            <column name="CURRENCY" valueNumeric="1"/>
-            <column name="PRICELIST" valueNumeric="1"/>
-            <column name="BUYSELL" value="SP"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:56"/>
-        </insert>
-        <insert tableName="PRODUCTPRICE">
-            <column name="PRODUCTPRICEID" value="599980f8-a8cf-4a03-8562-2a1b08856eac"/>
-            <column name="VALID_TO" valueDate="2058-10-31T00:00:00"/>
-            <column name="VALID_FROM" valueDate="2018-11-01T00:00:00"/>
-            <column name="PRICE" valueNumeric="205.00"/>
-            <column name="VAT" valueNumeric="19.00"/>
-            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="FROMQUANTITY" valueNumeric="1.00"/>
-            <column name="CURRENCY" valueNumeric="1"/>
-            <column name="PRICELIST" valueNumeric="2"/>
-            <column name="BUYSELL" value="SP"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:57"/>
-        </insert>
-        <insert tableName="PRODUCTPRICE">
-            <column name="PRODUCTPRICEID" value="814dc207-f265-4bcc-9913-1b2c2879c8c7"/>
-            <column name="VALID_TO" valueDate="2058-10-31T00:00:00"/>
-            <column name="VALID_FROM" valueDate="2018-11-01T00:00:00"/>
-            <column name="PRICE" valueNumeric="180.00"/>
-            <column name="VAT" valueNumeric="19.00"/>
-            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="FROMQUANTITY" valueNumeric="50.00"/>
-            <column name="CURRENCY" valueNumeric="1"/>
-            <column name="PRICELIST" valueNumeric="2"/>
-            <column name="BUYSELL" value="SP"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:58"/>
-        </insert>
-        <insert tableName="PRODUCTPRICE">
-            <column name="PRODUCTPRICEID" value="ac85ca59-bf12-46a9-9c76-1cb4ac78eda5"/>
-            <column name="VALID_TO" valueDate="2058-10-31T00:00:00"/>
-            <column name="VALID_FROM" valueDate="2018-11-01T00:00:00"/>
-            <column name="PRICE" valueNumeric="208.00"/>
-            <column name="VAT" valueNumeric="19.00"/>
-            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="FROMQUANTITY" valueNumeric="50.00"/>
-            <column name="CURRENCY" valueNumeric="2"/>
-            <column name="PRICELIST" valueNumeric="1"/>
-            <column name="BUYSELL" value="SP"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-12T14:35:59"/>
-        </insert>
-        
-        <insert tableName="STOCK">
-            <column name="STOCKID" value="f09201f8-85f3-4715-8d44-5cec7b8f437b"/>
-            <column name="IN_OUT" valueNumeric="1"/>
-            <column name="QUANTITY" valueNumeric="30"/>
-            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="ENTRYDATE" valueDate="2018-11-22T00:00:00"/>
-            <column name="WAREHOUSE" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-22T11:35:59"/>
-        </insert>
-        <insert tableName="STOCK">
-            <column name="STOCKID" value="a90a8aba-76bb-40b1-a4ab-ef39508296cb"/>
-            <column name="IN_OUT" valueNumeric="1"/>
-            <column name="QUANTITY" valueNumeric="25"/>
-            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="ENTRYDATE" valueDate="2018-11-15T00:00:00"/>
-            <column name="WAREHOUSE" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-22T11:36:04"/>
-        </insert>
-        <insert tableName="STOCK">
-            <column name="STOCKID" value="bd4c1a16-1b80-4b3e-aa67-306f387a62df"/>
-            <column name="IN_OUT" valueNumeric="0"/>
-            <column name="QUANTITY" valueNumeric="23"/>
-            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="ENTRYDATE" valueDate="2018-11-22T00:00:00"/>
-            <column name="WAREHOUSE" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-22T11:36:07"/>
-        </insert>
-        <insert tableName="STOCK">
-            <column name="STOCKID" value="3caba278-9d38-485c-9d78-11ea969b832c"/>
-            <column name="IN_OUT" valueNumeric="0"/>
-            <column name="QUANTITY" valueNumeric="17"/>
-            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
-            <column name="ENTRYDATE" valueDate="2018-11-15T00:00:00"/>
-            <column name="WAREHOUSE" valueNumeric="1"/>
-            <column name="USER_NEW" value="Admin"/>
-            <column name="DATE_NEW" valueDate="2018-11-22T11:36:09"/>
-        </insert>
-
-    </changeSet>
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+    <changeSet author="m.schroeger" id="7896e3d7-8ecc-4a41-9117-239480c05cb4">
+        <insert tableName="PRODUCT">
+            <column name="PRODUCTID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="ADVERTISING" value="N"/>
+            <column name="GROUPCODEID" valueNumeric="1"/>
+            <column name="MINSTOCK" valueNumeric="5.00"/>
+            <column name="PRODUCTCODE" value="ProduktNr1"/>
+            <column name="PRODUCTNAME" value="AX45"/>
+            <column name="STATUS" valueNumeric="1"/>
+            <column name="UNIT" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:34:29"/>
+        </insert>
+        <insert tableName="PRODUCT">
+            <column name="PRODUCTID" value="f52b1d6e-bf08-4fe1-8d83-ac0728c4b1c4"/>
+            <column name="ADVERTISING" value="N"/>
+            <column name="GROUPCODEID" valueNumeric="5"/>
+            <column name="MINSTOCK" valueNumeric="12.00"/>
+            <column name="PRODUCTCODE" value="ProduktNr1.1"/>
+            <column name="PRODUCTNAME" value="Produktname1.1"/>
+            <column name="STATUS" valueNumeric="1"/>
+            <column name="UNIT" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:02"/>
+        </insert>
+        <insert tableName="PRODUCT">
+            <column name="PRODUCTID" value="b973e3f9-277c-4787-96a0-7cac54472420"/>
+            <column name="ADVERTISING" value="N"/>
+            <column name="GROUPCODEID" valueNumeric="5"/>
+            <column name="MINSTOCK" valueNumeric="10.00"/>
+            <column name="PRODUCTCODE" value="ProduktNr1.2"/>
+            <column name="PRODUCTNAME" value="Produktname1.2"/>
+            <column name="STATUS" valueNumeric="1"/>
+            <column name="UNIT" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:11"/>
+        </insert>
+        <insert tableName="PRODUCT">
+            <column name="PRODUCTID" value="6e52e636-284d-454b-978c-8f58844c5c5b"/>
+            <column name="ADVERTISING" value="N"/>
+            <column name="GROUPCODEID" valueNumeric="5"/>
+            <column name="MINSTOCK" valueNumeric="15.00"/>
+            <column name="PRODUCTCODE" value="ProduktNr4.1"/>
+            <column name="PRODUCTNAME" value="Produktname4.1"/>
+            <column name="STATUS" valueNumeric="1"/>
+            <column name="UNIT" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:14"/>
+        </insert>
+        <insert tableName="PRODUCT">
+            <column name="PRODUCTID" value="072680e3-9e5d-4228-b5a8-f4acef8f2452"/>
+            <column name="ADVERTISING" value="N"/>
+            <column name="GROUPCODEID" valueNumeric="5"/>
+            <column name="MINSTOCK" valueNumeric="50.00"/>
+            <column name="PRODUCTCODE" value="ProduktNr4.2"/>
+            <column name="PRODUCTNAME" value="Produktname4.2a"/>
+            <column name="STATUS" valueNumeric="1"/>
+            <column name="UNIT" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:18"/>
+        </insert>
+        <insert tableName="PRODUCT">
+            <column name="PRODUCTID" value="368aa1c0-b802-4dea-844e-e61bf85a03c9"/>
+            <column name="ADVERTISING" value="N"/>
+            <column name="GROUPCODEID" valueNumeric="4"/>
+            <column name="MINSTOCK" valueNumeric="0.00"/>
+            <column name="PRODUCTCODE" value="R01"/>
+            <column name="PRODUCTNAME" value="Sonderrabatt"/>
+            <column name="STATUS" valueNumeric="1"/>
+            <column name="UNIT" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:23"/>
+        </insert>
+        <insert tableName="PRODUCT">
+            <column name="PRODUCTID" value="feefb3a9-f02a-4536-9ebb-ab7070cc71ba"/>
+            <column name="ADVERTISING" value="N"/>
+            <column name="GROUPCODEID" valueNumeric="1"/>
+            <column name="MINSTOCK" valueNumeric="2.00"/>
+            <column name="PRODUCTCODE" value="AX47-2233"/>
+            <column name="PRODUCTNAME" value="AX47"/>
+            <column name="STATUS" valueNumeric="1"/>
+            <column name="UNIT" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:26"/>
+        </insert>
+        
+        <insert tableName="PROD2PROD">
+            <column name="PROD2PRODID" value="c5288f96-41f0-4b9b-b79f-23da12ad485b"/>
+            <column name="OPTIONAL" valueNumeric="0"/>
+            <column name="TAKEPRICE" valueNumeric="0"/>
+            <column name="QUANTITY" valueNumeric="1.00"/>
+            <column name="SOURCE_ID" value="feefb3a9-f02a-4536-9ebb-ab7070cc71ba"/>
+            <column name="DEST_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:33"/>
+        </insert>
+        <insert tableName="PROD2PROD">
+            <column name="PROD2PRODID" value="f78cf164-3a9d-43a6-a58c-9f462e5ed012"/>
+            <column name="OPTIONAL" valueNumeric="0"/>
+            <column name="TAKEPRICE" valueNumeric="1"/>
+            <column name="QUANTITY" valueNumeric="2.00"/>
+            <column name="SOURCE_ID" value="f52b1d6e-bf08-4fe1-8d83-ac0728c4b1c4"/>
+            <column name="DEST_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:36"/>
+        </insert>
+        <insert tableName="PROD2PROD">
+            <column name="PROD2PRODID" value="cbd0699d-947c-4f6c-8c43-e9dcea72447a"/>
+            <column name="OPTIONAL" valueNumeric="0"/>
+            <column name="TAKEPRICE" valueNumeric="1"/>
+            <column name="QUANTITY" valueNumeric="3.00"/>
+            <column name="SOURCE_ID" value="b973e3f9-277c-4787-96a0-7cac54472420"/>
+            <column name="DEST_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:39"/>
+        </insert>
+        <insert tableName="PROD2PROD">
+            <column name="PROD2PRODID" value="aefd0be1-325d-42f7-9b79-1bab24e7ae23"/>
+            <column name="OPTIONAL" valueNumeric="0"/>
+            <column name="TAKEPRICE" valueNumeric="1"/>
+            <column name="QUANTITY" valueNumeric="3.00"/>
+            <column name="SOURCE_ID" value="6e52e636-284d-454b-978c-8f58844c5c5b"/>
+            <column name="DEST_ID" value="feefb3a9-f02a-4536-9ebb-ab7070cc71ba"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:42"/>
+        </insert>
+        <insert tableName="PROD2PROD">
+            <column name="PROD2PRODID" value="e413c0f8-c953-4380-ad2e-b9c04411baad"/>
+            <column name="OPTIONAL" valueNumeric="0"/>
+            <column name="TAKEPRICE" valueNumeric="0"/>
+            <column name="QUANTITY" valueNumeric="3.00"/>
+            <column name="SOURCE_ID" value="072680e3-9e5d-4228-b5a8-f4acef8f2452"/>
+            <column name="DEST_ID" value="feefb3a9-f02a-4536-9ebb-ab7070cc71ba"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:46"/>
+        </insert>
+        <insert tableName="PROD2PROD">
+            <column name="PROD2PRODID" value="cb43c351-38dc-4b1e-b408-2d9afcfdbb13"/>
+            <column name="OPTIONAL" valueNumeric="0"/>
+            <column name="TAKEPRICE" valueNumeric="0"/>
+            <column name="QUANTITY" valueNumeric="3.00"/>
+            <column name="SOURCE_ID" value="368aa1c0-b802-4dea-844e-e61bf85a03c9"/>
+            <column name="DEST_ID" value="6e52e636-284d-454b-978c-8f58844c5c5b"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:49"/>
+        </insert>
+        <insert tableName="PROD2PROD">
+            <column name="PROD2PRODID" value="a58d73e4-8e5a-4b96-9d39-2a178736bb31"/>
+            <column name="OPTIONAL" valueNumeric="0"/>
+            <column name="TAKEPRICE" valueNumeric="0"/>
+            <column name="QUANTITY" valueNumeric="1.00"/>
+            <column name="SOURCE_ID" value="6e52e636-284d-454b-978c-8f58844c5c5b"/>
+            <column name="DEST_ID" value="368aa1c0-b802-4dea-844e-e61bf85a03c9"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:33"/>
+        </insert>
+        <insert tableName="PROD2PROD">
+            <column name="PROD2PRODID" value="752b7549-703f-45de-a7d8-b0a0602715c0"/>
+            <column name="OPTIONAL" valueNumeric="0"/>
+            <column name="TAKEPRICE" valueNumeric="0"/>
+            <column name="QUANTITY" valueNumeric="1.00"/>
+            <column name="SOURCE_ID" value="b973e3f9-277c-4787-96a0-7cac54472420"/>
+            <column name="DEST_ID" value="368aa1c0-b802-4dea-844e-e61bf85a03c9"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:33"/>
+        </insert>
+
+        <insert tableName="PRODUCTPRICE">
+            <column name="PRODUCTPRICEID" value="12f288ac-f01b-4d20-b1b8-0f4f02e11079"/>
+            <column name="VALID_TO" valueDate="2018-10-31T00:00:00"/>
+            <column name="VALID_FROM" valueDate="2018-02-01T00:00:00"/>
+            <column name="PRICE" valueNumeric="150.00"/>
+            <column name="VAT" valueNumeric="19.00"/>
+            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="FROMQUANTITY" valueNumeric="1.00"/>
+            <column name="CURRENCY" valueNumeric="1"/>
+            <column name="PRICELIST" valueNumeric="1"/>
+            <column name="BUYSELL" value="SP"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:52"/>
+        </insert>
+        <insert tableName="PRODUCTPRICE">
+            <column name="PRODUCTPRICEID" value="409f7c1c-f6bf-44fe-8e63-e650f3807b93"/>
+            <column name="VALID_TO" valueDate="2058-10-31T00:00:00"/>
+            <column name="VALID_FROM" valueDate="2018-11-01T00:00:00"/>
+            <column name="PRICE" valueNumeric="195.00"/>
+            <column name="VAT" valueNumeric="19.00"/>
+            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="FROMQUANTITY" valueNumeric="50.00"/>
+            <column name="CURRENCY" valueNumeric="1"/>
+            <column name="PRICELIST" valueNumeric="1"/>
+            <column name="BUYSELL" value="SP"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:55"/>
+        </insert>
+        <insert tableName="PRODUCTPRICE">
+            <column name="PRODUCTPRICEID" value="4e6b8398-6618-4ceb-ac7c-9ecde9a2d698"/>
+            <column name="VALID_TO" valueDate="2058-10-31T00:00:00"/>
+            <column name="VALID_FROM" valueDate="2018-11-10T00:00:00"/>
+            <column name="PRICE" valueNumeric="210.00"/>
+            <column name="VAT" valueNumeric="19.00"/>
+            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="FROMQUANTITY" valueNumeric="1.00"/>
+            <column name="CURRENCY" valueNumeric="1"/>
+            <column name="PRICELIST" valueNumeric="1"/>
+            <column name="BUYSELL" value="SP"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:56"/>
+        </insert>
+        <insert tableName="PRODUCTPRICE">
+            <column name="PRODUCTPRICEID" value="599980f8-a8cf-4a03-8562-2a1b08856eac"/>
+            <column name="VALID_TO" valueDate="2058-10-31T00:00:00"/>
+            <column name="VALID_FROM" valueDate="2018-11-01T00:00:00"/>
+            <column name="PRICE" valueNumeric="205.00"/>
+            <column name="VAT" valueNumeric="19.00"/>
+            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="FROMQUANTITY" valueNumeric="1.00"/>
+            <column name="CURRENCY" valueNumeric="1"/>
+            <column name="PRICELIST" valueNumeric="2"/>
+            <column name="BUYSELL" value="SP"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:57"/>
+        </insert>
+        <insert tableName="PRODUCTPRICE">
+            <column name="PRODUCTPRICEID" value="814dc207-f265-4bcc-9913-1b2c2879c8c7"/>
+            <column name="VALID_TO" valueDate="2058-10-31T00:00:00"/>
+            <column name="VALID_FROM" valueDate="2018-11-01T00:00:00"/>
+            <column name="PRICE" valueNumeric="180.00"/>
+            <column name="VAT" valueNumeric="19.00"/>
+            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="FROMQUANTITY" valueNumeric="50.00"/>
+            <column name="CURRENCY" valueNumeric="1"/>
+            <column name="PRICELIST" valueNumeric="2"/>
+            <column name="BUYSELL" value="SP"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:58"/>
+        </insert>
+        <insert tableName="PRODUCTPRICE">
+            <column name="PRODUCTPRICEID" value="ac85ca59-bf12-46a9-9c76-1cb4ac78eda5"/>
+            <column name="VALID_TO" valueDate="2058-10-31T00:00:00"/>
+            <column name="VALID_FROM" valueDate="2018-11-01T00:00:00"/>
+            <column name="PRICE" valueNumeric="208.00"/>
+            <column name="VAT" valueNumeric="19.00"/>
+            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="FROMQUANTITY" valueNumeric="50.00"/>
+            <column name="CURRENCY" valueNumeric="2"/>
+            <column name="PRICELIST" valueNumeric="1"/>
+            <column name="BUYSELL" value="SP"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-12T14:35:59"/>
+        </insert>
+        
+        <insert tableName="STOCK">
+            <column name="STOCKID" value="f09201f8-85f3-4715-8d44-5cec7b8f437b"/>
+            <column name="IN_OUT" valueNumeric="1"/>
+            <column name="QUANTITY" valueNumeric="30"/>
+            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="ENTRYDATE" valueDate="2018-11-22T00:00:00"/>
+            <column name="WAREHOUSE" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-22T11:35:59"/>
+        </insert>
+        <insert tableName="STOCK">
+            <column name="STOCKID" value="a90a8aba-76bb-40b1-a4ab-ef39508296cb"/>
+            <column name="IN_OUT" valueNumeric="1"/>
+            <column name="QUANTITY" valueNumeric="25"/>
+            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="ENTRYDATE" valueDate="2018-11-15T00:00:00"/>
+            <column name="WAREHOUSE" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-22T11:36:04"/>
+        </insert>
+        <insert tableName="STOCK">
+            <column name="STOCKID" value="bd4c1a16-1b80-4b3e-aa67-306f387a62df"/>
+            <column name="IN_OUT" valueNumeric="0"/>
+            <column name="QUANTITY" valueNumeric="23"/>
+            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="ENTRYDATE" valueDate="2018-11-22T00:00:00"/>
+            <column name="WAREHOUSE" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-22T11:36:07"/>
+        </insert>
+        <insert tableName="STOCK">
+            <column name="STOCKID" value="3caba278-9d38-485c-9d78-11ea969b832c"/>
+            <column name="IN_OUT" valueNumeric="0"/>
+            <column name="QUANTITY" valueNumeric="17"/>
+            <column name="PRODUCT_ID" value="a2e76fe1-e49b-4f2b-8da5-12660738043d"/>
+            <column name="ENTRYDATE" valueDate="2018-11-15T00:00:00"/>
+            <column name="WAREHOUSE" valueNumeric="1"/>
+            <column name="USER_NEW" value="Admin"/>
+            <column name="DATE_NEW" valueDate="2018-11-22T11:36:09"/>
+        </insert>
+
+    </changeSet>
 </databaseChangeLog>
\ No newline at end of file
diff --git a/others/db_changes/data/example_salesproject/SALESPROJECT_gfk.xml b/others/db_changes/data/example_salesproject/SALESPROJECT_gfk.xml
index 76a6018c9d681961406347ab488e56bc07b05ad1..9574c79455b194b44dd366b4295a99cabef89f62 100644
--- a/others/db_changes/data/example_salesproject/SALESPROJECT_gfk.xml
+++ b/others/db_changes/data/example_salesproject/SALESPROJECT_gfk.xml
@@ -1,180 +1,180 @@
-<?xml version="1.1" encoding="UTF-8" standalone="no"?>
-<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
-<changeSet author="j.hoermanns" id="76912d9-ced7-4626-a031-d7138dfc948e">
-    <insert tableName="SALESPROJECT">
-        <column name="SALESPROJECTID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
-        <column name="USER_NEW" value="admin"/>
-        <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"/>
-        <column name="INFO" value="evtl. noch mit Berater Müller sprechen, ob ihm bekannt"/>
-        <column name="STATE" valueNumeric="1"/>
-        <column name="PHASE" valueNumeric="4"/>
-        <column name="VOLUME" valueNumeric="15"/>
-        <column name="PHASE" valueNumeric="4"/>
-        <column name="STARTDATE" valueDate="2017-07-21T09:03:43"/>
-        <column name="ENDDATE" valueDate="2017-10-14T09:03:43"/>
-        <column name="ESTIMATION" value="; 2; 4; 11; "/>
-        <column name="ESTIMATIONVALUE" valueNumeric="2"/>
-        <column name="PROBABILITY" valueNumeric="30"/>
-    </insert>
-
-    <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="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"/>
-        <column name="SOURCE" valueNumeric="1"/>
-    </insert>
-    
-    <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="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="2016-06-13T09:03:43"/>
-        <column name="DATE_END" valueDate="2016-06-13T09:03:43"/>
-    </insert>
-    
-    <insert tableName="SALESPROJECT_FORECAST">
-        <column name="SALESPROJECT_FORECASTID" value="affd17db-d925-4e20-81d5-ea9e4ca37c94"/>
-        <column name="USER_NEW" value="admin"/>
-        <column name="DATE_NEW" valueDate="2018-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="2018-06-13T09:03:43"/>
-        <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="2016-06-13T09:03:43"/>
-        <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
-        <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"/>
-    </insert>
-    
-    <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="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"/>
-    </insert>
-    
-    <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="2016-06-13T09:03:43"/>
-        <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
-        
-        <column name="CLASS" valueNumeric="1"/>
-        <column name="TYPE" value="CLASS.BRANCHE"/>
-        <column name="VALUE" valueNumeric="2"/>
-    </insert>
-    
-    <rollback>			
-        <delete tableName="SALESPROJECT">
-            <where>SALESPROJECTID = ?</where>
-            <whereParams>
-                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
-            </whereParams>
-        </delete>
-        <delete tableName="SALESPROJECT_SOURCE">
-            <where>SALESPROJECT_ID = ?</where>
-            <whereParams>
-                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
-            </whereParams>
-        </delete>
-        <delete tableName="SALESPROJECT_CYCLE">
-            <where>SALESPROJECT_ID = ?</where>
-            <whereParams>
-                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
-            </whereParams>
-        </delete>
-        <delete tableName="SALESPROJECT_FORECAST">
-            <where>SALESPROJECT_ID = ?</where>
-            <whereParams>
-                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
-            </whereParams>
-        </delete>
-        <delete tableName="SALESPROJECT_COMPETITION">
-            <where>SALESPROJECT_ID = ?</where>
-            <whereParams>
-                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
-            </whereParams>
-        </delete>
-        <delete tableName="SALESPROJECT_MEMBER">
-            <where>SALESPROJECT_ID = ?</where>
-            <whereParams>
-                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
-            </whereParams>
-        </delete>
-        <delete tableName="SALESPROJECT_CLASSIFICATION">
-            <where>SALESPROJECT_ID = ?</where>
-            <whereParams>
-                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
-            </whereParams>
-        </delete>
-    </rollback>
-</changeSet>
-</databaseChangeLog>
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+<changeSet author="j.hoermanns" id="76912d9-ced7-4626-a031-d7138dfc948e">
+    <insert tableName="SALESPROJECT">
+        <column name="SALESPROJECTID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
+        <column name="USER_NEW" value="admin"/>
+        <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"/>
+        <column name="INFO" value="evtl. noch mit Berater Müller sprechen, ob ihm bekannt"/>
+        <column name="STATE" valueNumeric="1"/>
+        <column name="PHASE" valueNumeric="4"/>
+        <column name="VOLUME" valueNumeric="15"/>
+        <column name="PHASE" valueNumeric="4"/>
+        <column name="STARTDATE" valueDate="2017-07-21T09:03:43"/>
+        <column name="ENDDATE" valueDate="2017-10-14T09:03:43"/>
+        <column name="ESTIMATION" value="; 2; 4; 11; "/>
+        <column name="ESTIMATIONVALUE" valueNumeric="2"/>
+        <column name="PROBABILITY" valueNumeric="30"/>
+    </insert>
+
+    <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="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"/>
+        <column name="SOURCE" valueNumeric="1"/>
+    </insert>
+    
+    <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="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="2016-06-13T09:03:43"/>
+        <column name="DATE_END" valueDate="2016-06-13T09:03:43"/>
+    </insert>
+    
+    <insert tableName="SALESPROJECT_FORECAST">
+        <column name="SALESPROJECT_FORECASTID" value="affd17db-d925-4e20-81d5-ea9e4ca37c94"/>
+        <column name="USER_NEW" value="admin"/>
+        <column name="DATE_NEW" valueDate="2018-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="2018-06-13T09:03:43"/>
+        <column name="VOLUME" valueNumeric="1"/>
+    </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="1.1"/>
+    </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="1.5"/>
+    </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="1.3"/>
+    </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="2016-06-13T09:03:43"/>
+        <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
+        <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"/>
+    </insert>
+    
+    <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="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"/>
+    </insert>
+    
+    <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="2016-06-13T09:03:43"/>
+        <column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
+        
+        <column name="CLASS" valueNumeric="1"/>
+        <column name="TYPE" value="CLASS.BRANCHE"/>
+        <column name="VALUE" valueNumeric="2"/>
+    </insert>
+    
+    <rollback>			
+        <delete tableName="SALESPROJECT">
+            <where>SALESPROJECTID = ?</where>
+            <whereParams>
+                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
+            </whereParams>
+        </delete>
+        <delete tableName="SALESPROJECT_SOURCE">
+            <where>SALESPROJECT_ID = ?</where>
+            <whereParams>
+                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
+            </whereParams>
+        </delete>
+        <delete tableName="SALESPROJECT_CYCLE">
+            <where>SALESPROJECT_ID = ?</where>
+            <whereParams>
+                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
+            </whereParams>
+        </delete>
+        <delete tableName="SALESPROJECT_FORECAST">
+            <where>SALESPROJECT_ID = ?</where>
+            <whereParams>
+                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
+            </whereParams>
+        </delete>
+        <delete tableName="SALESPROJECT_COMPETITION">
+            <where>SALESPROJECT_ID = ?</where>
+            <whereParams>
+                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
+            </whereParams>
+        </delete>
+        <delete tableName="SALESPROJECT_MEMBER">
+            <where>SALESPROJECT_ID = ?</where>
+            <whereParams>
+                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
+            </whereParams>
+        </delete>
+        <delete tableName="SALESPROJECT_CLASSIFICATION">
+            <where>SALESPROJECT_ID = ?</where>
+            <whereParams>
+                    <param value="0833465c-8851-4fbb-b7e3-8c1d73c903da" />
+            </whereParams>
+        </delete>
+    </rollback>
+</changeSet>
+</databaseChangeLog>
diff --git a/process/Chart_lib/Chart_lib.aod b/process/Chart_lib/Chart_lib.aod
deleted file mode 100644
index 136093c0cd67d56612c37180020a372491521170..0000000000000000000000000000000000000000
--- a/process/Chart_lib/Chart_lib.aod
+++ /dev/null
@@ -1,9 +0,0 @@
-<?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>
-  <variants>
-    <element>LIBRARY</element>
-  </variants>
-</process>
diff --git a/process/Chart_lib/process.js b/process/Chart_lib/process.js
deleted file mode 100644
index f2bcf98574a9038b6c83e6f92aa5265517662659..0000000000000000000000000000000000000000
--- a/process/Chart_lib/process.js
+++ /dev/null
@@ -1,180 +0,0 @@
-import("system.logging");
-import("system.util");
-
-// TODO lib is not finished yet
-
-
-/**
- *  
- * @class
- */
-function MultiDataChart() 
-{
-    this._X = 0;
-    this._Y = 1;
-    
-    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 [[x, y, ...], [x, y, ...]]
- * ... means you can add additional columns, used as identification and naming of drilldowns
- */
-MultiDataChart.prototype.addDataSource = function(pName, pData, pFixedXValues) 
-{        
-    this.dataSources[pName] = {
-        data: pData,
-        fixedValues: pFixedXValues
-    }
-    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 new 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 < this.dataSources[dataSource].data.length; i++) 
-        {
-            var dataRow = this.dataSources[dataSource].data[i];
-            var rowId = util.getNewUUID();
-                                  // id, parent, group,     x,                      y
-            this._resultData.push([rowId, "", dataSource, dataRow[this._X], dataRow[this._Y]]);
-        }
-    }
-    
-    logging.log(this._resultData.toSource())
-    return this._resultData;
-}
-
-/**
- * check if all X-Values exist. If not, create empty values.
- * 
- * 
- * TODO!!!!!!!!!!!!!
- * 
- */
-MultiDataChart.prototype._normalize = function(pDataSource)
-{
-    var fixed = pDataSource.fixedValues;
-    var data = pDataSource.data;
-    var found = {};
-    
-    var resultData = [];
-    
-    for (let i = 0; i < data.length; i++) 
-    {
-        
-        if (found[data[i][this._X]] == undefined)
-        {
-            if (fixed.indexOf(data[i][this._X]) >= 0)
-            {
-                
-            }
-            else
-            {
-                throw new Error("The X-Value " + data[i][this._X] + " is not in the fixed values of the dataSource!");
-            }
-        }
-        
-        found[data[i][this._X]] = true;
-        
-        resultData.push(data[i]);
-    }
-    
-    return resultData;
-}
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    /*
-    
-    
-    
-    
-    
-    
-    
-    for (drilldown in this.drilldowns)
-    {
-        if (drilldown.type == "cumulative")
-        {
-            this._processCumulativeDrilldown(drilldown);
-        }
-    }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-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/Data_lib/process.js b/process/Data_lib/process.js
index 83430f5e24f28bd8400789f26db7308ee097aeb9..2fcf30f728ba8e7bd304db31d1c5c7b9a8a7ed40 100644
--- a/process/Data_lib/process.js
+++ b/process/Data_lib/process.js
@@ -1,20 +1,81 @@
 import("system.util");
-import("system.logging");
 
 /**
- *  
+ *  TODO: documentation!!
+ * @class
+ */
+function ParentingData(pRootId) 
+{
+    this._data = [];
+    this._uids = {};
+    this._rootId = pRootId;
+}
+
+/**
+ * @return {DataTree}
+ */
+ParentingData.begin = function(pRootId) 
+{
+    return new ParentingData(pRootId);
+}
+
+ParentingData.prototype.addArray = function(pData) 
+{
+    pData.forEach(function(pRow)
+    {
+        this.add(pRow[0], pRow[1], pRow.splice(2));
+    }, this);
+    
+    return this;
+}
+
+ParentingData.prototype.add = function(pUid, pParentId, pData) 
+{
+    if (this._dataTree == undefined && this._uids[pUid] == undefined) 
+    {
+        this._uids[pUid] = true;
+        this._data.push([pUid, pParentId].concat(pData));
+    } else {
+        this._convertToTree();
+        this._dataTree.add(pUid, pParentId, pData);
+    }
+}
+
+ParentingData.prototype.toArray = function(pMaxDepth) 
+{ 
+    if (this._dataTree == undefined)
+    {
+        return this._data;
+    }
+    else
+    {
+        return this._dataTree.toArray(pMaxDepth);
+    }
+}
+
+ParentingData.prototype._convertToTree = function() 
+{
+    if (this._dataTree == undefined)
+    {
+        this._dataTree = DataTree.begin(this._rootId)
+                                 .addArray(this._data);
+        this._data = undefined;
+    }
+}
+
+/**
+ *  TODO: documentation + evtl. check-function for loops
  * @class
  */
 function DataTree(pRootId) 
 {
     this._dataTree = {
-        /*
-        root: {
-            ids: []
-        }*/
+        
     };
+    
     this._resultData = [];
-    this.rootId = pRootId
+    this.rootId = pRootId;
+    this.baseId = util.getNewUUID();
 }
 
 /**
@@ -22,8 +83,7 @@ function DataTree(pRootId)
  */
 DataTree.begin = function(pRootId) 
 {
-    var tree = new DataTree(pRootId);
-    return tree;
+    return new DataTree(pRootId);
 }
 
 /**
@@ -39,14 +99,12 @@ DataTree.prototype.getTreeObject = function()
 
 DataTree.prototype.add = function(pUid, pParentId, pData, pManipulateNodeFn) 
 {
-    logging.log(pUid + " " + pParentId + " " + pData.toSource())
-
     if (this._dataTree[pParentId] == undefined) 
     {
         // create parent node. It will be replaced later, if the actual parent is added.
         this._dataTree[pParentId] = {
             ids: [],
-            parent: "root"
+            parent: this.baseId
         }
     }
     this._dataTree[pParentId].ids.push(pUid);
@@ -56,7 +114,7 @@ DataTree.prototype.add = function(pUid, pParentId, pData, pManipulateNodeFn)
     
     var tmpIds = [];
     // node already created as parent by a childNode.
-    if (this._dataTree[pUid] != undefined && this._dataTree[pUid].parent == "root")
+    if (this._dataTree[pUid] != undefined && this._dataTree[pUid].parent == this.baseId)
     {
         // tmp-save already added ids of the node
         tmpIds = this._dataTree[pUid].ids;
@@ -87,7 +145,6 @@ DataTree.prototype.add = function(pUid, pParentId, pData, pManipulateNodeFn)
  */
 DataTree.prototype.addArray = function(pData, pManipulateNodeFn) 
 {
-    logging.log(pData.toSource())
     pData.forEach(function(pRow)
     {
         this.add(pRow[0], pRow[1], pRow.splice(2), pManipulateNodeFn);
@@ -96,26 +153,30 @@ DataTree.prototype.addArray = function(pData, pManipulateNodeFn)
     return this;
 }
 
-DataTree.prototype.toArray = function() 
+DataTree.prototype.toArray = function(pMaxDepth) 
 {   
+    var that = this;
+    // TODO: maybe implement without recursion to prevent stack overflow even on deep cycles...
     var treeArray = [];
     var tree = this._dataTree;
+    
     // in this function Ids are just concatenated. This is bad, because it results in very long strings.
     // Because of this the concatenated id's are maped to new uids in the resulting array
     var uidMap = {};
-    __push(this.rootId, tree[this.rootId]);
+    __push(this.rootId, tree[this.rootId], 0);
     
-    function __push(pParent, pNode) {   
+    function __push(pParent, pNode, pDepth) {   
         for (var i = 0; i < pNode.ids.length; i++) {
-            if (pNode.parent == "root")
+            if (pNode.parent == that.baseId)
             {
-                pParent = ""
+                pParent = "";
             }
             
             var nextUid = pParent + pNode.ids[i];
-            __addRow(nextUid, pParent, tree[pNode.ids[i]].data)
-            logging.log(nextUid + "\n---- " + tree[pNode.ids[i]].toSource())
-            __push(nextUid, tree[pNode.ids[i]])
+            __addRow(nextUid, pParent, tree[pNode.ids[i]].data);
+            
+            if (pMaxDepth == undefined || pDepth < pMaxDepth)
+                __push(nextUid, tree[pNode.ids[i]], pDepth+1);
         }
     }
     
@@ -123,7 +184,6 @@ DataTree.prototype.toArray = function()
     {
         uidMap[pUid] = util.getNewUUID();
         if (uidMap[pParentId] == undefined) {
-            logging.log(pParentId)
             if (pParentId == "")
             {
                 uidMap[pParentId] = "";
@@ -137,7 +197,5 @@ DataTree.prototype.toArray = function()
         treeArray.push([uidMap[pUid], uidMap[pParentId]].concat(pRowdata));
     }
     
-    logging.log(treeArray.toSource())
-
     return treeArray;
 }
\ No newline at end of file
diff --git a/process/Product_lib/process.js b/process/Product_lib/process.js
index 3290b4dc136d1911e582cf756faca6307d9abfab..52b718a5683465b087b10e4919d8473d262652bf 100644
--- a/process/Product_lib/process.js
+++ b/process/Product_lib/process.js
@@ -1,651 +1,646 @@
-import("system.logging");
-import("system.util");
-import("system.SQLTYPES");
-import("system.datetime");
-import("system.db");
-import("system.vars");
-import("system.translate");
-import("Util_lib");
-import("Binary_lib");
-import("Sql_lib");
-import("Keyword_lib");
-import("Data_lib");
-
-/**
- * utility functions for products
- * Do not create an instance of this!
- * 
- * @class
- */
-function ProductUtils() {}
-
-/**
- * Delivers the currently valid product price 
- * 
- * @param {String} pid ProductID
- * @param {String} buySell possible values: PP, SP
- * 
- * @example productUtils.getCurrentProductPrice(vars.get("$field.PRODUCTID"), "PP")
- * 
- * @return {String} currently valid product price
- */
-ProductUtils.getCurrentProductPrice = function(pid, buySell) {
-    if (pid != undefined && pid != "" && buySell != undefined && buySell != "")
-    {
-        var today = datetime.clearTime(vars.get("sys.date"), "utc");
-        var actualPriceCondition = SqlCondition.begin()
-                    .andPrepare("PRODUCTPRICE.BUYSELL", buySell)
-                    .andPrepare("PRODUCTPRICE.PRODUCT_ID", pid)
-                    .andPrepare("PRODUCTPRICE.CURRENCY", 1) // TODO: warum ist Currency hardgecoded auf 1??
-                    .andPrepare("PRODUCTPRICE.VALID_FROM", today, "# <= ?")
-                    .andSqlCondition(SqlCondition.begin()
-                        .orPrepare("PRODUCTPRICE.VALID_TO", today, "# >= ?")
-                        .or("PRODUCTPRICE.VALID_TO is null"), "1 = 2");
-                            
-        var productPriceData = db.array(db.ROW, actualPriceCondition.buildSelect("select PRICE, CURRENCY from PRODUCTPRICE", "1 = 2", "order by VALID_FROM desc"));
-        
-        if (productPriceData[0] && productPriceData[1])
-            return  productPriceData[0] + " " + KeywordUtils.get("CURRENCY", productPriceData[1])[1];
-        else
-            return "";
-    } else {
-        throw new Error(); // TODO: add message
-    }
-}
-
-/**
- * Delivers the stock
- * 
- * @param {String} pid ProductID
- * 
- * @example productUtils.getStockCount(vars.get("$field.PRODUCTID"))
- * 
- * @return {String} stock count
- */
-ProductUtils.getStockCount = function(pid) {
-    if (pid != undefined && pid != "")
-    {
-        var sum = db.cell(SqlCondition.begin()
-                                      .andPrepare("STOCK.PRODUCT_ID", pid)
-                                      .buildSelect("select sum(QUANTITY * case IN_OUT when 0 then -1 else 1)"
-                                                 + " from STOCK"));
-        
-        if (sum == "")
-            sum = "0";
-
-        return sum;
-    }
-    else
-    {
-        throw new Error();//TODO: add message
-    }
-}
-
-/**
- * Delivers metadata and price lists of the passed product. 
- * If parameter "priceListFilter" is passed valid price lists and the 
- * current price list to use for offer/order are delivered.
- * 
- * @param {String} pid req ProductID
- * @param {Object} priceListFilter opt { currency: "currencyValue", quantity: "quantityValue", relationId: "relationIdValue (for custom price lists)" }
- * @param {String[]} additionalProductInfoFields additional fields from Product
- *                   They are added to the result with the Fieldname as key. e.g. if the array is ["INFO"] the result will contain the key "INFO"
- * 
- * @example //Product_entity, Field: PRODUCT_ID, Process: onValueChange
- *          var pid = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.PRODUCT_ID"));
- *          var curr = vars.exists("$param.Currency_param") ? vars.get("$param.Currency_param") : "";
- *          var relid = vars.exists("$param.RelationId_param") ? vars.get("$param.RelationId_param") : "";
- *          var pUtils = new ProductUtils();
- *          var PriceListFilter = { currency: curr, quantity: vars.get("$field.QUANTITY"), relationId: relid };
- *          var ProductDetails = pUtils.getProductDetails(pid, PriceListFilter, ["INFO"]);
- * 
- * @return {Object} { <br>
- *                   productId: "productid" <br>
- *                   , productName: "product name" <br>
- *                   , groupCode: "keyvalue of keyword 'GROUPCODE'" <br>
- *                   , unit: "keyvalue of keyword 'UNIT'" <br>
- *                   , PriceLists: {$pricelistid$ { <br>
- *                          priceListId: "pricelistid" <br>
- *                          , relationId: "relationid" when filled -> custom price list <br>
- *                          , priceList: "keyvalue of keyword 'PRICELIST'" <br>
- *                          , price: "price" <br>
- *                          , vat: "vat" <br>
- *                          , validFrom: TIMESTAMP <br>
- *                          , validTo: TIMESTAMP <br>
- *                          , buySell: "SP" / "PP" <br>
- *                          , fromQuantity: "fromquantity" <br>
- *                          , currency: "keyvalue of keyword 'CURRENCY'" <br>
- *                      } } <br>
- *                   , CurrentValidPriceLists: {$pricelistid$ { <br>
- *                          priceListId: "pricelistid" <br>
- *                          , relationId: "relationid" when filled -> custom price list <br>
- *                          , priceList: "keyvalue of keyword 'PRICELIST'" <br>
- *                          , price: "price" <br>
- *                          , vat: "vat" <br>
- *                          , validFrom: TIMESTAMP <br>
- *                          , validTo: TIMESTAMP <br>
- *                          , buySell: "SP" / "PP" <br>
- *                          , fromQuantity: "fromquantity" <br>
- *                          , currency: "keyvalue of keyword 'CURRENCY'" <br>
- *                      } } <br>
- *                   , PriceListToUse: {$pricelistid$ { <br>
- *                          priceListId: "pricelistid" <br>
- *                          , relationId: "relationid" when filled -> custom price list <br>
- *                          , priceList: "keyvalue of keyword 'PRICELIST'" <br>
- *                          , price: "price" <br>
- *                          , vat: "vat" <br>
- *                          , validFrom: TIMESTAMP <br>
- *                          , validTo: TIMESTAMP <br>
- *                          , buySell: "SP" / "PP" <br>
- *                          , fromQuantity: "fromquantity" <br>
- *                          , currency: "keyvalue of keyword 'CURRENCY'" <br>
- *                      } }, <br>
- *                   INFO: "the productinfo"
- *               }
- */
-ProductUtils.getProductDetails = function(pid, priceListFilter, additionalProductInfoFields)
-{
-    if (additionalProductInfoFields == undefined) {additionalProductInfoFields = []}
-    var ProductDetails = {};
-
-    var cols = [];
-    var colsProduct = ["PRODUCT.PRODUCTID", "PRODUCT.PRODUCTNAME", "PRODUCT.GROUPCODEID", "PRODUCT.UNIT"];
-    var defaultProductFieldCount = colsProduct.length;
-    colsProduct = colsProduct.concat(additionalProductInfoFields.map(function(item) {return "PRODUCT." + item}));
-    
-    cols = cols.concat(colsProduct);
-
-    var joins = [];
-    var orderby = ["PRODUCTID"];
-
-    //PriceList (all)
-    var colsPricelistAll = ["allPP.PRODUCTPRICEID", "allPP.RELATION_ID", "allPP.PRICELIST", "allPP.PRICE", "allPP.VAT"
-                        , "allPP.VALID_FROM", "allPP.VALID_TO", "allPP.BUYSELL", "allPP.FROMQUANTITY", "allPP.CURRENCY"];
-
-    cols = cols.concat(colsPricelistAll);
-    joins.push(" left join PRODUCTPRICE allPP on allPP.PRODUCT_ID = PRODUCTID ");
-
-    //PriceList (currently valid)
-    var validPriceLists = false;
-    if (priceListFilter != undefined 
-        && priceListFilter.currency != undefined && priceListFilter.currency != "" 
-        && priceListFilter.quantity != undefined && priceListFilter.quantity != "")
-    {
-        validPriceLists = true;
-        var colsPricelistValid = ["validPP.PRODUCTPRICEID", "validPP.RELATION_ID", "validPP.PRICELIST", "validPP.PRICE", "validPP.VAT"
-                        , "validPP.VALID_FROM", "validPP.VALID_TO", "validPP.BUYSELL", "validPP.FROMQUANTITY", "validPP.CURRENCY"];
-
-        cols = cols.concat(colsPricelistValid);
-        joins.push("left join PRODUCTPRICE validPP on " 
-                    + db.translateCondition(SqlCondition.begin()
-                               .and("validPP.PRODUCT_ID = PRODUCTID")
-                               .andPrepare(["PRODUCTPRICE", "CURRENCY", "validPP"], priceListFilter.currency)
-                               .andPrepare(["PRODUCTPRICE", "VALID_FROM", "validPP"], datetime.date().toString(), "# <= ?")
-                               .andPrepare(["PRODUCTPRICE", "FROMQUANTITY", "validPP"], priceListFilter.quantity, "# <= ?")
-                               .andSqlCondition(SqlCondition.begin()
-                                    .orPrepare(["PRODUCTPRICE", "RELATION_ID", "validPP"], priceListFilter.relationId, "# <= ?")
-                                    .orSqlCondition(SqlCondition.begin()
-                                        .and("validPP.RELATION_ID is null")
-                                        .andPrepare(["PRODUCTPRICE", "BUYSELL", "validPP"], 'SP'), 
-                                    "1 = 2"), 
-                                "1 = 2")
-                                .build("1 = 2")))
-    }
-    
-    var ProductDataSql = SqlCondition.begin()
-                            .andPrepare("PRODUCT.PRODUCTID", pid)
-                            .buildSelect("select " + cols.join(", ") + " from PRODUCT " + joins.join(" "),
-                                         "1 = 2",
-                                         "order by " + orderby.join(", "))
-
-    var ProductData = db.table(ProductDataSql);
-
-    for (var i = 0; i < ProductData.length; i++)
-    {
-        //Product
-        if (ProductDetails.productId == undefined)
-        {
-            ProductDetails = {
-                            productId: ProductData[i][0]
-                            , productName: ProductData[i][1]
-                            , groupCode: ProductData[i][2]
-                            , unit: ProductData[i][3]
-                            , PriceLists: {}
-                            , CurrentValidPriceLists: {}
-                            , PriceListToUse: null
-                        };
-                        
-            // add additional fields to the details
-            var countPos = defaultProductFieldCount;
-            additionalProductInfoFields.forEach(function(productField)
-            {
-                this[productField] = ProductData[i][countPos];
-                countPos++;
-            }, ProductDetails);
-        }
-        //Pricelist (all)
-        var colIdx = colsProduct.length;
-        if (ProductData[i][colIdx] != "" && ProductDetails.PriceLists[ProductData[i][colIdx]] == undefined) //Pricelist found
-        {
-            ProductDetails.PriceLists[ProductData[i][colIdx]] = _getPriceListObject();
-        }
-
-        //Pricelist (currently valid)
-        colIdx = colsProduct.length + colsPricelistAll.length;
-        if (validPriceLists)
-        {
-            if (ProductData[i][colIdx] != "" && ProductDetails.CurrentValidPriceLists[ProductData[i][colIdx]] == undefined) //Pricelist found
-            {
-                ProductDetails.CurrentValidPriceLists[ProductData[i][colIdx]] = _getPriceListObject();
-            }
-        }
-    }
-
-    if (validPriceLists)
-        ProductDetails.PriceListToUse = _getPriceListToUse(ProductDetails.CurrentValidPriceLists, priceListFilter);
-
-    return ProductDetails;
-
-    function _getPriceListObject() {
-        return {
-                priceListId: ProductData[i][colIdx++]
-                , relationId: ProductData[i][colIdx++]
-                , priceList: ProductData[i][colIdx++]
-                , price: ProductData[i][colIdx++]
-                , vat: ProductData[i][colIdx++]
-                , validFrom: ProductData[i][colIdx++]
-                , validTo: ProductData[i][colIdx++]
-                , buySell: ProductData[i][colIdx++]
-                , fromQuantity: ProductData[i][colIdx++]
-                , currency: ProductData[i][colIdx++]
-        };
-    }
-
-    //price list to use for offer/order
-    function _getPriceListToUse(priceLists, priceListFilter) {
-        for (var list in priceLists) {
-            //custom price (defined in Org -> Conditions)
-            if (priceListFilter.relationId != "" && priceListFilter.relationId == priceLists[list].relationId) {
-                return priceLists[list];
-            }
-            //customer deposited price list (defined by Attribute)
-            if (priceListFilter.priceList != "" && priceListFilter.priceList == priceLists[list].priceList) {
-                return priceLists[list];
-            }
-            //default price list
-            if (priceLists[list].priceList == "1") {
-                return priceLists[list];
-            }
-        }
-
-        //no valid price list found
-        return null;
-    }
-}
-
-/**
- * Checks if there is already an existing price list identical to the passed price list 
- * 
- * @param {String} pid ProductID
- * @param {Object} priceList { <br>
- *                                  priceList: "keyvalue of keyword 'PRICELIST'" <br>
- *                                  , validFrom: TIMESTAMP <br>
- *                                  , validTo: TIMESTAMP <br>
- *                                  , buySell: "SP" / "PP" <br>
- *                                  , fromQuantity: "fromquantity" <br>
- *                                  , currency: "keyvalue of keyword 'CURRENCY'" <br>
- *                             }
- * 
- * @example //Productprice_entity, Field: PRICELIST, Process: onValidation
- *          var pUtils = new ProductUtils();
- *          var priceList = {
- *                          priceList: ProcessHandlingUtils.getOnValidationValue(vars.get("$field.PRICELIST"))
- *                          , fromQuantity: vars.get("$field.FROMQUANTITY")
- *                          , buySell: vars.get("$field.BUYSELL")
- *                          , currency: vars.get("$field.CURRENCY")
- *                          , validFrom: vars.get("$field.VALID_FROM")
- *                          , validTo: vars.get("$field.VALID_TO")
- *                      };
- *
- *          var identicalPriceList = pUtils.checkForIndenticalPriceLists(vars.get("$field.PRODUCT_ID"), priceList);
- *          if (identicalPriceList != null)
- *          {
- *              result.string(translate.text("Identical price list found!"));
- *          }
- * 
- * @return {Object | null} null if no identical price list was found, otherwise the found price list
- */
-ProductUtils.checkForIndenticalPriceLists = function(pid, priceList) {
-    var PriceLists = this.getProductDetails(pid).PriceLists;
-
-    for (var pricelist in PriceLists) {
-        //equal price list
-        //equal fromquantity
-        //equal currency
-        //equal pp/sp
-        if (priceList.priceList == PriceLists[pricelist].priceList 
-            && priceList.fromQuantity == PriceLists[pricelist].fromQuantity 
-            && priceList.buySell == PriceLists[pricelist].buySell
-            && priceList.currency == PriceLists[pricelist].currency) {
-            
-            //identical validFrom & validTo
-            // OR NOT [ validFrom_new <= validFrom & validTo_new <= validTo
-            //        OR validFrom_new >= validFrom & validTo_new >= validTo
-            //        OR validFrom_new < validFrom & validTo_new > validTo
-            // ]
-            if (priceList.validFrom == PriceLists[pricelist].validFrom && priceList.validTo == PriceLists[pricelist].validTo
-                || ! (priceList.validFrom <= PriceLists[pricelist].validFrom && priceList.validTo <= PriceLists[pricelist].validTo
-                       || priceList.validFrom >= PriceLists[pricelist].validFrom && priceList.validTo >= PriceLists[pricelist].validTo
-                       || priceList.validFrom < PriceLists[pricelist].validFrom && priceList.validTo > PriceLists[pricelist].validTo)) {
-                //identical price list found
-                return PriceLists[pricelist];
-            }
-        }
-    }
-
-    //no identical price list found
-    return null;        
-}
-
-/**
- * returns the image for a product
- * 
- * @param {String} pProductId the id of the product.
- * @param {String} pDefaultText the text, to use for default image generation.
- * @return {String} base64 coded String of the image. If none existed, the given String is used to create an image.
- */
-ProductUtils.getImage = function(pProductId, pDefaultText)
-{
-    return ImageUtils.get("PRODUCT", "IMAGE", pProductId, pDefaultText);
-}
-
-/**
- * sets the image of a product
- * 
- * @param {String} pProductId the id of the product.
- * @param {String} pImageDateBase64 base64 coded String of the image.
- * @return {Boolean} if image could be set
- */
-ProductUtils.setImage = function(pProductId, pImageDateBase64)
-{
-    return ImageUtils.set("PRODUCT", "IMAGE", pProductId, pImageDateBase64, "ProductImage", "Image of the product");
-}
-
-/**
- * deletes the image of a product
- * 
- * @param {String} pProductId the id of the product.
- * @return {Boolean} if image could be removed
- */
-ProductUtils.removeImage = function(pProductId)
-{
-    return ImageUtils.remove("PRODUCT", "IMAGE", pProductId);
-}
-
-/**
- * Class containing utility functions for Prod2Prod (Parts list)
- * 
- * @param {String} productId req ProductID
- * 
- * @class
- *
- */
-function Prod2ProdUtils(productId) {    
-    this.productId = productId;
-    this.data = undefined;
-}
-
-/**
- * Delivers an Object containing parts list structure for passed product "productId" (Constructor parameter)
- * 
- * @return {Object} { $prod2prodid$ { <br>
- *                       ids: [ Array containing child Prod2ProdIds for passed product "pProductId" (Constructor parameter) ] <br>
- *                       , rowdata: [ "PROD2PRODID", "DEST_ID", "SOURCE_ID", "QUANTITY", "OPTIONAL", "TAKEPRICE" ] from DB-Table PROD2PROD <br>
- *                       , destid: "Parent ProductID" <br>
- *                       , sourceid: "Child ProductID" <br>
- *                       , quantity: "Quantity" <br>
- *                       , optional: "0" = not optional, "1" = optional <br>
- *                       , takeprice: "0" = no price, "1" = price <br>
- *                  } }
- */
-Prod2ProdUtils.prototype.getPartsListObject = function() {
-    return this._relateChilds().getTreeObject();
-}
-
-/**
- * Delivers a 2D-Array for RecordContainer of Entity "Prod2prod_entity" 
- * containing parts list for passed product "productId" (Constructor parameter).
- * 
- * It is necessary to generate a specifically UID for the RecordContainer because 
- * the same data record can be listed several times. Therefore the primary key "PROD2PRODID"
- * can not be used for UID because this must be unique.
- * 
- * @return {String[][]} [ ["UID"
- *                    , "PARENTID" (equals "DEST_ID")
- *                    , "PROD2PRODID"
- *                    , "DEST_ID"
- *                    , "SOURCE_ID"
- *                    , "QUANTITY"
- *                    , "OPTIONAL"
- *                    , "TAKEPRICE"
- *                    , "PRODUCTCODE"] ]
- */
-Prod2ProdUtils.prototype.getPartsListForRecordContainer = function() {
-    var tree = this._relateChilds();
-    return tree.toArray();
-//    var ret = [];
-//    var childs = this._relateChilds();
-//    
-//    // map internal, (uids used in this function) concatenated ids to new random generated uuids. 
-//    // Without this every depth would make the uid significantly longer.
-//    var uidMap = {};
-//    
-//    __push("", childs.root, 0);
-//    
-//
-//    
-//    
-//    function __push(parent, obj) {
-//        logging.log(obj.toSource())
-//        //
-//        
-//        for (var i = 0; i < obj.ids.length; i++) {
-//            logging.log(childs[obj.ids[i]].toSource())
-//            var nextUid = parent + obj.ids[i];
-//            __addRow(nextUid, parent, childs[obj.ids[i]].rowdata)
-//           
-//            __push(nextUid, childs[obj.ids[i]])
-//        }
-//    }
-//    
-//    function __addRow(uid, parentId, rowdata)
-//    {
-//        uidMap[uid] = util.getNewUUID();
-//        if (uidMap[parentId] == undefined) {
-//            uidMap[parentId] = util.getNewUUID();
-//        }
-//        
-//        ret.push([uidMap[uid], uidMap[parentId]].concat(rowdata));
-//    }
-//    
-//    return ret;
-}
-
-/**
-* Delivers an Array containing productids of the parts list 
-* for passed product "productId" (Constructor parameter).
-* 
-* 
-* @return {String[]} [ "SOURCE_ID" ]
-*/
-Prod2ProdUtils.prototype.getPartsListProdIds = function() {
-    var ret = [];
-    var childs = this._relateChilds().getTreeObject();
-
-    __push(childs.root);
-
-    return ret;
-
-    function __push(pObj) {
-        for (var i = 0; i < pObj.ids.length; i++) {
-            ret.push(childs[pObj.ids[i]].sourceid);
-            __push(childs[pObj.ids[i]]);
-        }
-    }
-}
-
-/**
-* Delivers an Array containing productids of the parent list
-* for passed product "productId" (Constructor parameter).
-* 
-* 
-* @return {String[]} [ "DEST_ID" ]
-*/
-Prod2ProdUtils.prototype.getParentProdIds = function() {
-    var ret = [];
-    var parents = this._relateParents();
-
-    __push(parents.root);
-
-    return ret;
-
-    function __push(pObj) {
-        for (var i = 0; i < pObj.ids.length; i++) {
-            ret.push(parents[pObj.ids[i]].destid);
-            __push(parents[pObj.ids[i]]);
-        }
-    }
-}
-
-/** 
-* Function to initalize class variable "data" containing complete Prod2Prod-Data.<br>
-* It guarantees a unique load of data per instance.
-*
-* @ignore
-*/
-Prod2ProdUtils.prototype._initProd2ProdData = function() {
-    if (this.data == undefined) {
-        this.data = db.table("select SOURCE_ID, DEST_ID, PROD2PRODID, QUANTITY, OPTIONAL, TAKEPRICE, PRODUCTCODE, SOURCE_ID, DEST_ID "
-                    + "from PROD2PROD join PRODUCT on PROD2PROD.SOURCE_ID = PRODUCTID "
-                    + "order by PRODUCTCODE ");
-    }
-}
-
-/* object tree to relate products by DEST_ID / SOURCE_ID.
- * 
- **/
-Prod2ProdUtils.prototype._buildTree = function(supervised) {
-    this._initProd2ProdData();
-    var productId = this.productId;
-    
-    logging.log(this.data.toSource());
-    var tree = DataTree.begin(this.productId).addArray(this.data,
-        function(pUid, pNode)
-        {
-            logging.log(pUid)
-            if (pUid == productId)
-            {
-                pNode["sourceid"] = productId;
-                if (supervised) 
-                {
-                    pNode["destid"] = productId;
-                }
-            } 
-            else
-            {
-                pNode["destid"] = pNode.parent;
-                pNode["sourceid"] = pUid;
-                
-                if (pNode.data != undefined) {
-                    pNode["quantity"] = pNode.data[1];
-                    pNode["optional"] = pNode.data[2];
-                    pNode["takeprice"] = pNode.data[3];
-                    pNode["productcode"] = pNode.data[4];
-                }
-            }
-        }
-    );
-    /*
-
-    var tree = { root: {ids: [], sourceid: this.productId } };
-
-    if (supervised)
-        tree = { root: {ids: [], destid: this.productId } };
-
-    for (var i = 0; i < this.data.length; i++) {
-        var prod2prodid = this.data[i][0];
-        if (tree[prod2prodid] == undefined) {
-            tree[prod2prodid] = {
-                ids: [] 
-                , rowdata: this.data[i].slice(0)//copy to get NativeArray for concatenation
-                , destid: this.data[i][1]
-                , sourceid: this.data[i][2] 
-                , quantity: this.data[i][3]
-                , optional: this.data[i][4]
-                , takeprice: this.data[i][5]
-                , productcode: this.data[i][6]
-            };
-        }
-    }
-*/
-    return tree;
-}
-
-Prod2ProdUtils.prototype._relateChilds = function() {
-    var tree = this._buildTree(false);
-    logging.log(tree.getTreeObject().toSource())
-    __relate(this.productId);
-    logging.log(tree.getTreeObject().toSource())
-
-    return tree;
-
-    function __relate(id) {
-        var treeObject = tree.getTreeObject();
-        for (var treeId in treeObject) {
-            if (treeObject[treeId].destid == treeObject[id].sourceid && treeObject[id].ids.indexOf(treeId) == -1) { 
-                treeObject[id].ids.push(treeId);
-                __relate(treeId);
-            }    
-        }
-    }
-}
-/*
-Prod2ProdUtils.prototype._relateChilds = function() {
-    var tree = this._buildTree(false);
-    logging.log(tree.toSource())
-    
-    __relate("root");
-    
-    logging.log(tree.toSource())
-
-    return tree;
-
-
-    function __relate(id) {
-        for (var treeId in tree) {
-            if (tree[treeId].destid == tree[id].sourceid && tree[id].ids.indexOf(treeId) == -1) {   
-                tree[id].ids.push(treeId);
-                __relate(treeId);
-            }    
-        }
-    }
-}
-*/
-Prod2ProdUtils.prototype._relateParents = function() {
-    var tree = this._buildTree(true);
-
-    __relate(this.productId);
-
-    return tree;
-
-
-    function __relate(id) {
-        var treeObject = tree.getTreeObject();
-        for (var treeId in treeObject) {
-            if (treeObject[treeId].sourceid == treeObject[id].destid && treeObject[id].ids.indexOf(treeId) == -1) {   
-                treeObject[id].ids.push(treeId);
-                __relate(treeId);
-            }    
-        }
-    }
+import("system.util");
+import("system.SQLTYPES");
+import("system.datetime");
+import("system.db");
+import("system.vars");
+import("system.translate");
+import("Util_lib");
+import("Binary_lib");
+import("Sql_lib");
+import("Keyword_lib");
+import("Data_lib");
+
+/**
+ * utility functions for products
+ * Do not create an instance of this!
+ * 
+ * @class
+ */
+function ProductUtils() {}
+
+/**
+ * Delivers the currently valid product price 
+ * 
+ * @param {String} pid ProductID
+ * @param {String} buySell possible values: PP, SP
+ * 
+ * @example productUtils.getCurrentProductPrice(vars.get("$field.PRODUCTID"), "PP")
+ * 
+ * @return {String} currently valid product price
+ */
+ProductUtils.getCurrentProductPrice = function(pid, buySell) {
+    if (pid != undefined && pid != "" && buySell != undefined && buySell != "")
+    {
+        var today = datetime.clearTime(vars.get("sys.date"), "utc");
+        var actualPriceCondition = SqlCondition.begin()
+                    .andPrepare("PRODUCTPRICE.BUYSELL", buySell)
+                    .andPrepare("PRODUCTPRICE.PRODUCT_ID", pid)
+                    .andPrepare("PRODUCTPRICE.CURRENCY", 1) // TODO: warum ist Currency hardgecoded auf 1??
+                    .andPrepare("PRODUCTPRICE.VALID_FROM", today, "# <= ?")
+                    .andSqlCondition(SqlCondition.begin()
+                        .orPrepare("PRODUCTPRICE.VALID_TO", today, "# >= ?")
+                        .or("PRODUCTPRICE.VALID_TO is null"), "1 = 2");
+                            
+        var productPriceData = db.array(db.ROW, actualPriceCondition.buildSelect("select PRICE, CURRENCY from PRODUCTPRICE", "1 = 2", "order by VALID_FROM desc"));
+        
+        if (productPriceData[0] && productPriceData[1])
+            return  productPriceData[0] + " " + KeywordUtils.get("CURRENCY", productPriceData[1])[1];
+        else
+            return "";
+    } else {
+        throw new Error(); // TODO: add message
+    }
+}
+
+/**
+ * Delivers the stock
+ * 
+ * @param {String} pid ProductID
+ * 
+ * @example productUtils.getStockCount(vars.get("$field.PRODUCTID"))
+ * 
+ * @return {String} stock count
+ */
+ProductUtils.getStockCount = function(pid) {
+    if (pid != undefined && pid != "")
+    {
+        var sum = db.cell(SqlCondition.begin()
+                                      .andPrepare("STOCK.PRODUCT_ID", pid)
+                                      .buildSelect("select sum(QUANTITY * case IN_OUT when 0 then -1 else 1)"
+                                                 + " from STOCK"));
+        
+        if (sum == "")
+            sum = "0";
+
+        return sum;
+    }
+    else
+    {
+        throw new Error();//TODO: add message
+    }
+}
+
+/**
+ * Delivers metadata and price lists of the passed product. 
+ * If parameter "priceListFilter" is passed valid price lists and the 
+ * current price list to use for offer/order are delivered.
+ * 
+ * @param {String} pid req ProductID
+ * @param {Object} priceListFilter opt { currency: "currencyValue", quantity: "quantityValue", relationId: "relationIdValue (for custom price lists)" }
+ * @param {String[]} additionalProductInfoFields additional fields from Product
+ *                   They are added to the result with the Fieldname as key. e.g. if the array is ["INFO"] the result will contain the key "INFO"
+ * 
+ * @example //Product_entity, Field: PRODUCT_ID, Process: onValueChange
+ *          var pid = ProcessHandlingUtils.getOnValidationValue(vars.get("$field.PRODUCT_ID"));
+ *          var curr = vars.exists("$param.Currency_param") ? vars.get("$param.Currency_param") : "";
+ *          var relid = vars.exists("$param.RelationId_param") ? vars.get("$param.RelationId_param") : "";
+ *          var pUtils = new ProductUtils();
+ *          var PriceListFilter = { currency: curr, quantity: vars.get("$field.QUANTITY"), relationId: relid };
+ *          var ProductDetails = pUtils.getProductDetails(pid, PriceListFilter, ["INFO"]);
+ * 
+ * @return {Object} { <br>
+ *                   productId: "productid" <br>
+ *                   , productName: "product name" <br>
+ *                   , groupCode: "keyvalue of keyword 'GROUPCODE'" <br>
+ *                   , unit: "keyvalue of keyword 'UNIT'" <br>
+ *                   , PriceLists: {$pricelistid$ { <br>
+ *                          priceListId: "pricelistid" <br>
+ *                          , relationId: "relationid" when filled -> custom price list <br>
+ *                          , priceList: "keyvalue of keyword 'PRICELIST'" <br>
+ *                          , price: "price" <br>
+ *                          , vat: "vat" <br>
+ *                          , validFrom: TIMESTAMP <br>
+ *                          , validTo: TIMESTAMP <br>
+ *                          , buySell: "SP" / "PP" <br>
+ *                          , fromQuantity: "fromquantity" <br>
+ *                          , currency: "keyvalue of keyword 'CURRENCY'" <br>
+ *                      } } <br>
+ *                   , CurrentValidPriceLists: {$pricelistid$ { <br>
+ *                          priceListId: "pricelistid" <br>
+ *                          , relationId: "relationid" when filled -> custom price list <br>
+ *                          , priceList: "keyvalue of keyword 'PRICELIST'" <br>
+ *                          , price: "price" <br>
+ *                          , vat: "vat" <br>
+ *                          , validFrom: TIMESTAMP <br>
+ *                          , validTo: TIMESTAMP <br>
+ *                          , buySell: "SP" / "PP" <br>
+ *                          , fromQuantity: "fromquantity" <br>
+ *                          , currency: "keyvalue of keyword 'CURRENCY'" <br>
+ *                      } } <br>
+ *                   , PriceListToUse: {$pricelistid$ { <br>
+ *                          priceListId: "pricelistid" <br>
+ *                          , relationId: "relationid" when filled -> custom price list <br>
+ *                          , priceList: "keyvalue of keyword 'PRICELIST'" <br>
+ *                          , price: "price" <br>
+ *                          , vat: "vat" <br>
+ *                          , validFrom: TIMESTAMP <br>
+ *                          , validTo: TIMESTAMP <br>
+ *                          , buySell: "SP" / "PP" <br>
+ *                          , fromQuantity: "fromquantity" <br>
+ *                          , currency: "keyvalue of keyword 'CURRENCY'" <br>
+ *                      } }, <br>
+ *                   INFO: "the productinfo"
+ *               }
+ */
+ProductUtils.getProductDetails = function(pid, priceListFilter, additionalProductInfoFields)
+{
+    if (additionalProductInfoFields == undefined) {additionalProductInfoFields = []}
+    var ProductDetails = {};
+
+    var cols = [];
+    var colsProduct = ["PRODUCT.PRODUCTID", "PRODUCT.PRODUCTNAME", "PRODUCT.GROUPCODEID", "PRODUCT.UNIT"];
+    var defaultProductFieldCount = colsProduct.length;
+    colsProduct = colsProduct.concat(additionalProductInfoFields.map(function(item) {return "PRODUCT." + item}));
+    
+    cols = cols.concat(colsProduct);
+
+    var joins = [];
+    var orderby = ["PRODUCTID"];
+
+    //PriceList (all)
+    var colsPricelistAll = ["allPP.PRODUCTPRICEID", "allPP.RELATION_ID", "allPP.PRICELIST", "allPP.PRICE", "allPP.VAT"
+                        , "allPP.VALID_FROM", "allPP.VALID_TO", "allPP.BUYSELL", "allPP.FROMQUANTITY", "allPP.CURRENCY"];
+
+    cols = cols.concat(colsPricelistAll);
+    joins.push(" left join PRODUCTPRICE allPP on allPP.PRODUCT_ID = PRODUCTID ");
+
+    //PriceList (currently valid)
+    var validPriceLists = false;
+    if (priceListFilter != undefined 
+        && priceListFilter.currency != undefined && priceListFilter.currency != "" 
+        && priceListFilter.quantity != undefined && priceListFilter.quantity != "")
+    {
+        validPriceLists = true;
+        var colsPricelistValid = ["validPP.PRODUCTPRICEID", "validPP.RELATION_ID", "validPP.PRICELIST", "validPP.PRICE", "validPP.VAT"
+                        , "validPP.VALID_FROM", "validPP.VALID_TO", "validPP.BUYSELL", "validPP.FROMQUANTITY", "validPP.CURRENCY"];
+
+        cols = cols.concat(colsPricelistValid);
+        joins.push("left join PRODUCTPRICE validPP on " 
+                    + db.translateCondition(SqlCondition.begin()
+                               .and("validPP.PRODUCT_ID = PRODUCTID")
+                               .andPrepare(["PRODUCTPRICE", "CURRENCY", "validPP"], priceListFilter.currency)
+                               .andPrepare(["PRODUCTPRICE", "VALID_FROM", "validPP"], datetime.date().toString(), "# <= ?")
+                               .andPrepare(["PRODUCTPRICE", "FROMQUANTITY", "validPP"], priceListFilter.quantity, "# <= ?")
+                               .andSqlCondition(SqlCondition.begin()
+                                    .orPrepare(["PRODUCTPRICE", "RELATION_ID", "validPP"], priceListFilter.relationId, "# <= ?")
+                                    .orSqlCondition(SqlCondition.begin()
+                                        .and("validPP.RELATION_ID is null")
+                                        .andPrepare(["PRODUCTPRICE", "BUYSELL", "validPP"], 'SP'), 
+                                    "1 = 2"), 
+                                "1 = 2")
+                                .build("1 = 2")))
+    }
+    
+    var ProductDataSql = SqlCondition.begin()
+                            .andPrepare("PRODUCT.PRODUCTID", pid)
+                            .buildSelect("select " + cols.join(", ") + " from PRODUCT " + joins.join(" "),
+                                         "1 = 2",
+                                         "order by " + orderby.join(", "))
+
+    var ProductData = db.table(ProductDataSql);
+
+    for (var i = 0; i < ProductData.length; i++)
+    {
+        //Product
+        if (ProductDetails.productId == undefined)
+        {
+            ProductDetails = {
+                            productId: ProductData[i][0]
+                            , productName: ProductData[i][1]
+                            , groupCode: ProductData[i][2]
+                            , unit: ProductData[i][3]
+                            , PriceLists: {}
+                            , CurrentValidPriceLists: {}
+                            , PriceListToUse: null
+                        };
+                        
+            // add additional fields to the details
+            var countPos = defaultProductFieldCount;
+            additionalProductInfoFields.forEach(function(productField)
+            {
+                this[productField] = ProductData[i][countPos];
+                countPos++;
+            }, ProductDetails);
+        }
+        //Pricelist (all)
+        var colIdx = colsProduct.length;
+        if (ProductData[i][colIdx] != "" && ProductDetails.PriceLists[ProductData[i][colIdx]] == undefined) //Pricelist found
+        {
+            ProductDetails.PriceLists[ProductData[i][colIdx]] = _getPriceListObject();
+        }
+
+        //Pricelist (currently valid)
+        colIdx = colsProduct.length + colsPricelistAll.length;
+        if (validPriceLists)
+        {
+            if (ProductData[i][colIdx] != "" && ProductDetails.CurrentValidPriceLists[ProductData[i][colIdx]] == undefined) //Pricelist found
+            {
+                ProductDetails.CurrentValidPriceLists[ProductData[i][colIdx]] = _getPriceListObject();
+            }
+        }
+    }
+
+    if (validPriceLists)
+        ProductDetails.PriceListToUse = _getPriceListToUse(ProductDetails.CurrentValidPriceLists, priceListFilter);
+
+    return ProductDetails;
+
+    function _getPriceListObject() {
+        return {
+                priceListId: ProductData[i][colIdx++]
+                , relationId: ProductData[i][colIdx++]
+                , priceList: ProductData[i][colIdx++]
+                , price: ProductData[i][colIdx++]
+                , vat: ProductData[i][colIdx++]
+                , validFrom: ProductData[i][colIdx++]
+                , validTo: ProductData[i][colIdx++]
+                , buySell: ProductData[i][colIdx++]
+                , fromQuantity: ProductData[i][colIdx++]
+                , currency: ProductData[i][colIdx++]
+        };
+    }
+
+    //price list to use for offer/order
+    function _getPriceListToUse(priceLists, priceListFilter) {
+        for (var list in priceLists) {
+            //custom price (defined in Org -> Conditions)
+            if (priceListFilter.relationId != "" && priceListFilter.relationId == priceLists[list].relationId) {
+                return priceLists[list];
+            }
+            //customer deposited price list (defined by Attribute)
+            if (priceListFilter.priceList != "" && priceListFilter.priceList == priceLists[list].priceList) {
+                return priceLists[list];
+            }
+            //default price list
+            if (priceLists[list].priceList == "1") {
+                return priceLists[list];
+            }
+        }
+
+        //no valid price list found
+        return null;
+    }
+}
+
+/**
+ * Checks if there is already an existing price list identical to the passed price list 
+ * 
+ * @param {String} pid ProductID
+ * @param {Object} priceList { <br>
+ *                                  priceList: "keyvalue of keyword 'PRICELIST'" <br>
+ *                                  , validFrom: TIMESTAMP <br>
+ *                                  , validTo: TIMESTAMP <br>
+ *                                  , buySell: "SP" / "PP" <br>
+ *                                  , fromQuantity: "fromquantity" <br>
+ *                                  , currency: "keyvalue of keyword 'CURRENCY'" <br>
+ *                             }
+ * 
+ * @example //Productprice_entity, Field: PRICELIST, Process: onValidation
+ *          var pUtils = new ProductUtils();
+ *          var priceList = {
+ *                          priceList: ProcessHandlingUtils.getOnValidationValue(vars.get("$field.PRICELIST"))
+ *                          , fromQuantity: vars.get("$field.FROMQUANTITY")
+ *                          , buySell: vars.get("$field.BUYSELL")
+ *                          , currency: vars.get("$field.CURRENCY")
+ *                          , validFrom: vars.get("$field.VALID_FROM")
+ *                          , validTo: vars.get("$field.VALID_TO")
+ *                      };
+ *
+ *          var identicalPriceList = pUtils.checkForIndenticalPriceLists(vars.get("$field.PRODUCT_ID"), priceList);
+ *          if (identicalPriceList != null)
+ *          {
+ *              result.string(translate.text("Identical price list found!"));
+ *          }
+ * 
+ * @return {Object | null} null if no identical price list was found, otherwise the found price list
+ */
+ProductUtils.checkForIndenticalPriceLists = function(pid, priceList) {
+    var PriceLists = this.getProductDetails(pid).PriceLists;
+
+    for (var pricelist in PriceLists) {
+        //equal price list
+        //equal fromquantity
+        //equal currency
+        //equal pp/sp
+        if (priceList.priceList == PriceLists[pricelist].priceList 
+            && priceList.fromQuantity == PriceLists[pricelist].fromQuantity 
+            && priceList.buySell == PriceLists[pricelist].buySell
+            && priceList.currency == PriceLists[pricelist].currency) {
+            
+            //identical validFrom & validTo
+            // OR NOT [ validFrom_new <= validFrom & validTo_new <= validTo
+            //        OR validFrom_new >= validFrom & validTo_new >= validTo
+            //        OR validFrom_new < validFrom & validTo_new > validTo
+            // ]
+            if (priceList.validFrom == PriceLists[pricelist].validFrom && priceList.validTo == PriceLists[pricelist].validTo
+                || ! (priceList.validFrom <= PriceLists[pricelist].validFrom && priceList.validTo <= PriceLists[pricelist].validTo
+                       || priceList.validFrom >= PriceLists[pricelist].validFrom && priceList.validTo >= PriceLists[pricelist].validTo
+                       || priceList.validFrom < PriceLists[pricelist].validFrom && priceList.validTo > PriceLists[pricelist].validTo)) {
+                //identical price list found
+                return PriceLists[pricelist];
+            }
+        }
+    }
+
+    //no identical price list found
+    return null;        
+}
+
+/**
+ * returns the image for a product
+ * 
+ * @param {String} pProductId the id of the product.
+ * @param {String} pDefaultText the text, to use for default image generation.
+ * @return {String} base64 coded String of the image. If none existed, the given String is used to create an image.
+ */
+ProductUtils.getImage = function(pProductId, pDefaultText)
+{
+    return ImageUtils.get("PRODUCT", "IMAGE", pProductId, pDefaultText);
+}
+
+/**
+ * sets the image of a product
+ * 
+ * @param {String} pProductId the id of the product.
+ * @param {String} pImageDateBase64 base64 coded String of the image.
+ * @return {Boolean} if image could be set
+ */
+ProductUtils.setImage = function(pProductId, pImageDateBase64)
+{
+    return ImageUtils.set("PRODUCT", "IMAGE", pProductId, pImageDateBase64, "ProductImage", "Image of the product");
+}
+
+/**
+ * deletes the image of a product
+ * 
+ * @param {String} pProductId the id of the product.
+ * @return {Boolean} if image could be removed
+ */
+ProductUtils.removeImage = function(pProductId)
+{
+    return ImageUtils.remove("PRODUCT", "IMAGE", pProductId);
+}
+
+/**
+ * Class containing utility functions for Prod2Prod (Parts list)
+ * 
+ * @param {String} productId req ProductID
+ * 
+ * @class
+ *
+ */
+function Prod2ProdUtils(productId) {    
+    this.productId = productId;
+    this.data = undefined;
+}
+
+/**
+ * Delivers an Object containing parts list structure for passed product "productId" (Constructor parameter)
+ * 
+ * @return {Object} { $prod2prodid$ { <br>
+ *                       ids: [ Array containing child Prod2ProdIds for passed product "pProductId" (Constructor parameter) ] <br>
+ *                       , rowdata: [ "PROD2PRODID", "DEST_ID", "SOURCE_ID", "QUANTITY", "OPTIONAL", "TAKEPRICE" ] from DB-Table PROD2PROD <br>
+ *                       , destid: "Parent ProductID" <br>
+ *                       , sourceid: "Child ProductID" <br>
+ *                       , quantity: "Quantity" <br>
+ *                       , optional: "0" = not optional, "1" = optional <br>
+ *                       , takeprice: "0" = no price, "1" = price <br>
+ *                  } }
+ */
+Prod2ProdUtils.prototype.getPartsListObject = function() {
+    return this._relateChilds().getTreeObject();
+}
+
+/**
+ * Delivers a 2D-Array for RecordContainer of Entity "Prod2prod_entity" 
+ * containing parts list for passed product "productId" (Constructor parameter).
+ * 
+ * It is necessary to generate a specifically UID for the RecordContainer because 
+ * the same data record can be listed several times. Therefore the primary key "PROD2PRODID"
+ * can not be used for UID because this must be unique.
+ * 
+ * @return {String[][]} [ ["UID"
+ *                    , "PARENTID" (equals "DEST_ID")
+ *                    , "PROD2PRODID"
+ *                    , "DEST_ID"
+ *                    , "SOURCE_ID"
+ *                    , "QUANTITY"
+ *                    , "OPTIONAL"
+ *                    , "TAKEPRICE"
+ *                    , "PRODUCTCODE"] ]
+ */
+Prod2ProdUtils.prototype.getPartsListForRecordContainer = function() {
+    var tree = this._relateChilds();
+    return tree.toArray(7);
+//    var ret = [];
+//    var childs = this._relateChilds();
+//    
+//    // map internal, (uids used in this function) concatenated ids to new random generated uuids. 
+//    // Without this every depth would make the uid significantly longer.
+//    var uidMap = {};
+//    
+//    __push("", childs.root, 0);
+//    
+//
+//    
+//    
+//    function __push(parent, obj) {
+//        logging.log(obj.toSource())
+//        //
+//        
+//        for (var i = 0; i < obj.ids.length; i++) {
+//            logging.log(childs[obj.ids[i]].toSource())
+//            var nextUid = parent + obj.ids[i];
+//            __addRow(nextUid, parent, childs[obj.ids[i]].rowdata)
+//           
+//            __push(nextUid, childs[obj.ids[i]])
+//        }
+//    }
+//    
+//    function __addRow(uid, parentId, rowdata)
+//    {
+//        uidMap[uid] = util.getNewUUID();
+//        if (uidMap[parentId] == undefined) {
+//            uidMap[parentId] = util.getNewUUID();
+//        }
+//        
+//        ret.push([uidMap[uid], uidMap[parentId]].concat(rowdata));
+//    }
+//    
+//    return ret;
+}
+
+/**
+* Delivers an Array containing productids of the parts list 
+* for passed product "productId" (Constructor parameter).
+* 
+* 
+* @return {String[]} [ "SOURCE_ID" ]
+*/
+Prod2ProdUtils.prototype.getPartsListProdIds = function() {
+    var ret = [];
+    var childs = this._relateChilds().getTreeObject();
+
+    __push(childs.root);
+
+    return ret;
+
+    function __push(pObj) {
+        for (var i = 0; i < pObj.ids.length; i++) {
+            ret.push(childs[pObj.ids[i]].sourceid);
+            __push(childs[pObj.ids[i]]);
+        }
+    }
+}
+
+/**
+* Delivers an Array containing productids of the parent list
+* for passed product "productId" (Constructor parameter).
+* 
+* 
+* @return {String[]} [ "DEST_ID" ]
+*/
+Prod2ProdUtils.prototype.getParentProdIds = function() {
+    var ret = [];
+    var parents = this._relateParents();
+
+    __push(parents.root);
+
+    return ret;
+
+    function __push(pObj) {
+        for (var i = 0; i < pObj.ids.length; i++) {
+            ret.push(parents[pObj.ids[i]].destid);
+            __push(parents[pObj.ids[i]]);
+        }
+    }
+}
+
+/** 
+* Function to initalize class variable "data" containing complete Prod2Prod-Data.<br>
+* It guarantees a unique load of data per instance.
+*
+* @ignore
+*/
+Prod2ProdUtils.prototype._initProd2ProdData = function() {
+    if (this.data == undefined) {
+        this.data = db.table("select SOURCE_ID, DEST_ID, PROD2PRODID, QUANTITY, OPTIONAL, TAKEPRICE, PRODUCTCODE, SOURCE_ID, DEST_ID "
+                    + "from PROD2PROD join PRODUCT on PROD2PROD.SOURCE_ID = PRODUCTID "
+                    + "order by PRODUCTCODE ");
+    }
+}
+
+/* object tree to relate products by DEST_ID / SOURCE_ID.
+ * 
+ **/
+Prod2ProdUtils.prototype._buildTree = function(supervised) {
+    this._initProd2ProdData();
+    var productId = this.productId;
+    
+    var tree = DataTree.begin(this.productId).addArray(this.data,
+        function(pUid, pNode)
+        {
+            if (pUid == productId)
+            {
+                pNode["sourceid"] = productId;
+                if (supervised) 
+                {
+                    pNode["destid"] = productId;
+                }
+            } 
+            else
+            {
+                pNode["destid"] = pNode.parent;
+                pNode["sourceid"] = pUid;
+                
+                if (pNode.data != undefined) {
+                    pNode["quantity"] = pNode.data[1];
+                    pNode["optional"] = pNode.data[2];
+                    pNode["takeprice"] = pNode.data[3];
+                    pNode["productcode"] = pNode.data[4];
+                }
+            }
+        }
+    );
+    /*
+
+    var tree = { root: {ids: [], sourceid: this.productId } };
+
+    if (supervised)
+        tree = { root: {ids: [], destid: this.productId } };
+
+    for (var i = 0; i < this.data.length; i++) {
+        var prod2prodid = this.data[i][0];
+        if (tree[prod2prodid] == undefined) {
+            tree[prod2prodid] = {
+                ids: [] 
+                , rowdata: this.data[i].slice(0)//copy to get NativeArray for concatenation
+                , destid: this.data[i][1]
+                , sourceid: this.data[i][2] 
+                , quantity: this.data[i][3]
+                , optional: this.data[i][4]
+                , takeprice: this.data[i][5]
+                , productcode: this.data[i][6]
+            };
+        }
+    }
+*/
+    return tree;
+}
+
+Prod2ProdUtils.prototype._relateChilds = function() {
+    var tree = this._buildTree(false);
+    __relate(this.productId);
+
+    return tree;
+
+    function __relate(id) {
+        var treeObject = tree.getTreeObject();
+        for (var treeId in treeObject) {
+            if (treeObject[treeId].destid == treeObject[id].sourceid && treeObject[id].ids.indexOf(treeId) == -1) { 
+                treeObject[id].ids.push(treeId);
+                __relate(treeId);
+            }    
+        }
+    }
+}
+/*
+Prod2ProdUtils.prototype._relateChilds = function() {
+    var tree = this._buildTree(false);
+    logging.log(tree.toSource())
+    
+    __relate("root");
+    
+    logging.log(tree.toSource())
+
+    return tree;
+
+
+    function __relate(id) {
+        for (var treeId in tree) {
+            if (tree[treeId].destid == tree[id].sourceid && tree[id].ids.indexOf(treeId) == -1) {   
+                tree[id].ids.push(treeId);
+                __relate(treeId);
+            }    
+        }
+    }
+}
+*/
+Prod2ProdUtils.prototype._relateParents = function() {
+    var tree = this._buildTree(true);
+
+    __relate(this.productId);
+
+    return tree;
+
+
+    function __relate(id) {
+        var treeObject = tree.getTreeObject();
+        for (var treeId in treeObject) {
+            if (treeObject[treeId].sourceid == treeObject[id].destid && treeObject[id].ids.indexOf(treeId) == -1) {   
+                treeObject[id].ids.push(treeId);
+                __relate(treeId);
+            }    
+        }
+    }
 }
\ No newline at end of file