From 0882ac2265867cfad6c51178070c04c9acbbfe60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Maximilian=20Schr=C3=B6ger?= <m.schroeger@adito.de>
Date: Tue, 13 Nov 2018 11:04:19 +0100
Subject: [PATCH] =?UTF-8?q?St=C3=BCcklisten=20ERSTE=20Version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 entity/Offeritem_entity/Offeritem_entity.aod  |   1 +
 entity/Offeritem_entity/onDBInsert.js         |  83 +++++++
 entity/Prod2prod_entity/Prod2prod_entity.aod  | 138 +++++++++++
 entity/Prod2prod_entity/contentProcess.js     |  14 ++
 .../entityfields/date_edit/valueProcess.js    |   6 +
 .../entityfields/date_new/valueProcess.js     |   7 +
 .../entityfields/dest_id/valueProcess.js      |  10 +
 .../optional/possibleItemsProcess.js          |   7 +
 .../entityfields/optional/valueProcess.js     |   6 +
 .../entityfields/quantity/valueProcess.js     |  10 +
 .../entityfields/source_id/onValidation.js    |  29 +++
 .../source_id/possibleItemsProcess.js         |  30 +++
 .../takeprice/possibleItemsProcess.js         |   7 +
 .../entityfields/uid/valueProcess.js          |   7 +
 .../entityfields/user_edit/valueProcess.js    |   6 +
 .../entityfields/user_new/valueProcess.js     |   6 +
 entity/Prod2prod_entity/externalOpenAction.js |   4 +
 entity/Prod2prod_entity/onDelete.js           |   4 +
 entity/Prod2prod_entity/onInsert.js           |  25 ++
 entity/Prod2prod_entity/onUpdate.js           |  23 ++
 entity/Product_entity/Product_entity.aod      |  22 ++
 .../children/productid_param/code.js          |   4 +
 entity/Product_entity/orderClauseProcess.js   |   0
 .../entityfields/fromquantity/valueProcess.js |  20 +-
 .../_____LANGUAGE_EXTRA.aod                   |   6 +
 .../_____LANGUAGE_de/_____LANGUAGE_de.aod     |   4 +
 .../_____LANGUAGE_en/_____LANGUAGE_en.aod     |   6 +
 .../Prod2prod_context/Prod2prod_context.aod   |  19 ++
 .../Prod2prodFilter_view.aod                  |  43 ++++
 .../Prod2prodPreview_view.aod                 |  10 +
 .../ProductMain_view/ProductMain_view.aod     |   5 +
 process/Offer_lib/process.js                  |   7 +
 process/Product_lib/process.js                | 214 ++++++++++++++++--
 33 files changed, 751 insertions(+), 32 deletions(-)
 create mode 100644 entity/Prod2prod_entity/Prod2prod_entity.aod
 create mode 100644 entity/Prod2prod_entity/contentProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/date_edit/valueProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/date_new/valueProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/dest_id/valueProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/optional/possibleItemsProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/optional/valueProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/quantity/valueProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/source_id/onValidation.js
 create mode 100644 entity/Prod2prod_entity/entityfields/source_id/possibleItemsProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/takeprice/possibleItemsProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/uid/valueProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/user_edit/valueProcess.js
 create mode 100644 entity/Prod2prod_entity/entityfields/user_new/valueProcess.js
 create mode 100644 entity/Prod2prod_entity/externalOpenAction.js
 create mode 100644 entity/Prod2prod_entity/onDelete.js
 create mode 100644 entity/Prod2prod_entity/onInsert.js
 create mode 100644 entity/Prod2prod_entity/onUpdate.js
 create mode 100644 entity/Product_entity/entityfields/productprod2prod_dfo/children/productid_param/code.js
 create mode 100644 entity/Product_entity/orderClauseProcess.js
 create mode 100644 neonContext/Prod2prod_context/Prod2prod_context.aod
 create mode 100644 neonView/Prod2prodFilter_view/Prod2prodFilter_view.aod
 create mode 100644 neonView/Prod2prodPreview_view/Prod2prodPreview_view.aod

diff --git a/entity/Offeritem_entity/Offeritem_entity.aod b/entity/Offeritem_entity/Offeritem_entity.aod
index 5cca45ce71..c28e322e3b 100644
--- a/entity/Offeritem_entity/Offeritem_entity.aod
+++ b/entity/Offeritem_entity/Offeritem_entity.aod
@@ -117,6 +117,7 @@
       <columnName>PRODUCT_ID</columnName>
       <caption>Article</caption>
       <possibleItemsProcess>%aditoprj%/entity/Offeritem_entity/entityfields/product_id/possibleItemsProcess.js</possibleItemsProcess>
+      <onValidation>%aditoprj%/entity/Offeritem_entity/entityfields/product_id/onValidation.js</onValidation>
       <onValueChange>%aditoprj%/entity/Offeritem_entity/entityfields/product_id/onValueChange.js</onValueChange>
     </entityField>
     <entityField>
diff --git a/entity/Offeritem_entity/onDBInsert.js b/entity/Offeritem_entity/onDBInsert.js
index d27032ac0e..786f099d48 100644
--- a/entity/Offeritem_entity/onDBInsert.js
+++ b/entity/Offeritem_entity/onDBInsert.js
@@ -1,11 +1,48 @@
+import("system.datetime");
 import("system.neon");
 import("system.vars");
 import("system.db");
+import("system.util");
 import("Offer_lib");
+import("Product_lib");
 
 var oid = vars.get("$field.OFFER_ID");
 if(oid != "")
 {
+    //insert parts list
+    var rootProdId = vars.get("$field.PRODUCT_ID");
+    if(rootProdId != "")
+    {
+        var p2pUtils = new Prod2prodUtils();
+        var pUtils = new ProductUtils();
+        var partsList = p2pUtils.getSubordinatedObject(rootProdId);
+        var statements = [];
+        var cols =  ["OFFERITEMID"
+                            , "OFFER_ID"
+                            , "PRODUCT_ID"
+                            , "GROUPCODEID"
+                            , "ASSIGNEDTO"
+                            , "ITEMNAME"
+                            , "UNIT"
+                            , "PRICE"
+                            , "VAT"
+                            , "QUANTITY"
+                            , "OPTIONAL"
+                            , "ITEMPOSITION"
+                            , "ITEMSORT"
+                            , "DATE_NEW"
+                            , "USER_NEW"];
+
+        var colTypes = db.getColumnTypes("OFFERITEM", cols);
+
+        __offeritemInsertStatement(partsList.root, vars.get("$field.OFFERITEMID"), vars.get("$field.ITEMPOSITION"));
+
+        if(statements.length > 0)
+            db.inserts(statements);
+    }
+    
+    
+    //update offer price
     var cols = ["NET", "VAT"];
     var colTypes = db.getColumnTypes("OFFER", cols);
     var oUtils = new OfferUtils();
@@ -14,4 +51,50 @@ if(oid != "")
     db.updateData("OFFER", cols, colTypes, vals, "OFFERID = '" + oid + "'");
     
     neon.refresh("Offer_entity");
+}
+
+function __offeritemInsertStatement(pPartsListObj, pAssignedTo, pPos)
+{
+    for(var i = 0; i < pPartsListObj.ids.length; i++)
+    {
+        var p2pid = pPartsListObj.ids[i];
+        var newid = util.getNewUUID();
+
+        var Prod2prodObj = partsList[p2pid];
+        var prodid = partsList[p2pid].prodid;
+
+        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 ProdDetails = pUtils.getProductDetails(prodid, { currency: curr, quantity: Prod2prodObj.quantity, relationId: relid } )
+
+        var price = "";
+        var vat = "";
+        if(Prod2prodObj.takeprice == "Y" && ProdDetails.PriceListToUse != null)
+        {
+            price = ProdDetails.PriceListToUse.price;
+            vat = ProdDetails.PriceListToUse.vat;
+        }
+
+        var vals =  [newid
+                    , oid
+                    , prodid
+                    , ProdDetails.groupCode
+                    , pAssignedTo
+                    , ProdDetails.productName
+                    , ProdDetails.unit
+                    , price
+                    , vat
+                    , Prod2prodObj.quantity
+                    , Prod2prodObj.optional
+                    , Prod2prodObj.pos //TODO: Pos
+                    , "" //TODO: Itemsort
+                    , datetime.date()
+                    , vars.get("$sys.user")
+                     ];
+
+        statements.push(["OFFERITEM", cols, colTypes, vals]);
+
+        __offeritemInsertStatement(partsList[p2pid], newid);
+    }
 }
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/Prod2prod_entity.aod b/entity/Prod2prod_entity/Prod2prod_entity.aod
new file mode 100644
index 0000000000..837bb6c123
--- /dev/null
+++ b/entity/Prod2prod_entity/Prod2prod_entity.aod
@@ -0,0 +1,138 @@
+<?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.0.4" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.0.4">
+  <name>Prod2prod_entity</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <externalOpenAction>%aditoprj%/entity/Prod2prod_entity/externalOpenAction.js</externalOpenAction>
+  <alias>Data_alias</alias>
+  <jDitoRecordAlias>Data_alias</jDitoRecordAlias>
+  <fields>
+    <element>UID</element>
+    <element>DEST_ID</element>
+    <element>SOURCE_ID</element>
+    <element>QUANTITY</element>
+    <element>OPTIONAL</element>
+    <element>TAKEPRICE</element>
+    <element>POS</element>
+    <element>PARENTID</element>
+  </fields>
+  <contentProcess>%aditoprj%/entity/Prod2prod_entity/contentProcess.js</contentProcess>
+  <isPageable v="false" />
+  <isSortable v="false" />
+  <onInsert>%aditoprj%/entity/Prod2prod_entity/onInsert.js</onInsert>
+  <onUpdate>%aditoprj%/entity/Prod2prod_entity/onUpdate.js</onUpdate>
+  <onDelete>%aditoprj%/entity/Prod2prod_entity/onDelete.js</onDelete>
+  <recordContainerType>JDITO</recordContainerType>
+  <entityFields>
+    <entityIncomingField>
+      <name>#INCOMING</name>
+      <dependencies>
+        <entityDependency>
+          <name>87bdd527-83c1-4700-915f-e87afb65f144</name>
+          <entityName>Product_entity</entityName>
+          <fieldName>ProductProd2prod_dfo</fieldName>
+          <isOutgoing v="false" />
+        </entityDependency>
+      </dependencies>
+    </entityIncomingField>
+    <entityField>
+      <name>DATE_EDIT</name>
+      <tableName></tableName>
+      <contentType>DATE</contentType>
+      <valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/date_edit/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>DATE_NEW</name>
+      <tableName></tableName>
+      <columnName></columnName>
+      <contentType>DATE</contentType>
+      <valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/date_new/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>DEST_ID</name>
+      <tableName></tableName>
+      <columnName></columnName>
+      <fieldName>DEST_ID</fieldName>
+      <valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/dest_id/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>OPTIONAL</name>
+      <title>Optional</title>
+      <tableName></tableName>
+      <columnName></columnName>
+      <fieldName>OPTIONAL</fieldName>
+      <caption>Optional</caption>
+      <contentType>BOOLEAN</contentType>
+      <possibleItemsProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/optional/possibleItemsProcess.js</possibleItemsProcess>
+      <valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/optional/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>UID</name>
+      <tableName></tableName>
+      <columnName></columnName>
+      <fieldName>UID</fieldName>
+      <valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/uid/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>QUANTITY</name>
+      <tableName></tableName>
+      <columnName></columnName>
+      <fieldName>QUANTITY</fieldName>
+      <caption>Quantity</caption>
+      <valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/quantity/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>SOURCE_ID</name>
+      <tableName></tableName>
+      <columnName></columnName>
+      <fieldName>SOURCE_ID</fieldName>
+      <caption>Product</caption>
+      <possibleItemsProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/source_id/possibleItemsProcess.js</possibleItemsProcess>
+      <onValidation>%aditoprj%/entity/Prod2prod_entity/entityfields/source_id/onValidation.js</onValidation>
+    </entityField>
+    <entityField>
+      <name>TAKEPRICE</name>
+      <tableName></tableName>
+      <columnName></columnName>
+      <fieldName>TAKEPRICE</fieldName>
+      <caption>Price</caption>
+      <contentType>BOOLEAN</contentType>
+      <possibleItemsProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/takeprice/possibleItemsProcess.js</possibleItemsProcess>
+    </entityField>
+    <entityField>
+      <name>USER_EDIT</name>
+      <tableName></tableName>
+      <columnName></columnName>
+      <valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/user_edit/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>USER_NEW</name>
+      <tableName></tableName>
+      <columnName></columnName>
+      <valueProcess>%aditoprj%/entity/Prod2prod_entity/entityfields/user_new/valueProcess.js</valueProcess>
+    </entityField>
+    <entityParameter>
+      <name>ProductId_param</name>
+      <expose v="true" />
+      <triggerRecalculation v="true" />
+      <description>PARAMETER</description>
+    </entityParameter>
+    <entityField>
+      <name>POS</name>
+      <fieldName>POS</fieldName>
+      <caption>Pos</caption>
+    </entityField>
+    <entityField>
+      <name>PARENTID</name>
+      <fieldName>PARENTID</fieldName>
+      <caption>Parent</caption>
+    </entityField>
+  </entityFields>
+  <linkInformation>
+    <linkInformation>
+      <name>96c9cc1a-26ee-4cc3-8e83-330420fc2c60</name>
+      <tableName>PROD2PROD</tableName>
+      <primaryKey>PROD2PRODID</primaryKey>
+      <isUIDTable v="true" />
+    </linkInformation>
+  </linkInformation>
+</entity>
diff --git a/entity/Prod2prod_entity/contentProcess.js b/entity/Prod2prod_entity/contentProcess.js
new file mode 100644
index 0000000000..922c7492f5
--- /dev/null
+++ b/entity/Prod2prod_entity/contentProcess.js
@@ -0,0 +1,14 @@
+import("system.result");
+import("system.vars");
+import("system.db");
+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();
+    
+    result.object(p2pUtils.getSubordinatedData2DArray(prodid));
+}
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/date_edit/valueProcess.js b/entity/Prod2prod_entity/entityfields/date_edit/valueProcess.js
new file mode 100644
index 0000000000..00e95d744e
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/date_edit/valueProcess.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_EDIT)
+    result.string(vars.getString("$sys.date"));
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/date_new/valueProcess.js b/entity/Prod2prod_entity/entityfields/date_new/valueProcess.js
new file mode 100644
index 0000000000..abfd322661
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/date_new/valueProcess.js
@@ -0,0 +1,7 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+    result.string(vars.getString("$sys.date"));
+
diff --git a/entity/Prod2prod_entity/entityfields/dest_id/valueProcess.js b/entity/Prod2prod_entity/entityfields/dest_id/valueProcess.js
new file mode 100644
index 0000000000..4428a4ab94
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/dest_id/valueProcess.js
@@ -0,0 +1,10 @@
+import("system.result");
+import("system.neon");
+import("system.vars");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+{
+    if(vars.exists("$param.ProductId_param") && vars.get("$param.ProductId_param") != null && vars.get("$param.ProductId_param") != "")
+        result.string(vars.getString("$param.ProductId_param"));    
+}
+
diff --git a/entity/Prod2prod_entity/entityfields/optional/possibleItemsProcess.js b/entity/Prod2prod_entity/entityfields/optional/possibleItemsProcess.js
new file mode 100644
index 0000000000..1dfbf04839
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/optional/possibleItemsProcess.js
@@ -0,0 +1,7 @@
+import("system.translate");
+import("system.result");
+
+result.object([
+     ["0", translate.text("Yes")]
+    ,["1", translate.text("No")]
+]);
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/optional/valueProcess.js b/entity/Prod2prod_entity/entityfields/optional/valueProcess.js
new file mode 100644
index 0000000000..8a574b0a35
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/optional/valueProcess.js
@@ -0,0 +1,6 @@
+//import("system.vars");
+//import("system.result");
+//import("system.neon");
+//
+//if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+//    result.string("1");
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/quantity/valueProcess.js b/entity/Prod2prod_entity/entityfields/quantity/valueProcess.js
new file mode 100644
index 0000000000..11dd557c3f
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/quantity/valueProcess.js
@@ -0,0 +1,10 @@
+//import("system.vars");
+//import("system.result");
+//import("system.neon");
+//
+//if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW && vars.get("$this.value") == "")
+//{
+//    result.string("1");
+//}
+//else
+//    result.string(vars.get("$this.value"));
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/source_id/onValidation.js b/entity/Prod2prod_entity/entityfields/source_id/onValidation.js
new file mode 100644
index 0000000000..09a093be99
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/source_id/onValidation.js
@@ -0,0 +1,29 @@
+//import("system.vars");
+//import("system.result");
+//import("system.db");
+//import("system.neon");
+//import("Keyword_lib");
+//import("Product_lib");
+//
+//var kwUtils = new KeywordUtils();
+//
+//var condition = "";
+//if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_EDIT || vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+//{
+//    var prodid = vars.get("$field.DEST_ID");
+//    var excludeableProds = [prodid];
+//    
+//    var p2pUtils = new Prod2prodUtils();
+//    excludeableProds = excludeableProds.concat(p2pUtils.getSubordinatedProdIds(prodid));
+//    
+//    condition += " where PRODUCTID not in ('" + excludeableProds.join("','") + "')";
+//}
+//
+//var prods = db.table("select PRODUCTID, GROUPCODEID, PRODUCTNAME, PRODUCTCODE from PRODUCT " + condition);
+//var res = [];
+//for(var i = 0; i < prods.length; i++)
+//{
+//    res.push([prods[i][0], kwUtils.getViewValue("GROUPCODE", prods[i][1]) + " / " + prods[i][2] + " / " + prods[i][3]]);
+//}
+//
+//result.object(res);
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/source_id/possibleItemsProcess.js b/entity/Prod2prod_entity/entityfields/source_id/possibleItemsProcess.js
new file mode 100644
index 0000000000..bee5aec9a2
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/source_id/possibleItemsProcess.js
@@ -0,0 +1,30 @@
+import("system.vars");
+import("system.result");
+import("system.db");
+import("system.neon");
+import("Keyword_lib");
+import("Product_lib");
+
+var kwUtils = new KeywordUtils();
+
+var condition = "";
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_EDIT || vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+{
+    var prodid = vars.get("$field.DEST_ID");
+    var excludeableProds = [prodid];
+    
+    var p2pUtils = new Prod2prodUtils();
+    excludeableProds = excludeableProds.concat(p2pUtils.getSubordinatedProdIds(prodid));
+    excludeableProds = excludeableProds.concat(p2pUtils.getSupervisedProdIds(prodid));
+    
+    condition += " where PRODUCTID not in ('" + excludeableProds.join("','") + "')";
+}
+
+var prods = db.table("select PRODUCTID, GROUPCODEID, PRODUCTNAME, PRODUCTCODE from PRODUCT " + condition);
+var res = [];
+for(var i = 0; i < prods.length; i++)
+{
+    res.push([prods[i][0], kwUtils.getViewValue("GROUPCODE", prods[i][1]) + " / " + prods[i][2] + " / " + prods[i][3]]);
+}
+
+result.object(res);
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/takeprice/possibleItemsProcess.js b/entity/Prod2prod_entity/entityfields/takeprice/possibleItemsProcess.js
new file mode 100644
index 0000000000..f31ec18e89
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/takeprice/possibleItemsProcess.js
@@ -0,0 +1,7 @@
+import("system.translate");
+import("system.result");
+
+result.object([
+     ["Y", translate.text("Yes")]
+    ,["N", translate.text("No")]
+]);
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/uid/valueProcess.js b/entity/Prod2prod_entity/entityfields/uid/valueProcess.js
new file mode 100644
index 0000000000..5be18c3983
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/uid/valueProcess.js
@@ -0,0 +1,7 @@
+import("system.util");
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+    result.string(util.getNewUUID());
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/user_edit/valueProcess.js b/entity/Prod2prod_entity/entityfields/user_edit/valueProcess.js
new file mode 100644
index 0000000000..67c86b14ca
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/user_edit/valueProcess.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_EDIT)
+    result.string(vars.getString("$sys.user"));
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/entityfields/user_new/valueProcess.js b/entity/Prod2prod_entity/entityfields/user_new/valueProcess.js
new file mode 100644
index 0000000000..81966a3fbc
--- /dev/null
+++ b/entity/Prod2prod_entity/entityfields/user_new/valueProcess.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+    result.string(vars.getString("$sys.user"));
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/externalOpenAction.js b/entity/Prod2prod_entity/externalOpenAction.js
new file mode 100644
index 0000000000..5e4ce1796f
--- /dev/null
+++ b/entity/Prod2prod_entity/externalOpenAction.js
@@ -0,0 +1,4 @@
+import("system.vars");
+import("system.neon");
+
+neon.openContext("Product_context", [vars.get("$field.SOURCE_ID")], neon.OPERATINGSTATE_VIEW, null);
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/onDelete.js b/entity/Prod2prod_entity/onDelete.js
new file mode 100644
index 0000000000..db58c1cefa
--- /dev/null
+++ b/entity/Prod2prod_entity/onDelete.js
@@ -0,0 +1,4 @@
+import("system.vars");
+import("system.db");
+
+db.deleteData("PROD2PROD", "PROD2PRODID = '" + vars.get("$field.UID") + "'");
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/onInsert.js b/entity/Prod2prod_entity/onInsert.js
new file mode 100644
index 0000000000..a20684ae00
--- /dev/null
+++ b/entity/Prod2prod_entity/onInsert.js
@@ -0,0 +1,25 @@
+import("system.datetime");
+import("system.vars");
+import("system.db");
+
+var cols = [ "PROD2PRODID"
+           , "DEST_ID"
+           , "SOURCE_ID"
+           , "QUANTITY"
+           , "OPTIONAL"
+           , "TAKEPRICE"
+           , "DATE_NEW"
+           , "USER_NEW" ];
+
+var vals = [ vars.get("$field.UID")
+           , vars.get("$field.DEST_ID")
+           , vars.get("$field.SOURCE_ID")
+           , vars.get("$field.QUANTITY")
+           , vars.get("$field.OPTIONAL")
+           , vars.get("$field.TAKEPRICE")
+           , vars.get("$field.DATE_NEW")
+           , vars.get("$field.USER_NEW") ];
+
+var colTypes = db.getColumnTypes("PROD2PROD", cols);
+
+db.insertData("PROD2PROD", cols, colTypes, vals);
\ No newline at end of file
diff --git a/entity/Prod2prod_entity/onUpdate.js b/entity/Prod2prod_entity/onUpdate.js
new file mode 100644
index 0000000000..93a576e2c7
--- /dev/null
+++ b/entity/Prod2prod_entity/onUpdate.js
@@ -0,0 +1,23 @@
+import("system.datetime");
+import("system.vars");
+import("system.db");
+
+var cols = [ "DEST_ID"
+           , "SOURCE_ID"
+           , "QUANTITY"
+           , "OPTIONAL"
+           , "TAKEPRICE"
+           , "DATE_EDIT"
+           , "USER_EDIT" ];
+
+var vals = [ vars.get("$field.DEST_ID")
+           , vars.get("$field.SOURCE_ID")
+           , vars.get("$field.QUANTITY")
+           , vars.get("$field.OPTIONAL")
+           , vars.get("$field.TAKEPRICE")
+           , vars.get("$field.DATE_EDIT")
+           , vars.get("$field.USER_EDIT") ];
+
+var colTypes = db.getColumnTypes("PROD2PROD", cols);
+
+db.updateData("PROD2PROD", cols, colTypes, vals, "PROD2PRODID = '" + vars.get("$field.UID") + "'");
\ No newline at end of file
diff --git a/entity/Product_entity/Product_entity.aod b/entity/Product_entity/Product_entity.aod
index b329898832..529105de08 100644
--- a/entity/Product_entity/Product_entity.aod
+++ b/entity/Product_entity/Product_entity.aod
@@ -4,6 +4,8 @@
   <title>Product</title>
   <majorModelMode>DISTRIBUTED</majorModelMode>
   <alias>Data_alias</alias>
+  <orderClauseProcess>%aditoprj%/entity/Product_entity/orderClauseProcess.js</orderClauseProcess>
+  <jDitoRecordAlias>Data_alias</jDitoRecordAlias>
   <recordContainerType>DB</recordContainerType>
   <caption>Product</caption>
   <iconId>VAADIN:HAMMER</iconId>
@@ -227,6 +229,26 @@
     <entityIncomingField>
       <name>#INCOMING</name>
     </entityIncomingField>
+    <entityOutgoingField>
+      <name>ProductProd2prod_dfo</name>
+      <title>Parts list</title>
+      <fieldType>DEPENDENCY_OUT</fieldType>
+      <caption>Parts list</caption>
+      <dependency>
+        <name>dependency</name>
+        <entityName>Prod2prod_entity</entityName>
+        <fieldName>#INCOMING</fieldName>
+      </dependency>
+      <children>
+        <entityParameter>
+          <name>ProductId_param</name>
+          <code>%aditoprj%/entity/Product_entity/entityfields/productprod2prod_dfo/children/productid_param/code.js</code>
+          <expose v="true" />
+          <triggerRecalculation v="true" />
+          <mandatory v="true" />
+        </entityParameter>
+      </children>
+    </entityOutgoingField>
   </entityFields>
   <linkInformation>
     <linkInformation>
diff --git a/entity/Product_entity/entityfields/productprod2prod_dfo/children/productid_param/code.js b/entity/Product_entity/entityfields/productprod2prod_dfo/children/productid_param/code.js
new file mode 100644
index 0000000000..eaa8f9632d
--- /dev/null
+++ b/entity/Product_entity/entityfields/productprod2prod_dfo/children/productid_param/code.js
@@ -0,0 +1,4 @@
+import("system.result");
+import("system.vars");
+
+result.string(vars.get("$field.PRODUCTID"));
\ No newline at end of file
diff --git a/entity/Product_entity/orderClauseProcess.js b/entity/Product_entity/orderClauseProcess.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/entity/Productprice_entity/entityfields/fromquantity/valueProcess.js b/entity/Productprice_entity/entityfields/fromquantity/valueProcess.js
index 3aebc70e19..11dd557c3f 100644
--- a/entity/Productprice_entity/entityfields/fromquantity/valueProcess.js
+++ b/entity/Productprice_entity/entityfields/fromquantity/valueProcess.js
@@ -1,10 +1,10 @@
-import("system.vars");
-import("system.result");
-import("system.neon");
-
-if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW && vars.get("$this.value") == "")
-{
-    result.string("1");
-}
-else
-    result.string(vars.get("$this.value"));
\ No newline at end of file
+//import("system.vars");
+//import("system.result");
+//import("system.neon");
+//
+//if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW && vars.get("$this.value") == "")
+//{
+//    result.string("1");
+//}
+//else
+//    result.string(vars.get("$this.value"));
\ No newline at end of file
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index 229bfbb65f..af2f7de64d 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -750,6 +750,12 @@
     <entry>
       <key>Identical price list found!</key>
     </entry>
+    <entry>
+      <key>Current purchase/sales price</key>
+    </entry>
+    <entry>
+      <key>Parts list</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
   <sqlModels>
diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
index ccc2672c0e..7270d815e8 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -967,6 +967,10 @@
       <key>Identical price list found!</key>
       <value>Identische Preisliste gefunden!</value>
     </entry>
+    <entry>
+      <key>Parts list</key>
+      <value>Stückliste</value>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index 0cd4f382da..c8e9e22263 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -759,6 +759,12 @@
     <entry>
       <key>Identical price list found!</key>
     </entry>
+    <entry>
+      <key>Current purchase/sales price</key>
+    </entry>
+    <entry>
+      <key>Parts list</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/neonContext/Prod2prod_context/Prod2prod_context.aod b/neonContext/Prod2prod_context/Prod2prod_context.aod
new file mode 100644
index 0000000000..8fe7acd0c3
--- /dev/null
+++ b/neonContext/Prod2prod_context/Prod2prod_context.aod
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.0.0">
+  <name>Prod2prod_context</name>
+  <title></title>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <filterview>Prod2prodFilter_view</filterview>
+  <preview>Prod2prodPreview_view</preview>
+  <entity>Prod2prod_entity</entity>
+  <references>
+    <neonViewReference>
+      <name>0f388c5e-7873-49de-8396-16a2e01dfa84</name>
+      <view>Prod2prodFilter_view</view>
+    </neonViewReference>
+    <neonViewReference>
+      <name>2a037997-7a55-4005-956e-fccf12ccc9d2</name>
+      <view>Prod2prodPreview_view</view>
+    </neonViewReference>
+  </references>
+</neonContext>
diff --git a/neonView/Prod2prodFilter_view/Prod2prodFilter_view.aod b/neonView/Prod2prodFilter_view/Prod2prodFilter_view.aod
new file mode 100644
index 0000000000..a4e266e16d
--- /dev/null
+++ b/neonView/Prod2prodFilter_view/Prod2prodFilter_view.aod
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.0">
+  <name>Prod2prodFilter_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <tableViewTemplate>
+      <name>Prod2prod_table</name>
+      <autoNewRow v="true" />
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonTableColumn>
+          <name>296fcc2e-775f-4f05-822e-8e91a9eaa037</name>
+          <entityField>POS</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>1c681134-4741-4dd6-b4c3-899d98216b72</name>
+          <entityField>PARENTID</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>723600d0-7d3b-4d96-9880-cb5b9ea90002</name>
+          <entityField>SOURCE_ID</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>3975b280-3f16-413c-8613-4de277cd8ece</name>
+          <entityField>QUANTITY</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>295adb8f-c639-4e5a-b02d-7f61756992ff</name>
+          <entityField>OPTIONAL</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>892a56f5-4417-4ece-9d94-70b1d9f0c4d4</name>
+          <entityField>TAKEPRICE</entityField>
+        </neonTableColumn>
+      </columns>
+    </tableViewTemplate>
+  </children>
+</neonView>
diff --git a/neonView/Prod2prodPreview_view/Prod2prodPreview_view.aod b/neonView/Prod2prodPreview_view/Prod2prodPreview_view.aod
new file mode 100644
index 0000000000..98582cacbd
--- /dev/null
+++ b/neonView/Prod2prodPreview_view/Prod2prodPreview_view.aod
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.0">
+  <name>Prod2prodPreview_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+</neonView>
diff --git a/neonView/ProductMain_view/ProductMain_view.aod b/neonView/ProductMain_view/ProductMain_view.aod
index fb403a674b..c1dc178e3e 100644
--- a/neonView/ProductMain_view/ProductMain_view.aod
+++ b/neonView/ProductMain_view/ProductMain_view.aod
@@ -14,6 +14,11 @@
       <entityField>#ENTITY</entityField>
       <view>ProductPreview_view</view>
     </neonViewReference>
+    <neonViewReference>
+      <name>7f416115-ff89-45ca-be10-ed568cac266c</name>
+      <entityField>ProductProd2prod_dfo</entityField>
+      <view>Prod2prodFilter_view</view>
+    </neonViewReference>
     <neonViewReference>
       <name>11c4c5a0-27fa-4748-a6c6-3a667d2f3d8f</name>
       <entityField>ProductProductprice_dfo</entityField>
diff --git a/process/Offer_lib/process.js b/process/Offer_lib/process.js
index fa042cdc34..e83df95957 100644
--- a/process/Offer_lib/process.js
+++ b/process/Offer_lib/process.js
@@ -85,5 +85,12 @@ function OfferItemUtils(){
     
     this.roundPrice = function(pPrice){
         return eMath.roundDec(pPrice, 2, eMath.ROUND_HALF_UP);
+    }
+    
+    this.insertPartsList = function()
+    {
+        
+        
+        
     }
 }
\ No newline at end of file
diff --git a/process/Product_lib/process.js b/process/Product_lib/process.js
index d9ff3b7d4b..c0149dd204 100644
--- a/process/Product_lib/process.js
+++ b/process/Product_lib/process.js
@@ -3,6 +3,7 @@ import("system.SQLTYPES");
 import("system.datetime");
 import("system.db");
 import("system.vars");
+import("Util_lib");
 
 function ProductUtils()
 {
@@ -87,9 +88,6 @@ function ProductUtils()
         var conditions = ["1=1"];
         var orderby = ["PRODUCTID"];
         var sqltypes = [];
-             
-        //Prod2Prod
-        //TODO: get product structure
         
         //PriceList (all)
         var colsPricelistAll = ["allPP.PRODUCTPRICEID", "allPP.RELATION_ID", "allPP.PRICELIST", "allPP.PRICE", "allPP.VAT"
@@ -125,30 +123,28 @@ function ProductUtils()
                    + " and " + conditions.join(" and ")
                    + " order by " + orderby.join(", ");
         
-        
         var ProductData = db.table([ProductDataSql, sqltypes]);
         
         for(var i = 0; i < ProductData.length; i++)
         {
             //Product
-            if(ProductDetails[ProductData[i][0]] == undefined)
+            if(ProductDetails.productId == undefined)
             {
-                ProductDetails[ProductData[i][0]] = {
-                    productId: ProductData[i][0]
-                    , productName: ProductData[i][1]
-                    , groupCode: ProductData[i][2]
-                    , unit: ProductData[i][3]
-                    , Prod2Prod: {}
-                    , PriceLists: {}
-                    , CurrentValidPriceLists: {}
-                    , PriceListToUse: null
-                };
+                ProductDetails = {
+                                productId: ProductData[i][0]
+                                , productName: ProductData[i][1]
+                                , groupCode: ProductData[i][2]
+                                , unit: ProductData[i][3]
+                                , PriceLists: {}
+                                , CurrentValidPriceLists: {}
+                                , PriceListToUse: null
+                            };
             }
             //Pricelist (all)
             var colIdx = colsProduct.length;
-            if(ProductData[i][colIdx] != "" && ProductDetails[ProductData[i][0]].PriceLists[ProductData[i][colIdx]] == undefined) //Pricelist found
+            if(ProductData[i][colIdx] != "" && ProductDetails.PriceLists[ProductData[i][colIdx]] == undefined) //Pricelist found
             {
-                ProductDetails[ProductData[i][0]].PriceLists[ProductData[i][colIdx]] = {
+                ProductDetails.PriceLists[ProductData[i][colIdx]] = {
                     priceListId: ProductData[i][colIdx++]
                     , relationId: ProductData[i][colIdx++]
                     , priceList: ProductData[i][colIdx++]
@@ -161,13 +157,14 @@ function ProductUtils()
                     , currency: ProductData[i][colIdx++]
                 }
             }
-            
+           
             //Pricelist (currently valid)
+            colIdx = colsProduct.length + colsPricelistAll.length;
             if(validPriceLists)
             {
-                if(ProductData[i][colIdx] != "" && ProductDetails[ProductData[i][0]].CurrentValidPriceLists[ProductData[i][colIdx]] == undefined) //Pricelist found
+                if(ProductData[i][colIdx] != "" && ProductDetails.CurrentValidPriceLists[ProductData[i][colIdx]] == undefined) //Pricelist found
                 {
-                    ProductDetails[ProductData[i][0]].CurrentValidPriceLists[ProductData[i][colIdx]] = {
+                    ProductDetails.CurrentValidPriceLists[ProductData[i][colIdx]] = {
                         priceListId: ProductData[i][colIdx++]
                         , relationId: ProductData[i][colIdx++]
                         , priceList: ProductData[i][colIdx++]
@@ -179,8 +176,8 @@ function ProductUtils()
         }
         
         if(validPriceLists)
-            ProductDetails[pPid].PriceListToUse = _getPriceListToUse(ProductDetails[pPid].CurrentValidPriceLists, pPriceListFilter);
-        
+            ProductDetails.PriceListToUse = _getPriceListToUse(ProductDetails.CurrentValidPriceLists, pPriceListFilter);
+            
         return ProductDetails;
         
         
@@ -253,4 +250,177 @@ function ProductUtils()
                  
     }
     
+}
+
+function Prod2prodUtils()
+{
+    var data = getProd2prodData();
+    
+    function getProd2prodData()
+    {
+        var sqlStr = "select PROD2PRODID, DEST_ID, SOURCE_ID, QUANTITY, OPTIONAL, TAKEPRICE "
+                            + "from PROD2PROD join PRODUCT on PROD2PROD.SOURCE_ID = PRODUCTID "
+                            + "order by PRODUCTCODE ";
+
+        return db.table(sqlStr);
+    }
+    
+    function _buildTree(pPid, pSupervised)
+    {
+        /* object tree to relate products by DEST_ID / SOURCE_ID.
+         * Parts list shows subordinated products.
+         **/
+        var tree = { root: {ids: [], sourceid: pPid } };
+        
+        if(pSupervised)
+            tree = { root: {ids: [], destid: pPid } };
+
+        for (var i = 0; i < data.length; i++)
+        {
+            var prod2prodid = data[i][0];
+            if ( tree[prod2prodid] == undefined )                                         
+            tree[prod2prodid] = {
+                ids: [] 
+                , prodid: ""
+                , rowdata: data[i].slice(0)//copy to get NativeArray for concatenation
+                , destid: data[i][1]
+                , sourceid: data[i][2] 
+                , quantity: data[i][3]
+                , optional: data[i][4]
+                , takeprice: data[i][5]
+                , pos: 0
+                , parentid: ""
+            };  
+        }
+        
+        return tree;
+    }
+    
+    function _getSubordinated(pPid)
+    {
+        var tree = _buildTree(pPid, false);
+
+        __relate("root", ["0"]);
+        
+        return tree;
+        
+        
+        function __relate(pID, pPos)
+        {
+            for ( var id in tree )
+            {
+                if ( tree[id].destid == tree[pID].sourceid && tree[pID].ids.indexOf(id) == -1 )
+                {   
+                    tree[pID].ids.push(id);
+
+                    var rowdata = tree[id].rowdata;
+                    pPos[pPos.length-1] = (Number(pPos[pPos.length-1]) + 1).toString();
+                                                 //POS, PARENTID
+                    rowdata = rowdata.concat([pPos.join("."), pID]);
+
+                    tree[id].rowdata = rowdata;
+                    tree[id].prodid = tree[id].sourceid;
+                    tree[id].pos = rowdata[6];
+                    tree[id].parentid = rowdata[7];
+
+                    __relate(id, pPos.concat([0]));
+                }    
+            }
+        }
+    }
+    
+    this.getSubordinatedObject = function(pPid)
+    {
+        return _getSubordinated(pPid);
+    }
+    
+    this.getSubordinatedData2DArray = function(pPid)
+    {
+        var ret = [];
+        var so = _getSubordinated(pPid);
+        
+        __push(so.root);
+        
+        function __push(pObj)
+        {
+            for(var i = 0; i < pObj.ids.length; i++)
+            {
+                ret.push(so[pObj.ids[i]].rowdata);
+                __push( so[pObj.ids[i]] );
+            }
+        }
+        
+        var dUtils = new DataUtils();
+        dUtils.array_mDimSort(ret, 6, true);
+        
+        return ret;
+    }
+    
+    this.getSubordinatedProdIds = function(pPid)
+    {
+        var ret = [];
+        var so = _getSubordinated(pPid);
+        for(var p2pid in so)
+            ret.push(so[p2pid].prodid);
+        
+        return ret;
+    }
+    
+    function _getSupervised(pPid)
+    {
+        var SuperVised = {};
+        
+        var tree = _buildTree(pPid, true);
+
+        __relate("root", ["0"]);
+        
+        return SuperVised;
+        
+        
+        function __relate(pID, pPos)
+        {
+            for ( var id in tree )
+            {
+                if ( tree[id].sourceid == tree[pID].destid && tree[pID].ids.indexOf(id) == -1 )
+                {   
+                   var rowdata = tree[id].data;
+                   pPos[pPos.length-1] = (Number(pPos[pPos.length-1]) + 1).toString();
+                                                //POS, PARENTID
+                   rowdata = rowdata.concat([pPos.join("."), pID]);
+                   
+                   SuperVised[id] = { prodid: tree[id].destid, data: rowdata };
+                   
+                   __relate(id, pPos.concat([0]));
+                }    
+            }
+        }
+    }
+    
+    this.getSupervisedData = function(pPid)
+    {
+        return _getSupervised(pPid);
+    }
+    
+    this.getSupervisedData2DArray = function(pPid)
+    {
+        var ret = [];
+        var so = _getSupervised(pPid);
+        for(var p2pid in so)
+            ret.push(so[p2pid].data);
+        
+        var dUtils = new DataUtils();
+        dUtils.array_mDimSort(ret, 6, true);
+        
+        return ret;
+    }
+    
+    this.getSupervisedProdIds = function(pPid)
+    {
+        var ret = [];
+        var so = _getSupervised(pPid);
+        for(var p2pid in so)
+            ret.push(so[p2pid].prodid);
+        
+        return ret;
+    }
 }
\ No newline at end of file
-- 
GitLab