Skip to content
Snippets Groups Projects
Commit f832c5bb authored by Johannes Hörmann's avatar Johannes Hörmann
Browse files

Merge branch 'Product_revert' into 'master'

Product revert

See merge request xrm/basic!27
parents a9d41ef2 1880446d
No related branches found
No related tags found
No related merge requests found
import("system.translate");
import("system.logging");
import("system.result");
import("system.vars");
logging.log("validate")
if (parseInt(vars.get("$field.QUANTITY")) <= 0)
{
result.string(translate.text("${QUANTITY_LOWER_THAN_1}"));
}
\ No newline at end of file
}
......@@ -139,15 +139,11 @@
<onDelete>%aditoprj%/entity/Prod2prod_entity/recordcontainers/jdito/onDelete.js</onDelete>
<recordFields>
<element>UID.value</element>
<element>PARENTID.value</element>
<element>PROD2PRODID.value</element>
<element>SOURCE_ID.value</element>
<element>DEST_ID.value</element>
<element>QUANTITY.value</element>
<element>OPTIONAL.value</element>
<element>TAKEPRICE.value</element>
<element>PRODUCTCODE.value</element>
<element>PRODUCTID.value</element>
<element>SOURCE_ID.value</element>
<element>DEST_ID.displayValue</element>
</recordFields>
</jDitoRecordContainer>
</recordContainers>
......
import("system.logging");
import("system.neon");
import("system.result");
import("system.vars");
......@@ -5,17 +6,138 @@ import("system.db");
import("system.util");
import("Product_lib");
/**
* Calculate the root elements for this tree.
*
* @param productRootID string
* @param rows TreeData[]
* @return string[]
*/
function calculateRootElements (productRootID, rows) {
return rows.filter(function (row) {
// Filter predicate if the DIST_ID matches.
return row[2] === productRootID;
}).map(function (row) {
// Map to PROD2PROD_ID.
return row[0];
});
}
/**
* Calculates a mapping object which has the PROD2PROD_ID as
* key and the full TreeData array as value.
*
* @param rows TreeData[]
* @return {[key: TreeData]}
*/
function buildProd2ProdIDMapping (rows) {
var mapping = {}
rows.forEach(function(row) {
// Create new property which PROD2PROD_ID as key and data
// as value.
mapping[row[0]] = row;
});
return mapping;
}
/**
* Calcualtes the children mapping structure which has the DIST_ID
* as key and an array of PROD2PROD_IDs as value.
*
* @param rows TreeData[]
* @return {[key: string[]]}
*/
function buildChildrenMapping(rows) {
var parrentMapping = {}
rows.forEach(function (row) {
// Create empty array if not created previously.
if (parrentMapping[row[2]] === undefined)
parrentMapping[row[2]] = []
// Push with DIST_ID as key and PROD2PROD_ID as value.
parrentMapping[row[2]].push(row[0]);
})
return parrentMapping
}
/**
* Calculates the graph starting from the given elementID.
*/
function buildGraph (elementID, parentElementID, mappingStructure, prod2prodIdMapping) {
var elements = []
// Get the PROD2PROD data array and copy it.
// Copying is requried due to mutability of arrays.
var elementData = prod2prodIdMapping[elementID].slice(0);
// Just as an error prevention.
if (elementData === undefined)
return elements;
// Generate new PROD2PROD_ID to create a uniqueness between the PROD2PROD objects.
var virtualProd2ProdId = util.getNewUUID();
// Override actual PROD2PROD_ID with new ID.
elementData[0] = virtualProd2ProdId;
// Override parent id to match overriden prod2prodId of parent
if (parentElementID === null || parentElementID === undefined)
// Describes an root element
elementData[2] = null;
else
elementData[2] = parentElementID;
// Push element data to elements array of this graph.
elements.push(elementData);
// Search for children
var childrens = mappingStructure[elementData[1]];
if (childrens !== undefined && childrens.length > 0) {
// Build graph for each children
childrens.forEach(function(children) {
// Recursive function call (!)
var graphResult = buildGraph(children, elementData[0], mappingStructure, prod2prodIdMapping);
graphResult.forEach(function(res) {elements.push(res)})
});
}
return elements;
}
if (vars.get("$sys.recordstate") != neon.OPERATINGSTATE_NEW)
{
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());
// First 3 columns are crucial, the rest is optional.
var data = db.table("select PROD2PRODID, SOURCE_ID, DEST_ID, QUANTITY, PRODUCTCODE, PRODUCTID "
+ "from PROD2PROD join PRODUCT on PROD2PROD.SOURCE_ID = PRODUCTID "
+ "order by PRODUCTCODE");
var prod2prodIdMapping = buildProd2ProdIDMapping(data);
var childrenMapping = buildChildrenMapping(data);
var rootElements = calculateRootElements(prodid, data);
var allData = []
rootElements.forEach(function(rg) {
var graphData = buildGraph(rg, null, childrenMapping, prod2prodIdMapping)
graphData.forEach(function (gd) { allData.push(gd); })
})
result.object(allData);
}
}
else
{
result.object([]);
}
\ No newline at end of file
}
......@@ -16,5 +16,9 @@
<name>428b22a1-427f-4547-a478-964442078bc1</name>
<view>Prod2ProdEdit_view</view>
</neonViewReference>
<neonViewReference>
<name>257aa20f-d6b4-4a64-8f61-bb62b6ef49c8</name>
<view>Prod2prodTable_view</view>
</neonViewReference>
</references>
</neonContext>
......@@ -11,7 +11,7 @@
<children>
<treetableViewTemplate>
<name>Partlist</name>
<parentField>PARENTID</parentField>
<parentField>DEST_ID</parentField>
<favoriteActionGroup1>alter</favoriteActionGroup1>
<titleField>PRODUCTCODE</titleField>
<descriptionField>QUANTITY</descriptionField>
......
<?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.1.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.1.0">
<name>Prod2prodTable_view</name>
<majorModelMode>DISTRIBUTED</majorModelMode>
<layout>
<boxLayout>
<name>layout</name>
</boxLayout>
</layout>
<children>
<tableViewTemplate>
<name>data</name>
<entityField>#ENTITY</entityField>
<columns>
<neonTableColumn>
<name>1a1880db-4a23-4c0f-9a87-7da546461cca</name>
<entityField>PARENTID</entityField>
</neonTableColumn>
<neonTableColumn>
<name>40710edc-b8ef-43fa-8f8c-99add3946c47</name>
<entityField>SOURCE_ID</entityField>
</neonTableColumn>
<neonTableColumn>
<name>673daab5-c779-49db-aaf4-851f2d0a2c95</name>
<entityField>QUANTITY</entityField>
</neonTableColumn>
<neonTableColumn>
<name>0c99aadc-0798-45eb-b015-8cdef16bf0f1</name>
<entityField>OPTIONAL</entityField>
</neonTableColumn>
<neonTableColumn>
<name>da0abba6-9ea0-4503-9b51-8d232f345aa8</name>
<entityField>TAKEPRICE</entityField>
</neonTableColumn>
</columns>
</tableViewTemplate>
</children>
</neonView>
......@@ -29,6 +29,11 @@
<entityField>#ENTITY</entityField>
<view>ProductDescription_view</view>
</neonViewReference>
<neonViewReference>
<name>cbcf23d7-1d80-41c5-8041-8e768fa91487</name>
<entityField>ProductLinks</entityField>
<view>Prod2prodTable_view</view>
</neonViewReference>
<neonViewReference>
<name>7f416115-ff89-45ca-be10-ed568cac266c</name>
<entityField>ProductLinks</entityField>
......
......@@ -272,10 +272,9 @@ ItemUtils.prototype.insertPartsList = function(columns, productId, assignedTo, c
columns = columns.concat(additionalProductInfo.map(function(item) {return item[0]}));
var colTypes = db.getColumnTypes(table, columns);
// partsList[rootProdId] = root node
if (partsList[rootProdId] != undefined) // if product has a parts list
if (partsList.root != undefined) // if product has a parts list
{
__itemInsertStatement(partsList[rootProdId], assignedTo, currency, contactId);
__itemInsertStatement(partsList.root, assignedTo, currency, contactId);
}
if (statements.length > 0)
......
......@@ -393,14 +393,15 @@ ProductUtils.removeImage = function(pProductId)
* @class
*
*/
function Prod2ProdUtils(productId) {
function Prod2ProdUtils(productId)
{
this.productId = productId;
this.data = undefined;
}
/**
* Delivers an Object containing parts list structure for passed product "productId" (Constructor parameter)
*
* Delivers an Object containing parts list structure for passed product "pProductId" (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>
......@@ -409,10 +410,13 @@ function Prod2ProdUtils(productId) {
* , quantity: "Quantity" <br>
* , optional: "0" = not optional, "1" = optional <br>
* , takeprice: "0" = no price, "1" = price <br>
* , productcode: "Productcode" <br>
* , productid: "Productid" <br>
* } }
*/
Prod2ProdUtils.prototype.getPartsListObject = function() {
return this._relateChilds().getTreeObject();
Prod2ProdUtils.prototype.getPartsListObject = function()
{
return this._relateChilds();
}
/**
......@@ -434,9 +438,27 @@ Prod2ProdUtils.prototype.getPartsListObject = function() {
* , "PRODUCTCODE"
* , "PRODUCTID"] ]
*/
Prod2ProdUtils.prototype.getPartsListForRecordContainer = function() {
var tree = this._relateChilds();
return tree.toArray(7);
Prod2ProdUtils.prototype.getPartsListForRecordContainer = function()
{
var ret = [];
var childs = this._relateChilds();
__push(childs.root);
function __push(pObj)
{
for(var i = 0; i < pObj.ids.length; i++)
{
var rowdata = childs[pObj.ids[i]].rowdata;
var UID = util.getNewUUID();
var PARENTID = childs[pObj.ids[i]].destid;
rowdata = [UID, PARENTID].concat(rowdata);
ret.push(rowdata);
__push( childs[pObj.ids[i]] );
}
}
return ret;
}
/**
......@@ -446,18 +468,21 @@ Prod2ProdUtils.prototype.getPartsListForRecordContainer = function() {
*
* @return {String[]} [ "SOURCE_ID" ]
*/
Prod2ProdUtils.prototype.getPartsListProdIds = function() {
Prod2ProdUtils.prototype.getPartsListProdIds = function()
{
var ret = [];
var childs = this._relateChilds().getTreeObject();
var childs = this._relateChilds();
__push(childs.root);
return ret;
function __push(pObj) {
for (var i = 0; i < pObj.ids.length; i++) {
function __push(pObj)
{
for(var i = 0; i < pObj.ids.length; i++)
{
ret.push(childs[pObj.ids[i]].sourceid);
__push(childs[pObj.ids[i]]);
__push( childs[pObj.ids[i]] );
}
}
}
......@@ -469,7 +494,8 @@ Prod2ProdUtils.prototype.getPartsListProdIds = function() {
*
* @return {String[]} [ "DEST_ID" ]
*/
Prod2ProdUtils.prototype.getParentProdIds = function() {
Prod2ProdUtils.prototype.getParentProdIds = function()
{
var ret = [];
var parents = this._relateParents();
......@@ -477,10 +503,12 @@ Prod2ProdUtils.prototype.getParentProdIds = function() {
return ret;
function __push(pObj) {
for (var i = 0; i < pObj.ids.length; i++) {
function __push(pObj)
{
for(var i = 0; i < pObj.ids.length; i++)
{
ret.push(parents[pObj.ids[i]].destid);
__push(parents[pObj.ids[i]]);
__push( parents[pObj.ids[i]] );
}
}
}
......@@ -491,9 +519,10 @@ Prod2ProdUtils.prototype.getParentProdIds = function() {
*
* @ignore
*/
Prod2ProdUtils.prototype._initProd2ProdData = function() {
Prod2ProdUtils.prototype._initProd2ProdData = function()
{
if (this.data == undefined) {
this.data = db.table("select SOURCE_ID, DEST_ID, PROD2PRODID, QUANTITY, OPTIONAL, TAKEPRICE, PRODUCTCODE, PRODUCTID, SOURCE_ID, DEST_ID "
this.data = db.table("select PROD2PRODID, DEST_ID, SOURCE_ID, QUANTITY, OPTIONAL, TAKEPRICE, PRODUCTCODE, PRODUCTID "
+ "from PROD2PROD join PRODUCT on PROD2PROD.SOURCE_ID = PRODUCTID "
+ "order by PRODUCTCODE ");
}
......@@ -502,78 +531,77 @@ Prod2ProdUtils.prototype._initProd2ProdData = function() {
/**
* object tree to relate products by DEST_ID / SOURCE_ID.
**/
Prod2ProdUtils.prototype._buildTree = function(supervised) {
Prod2ProdUtils.prototype._buildTree = function(pSupervised)
{
this._initProd2ProdData();
var productId = this.productId;
var tree = { root: {ids: [], sourceid: this.productId } };
var tree = DataTree.begin(this.productId).addArray(this.data,
function(pUid, pNode)
if(pSupervised)
tree = { root: {ids: [], destid: this.productId } };
for (var i = 0; i < this.data.length; i++)
{
if (pUid == productId)
var prod2prodid = this.data[i][0];
if ( tree[prod2prodid] == undefined )
{
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];
pNode["productid"] = pNode.data[5];
}
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]
, productid: this.data[i][7]
};
}
}
);
return tree;
return tree;
}
Prod2ProdUtils.prototype._relateChilds = function() {
Prod2ProdUtils.prototype._relateChilds = function()
{
var tree = this._buildTree(false);
__relate(this.productId);
__relate("root");
return tree;
function __relate(id) {
var treeObject = tree.getTreeObject();
if (treeObject[id] != undefined)
function __relate(pID)
{
for ( var id in tree )
{
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);
}
}
if ( tree[id].destid == tree[pID].sourceid && tree[pID].ids.indexOf(id) == -1 )
{
tree[pID].ids.push(id);
__relate(id);
}
}
}
}
Prod2ProdUtils.prototype._relateParents = function() {
Prod2ProdUtils.prototype._relateParents = function()
{
var tree = this._buildTree(true);
__relate(this.productId);
__relate("root");
return tree;
function __relate(id) {
var treeObject = tree.getTreeObject();
if (treeObject[id] != undefined)
function __relate(pID)
{
for ( var id in tree )
{
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);
}
}
if ( tree[id].sourceid == tree[pID].destid && tree[pID].ids.indexOf(id) == -1 )
{
tree[pID].ids.push(id);
__relate(id);
}
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment