salix/modules/agency/back/methods/zone-geo/getLeaves.js

157 lines
5.0 KiB
JavaScript
Raw Normal View History

2019-01-21 10:45:53 +00:00
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethod('getLeaves', {
description: 'Returns the first shipped and landed possible for params',
accepts: [{
arg: 'zoneFk',
type: 'Number',
required: true,
},
{
arg: 'parentFk',
type: 'Number',
default: 1,
required: false,
2019-02-18 07:37:26 +00:00
},
{
arg: 'filter',
type: 'Object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
http: {source: 'query'}
2019-01-21 10:45:53 +00:00
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/getLeaves`,
verb: 'GET'
}
});
2019-09-13 10:16:38 +00:00
Self.getLeaves = async(zoneFk, parentFk, filter) => {
2019-01-21 10:45:53 +00:00
let conn = Self.dataSource.connector;
let stmts = [];
2019-02-18 07:37:26 +00:00
stmts.push(`DROP TEMPORARY TABLE IF EXISTS tmp.checkedChilds`);
2019-01-21 10:45:53 +00:00
stmts.push(new ParameterizedSQL(
2019-02-18 07:37:26 +00:00
`CREATE TEMPORARY TABLE tmp.checkedChilds (
id INT,
name VARCHAR(100),
lft INT,
rgt INT,
depth BIGINT(22),
sons DECIMAL(10, 0),
isIncluded TINYINT
) ENGINE = MEMORY`));
2019-01-21 10:45:53 +00:00
2019-09-13 10:16:38 +00:00
if (!parentFk) {
2019-02-18 07:37:26 +00:00
stmts.push(new ParameterizedSQL(
`INSERT INTO tmp.checkedChilds
SELECT
zg.id,
zg.name,
zg.lft,
zg.rgt,
zg.depth,
zg.sons,
zi.isIncluded
FROM zoneGeo zg
JOIN zoneIncluded zi ON zi.geoFk = zg.id
AND zoneFk = ?`, [zoneFk]));
}
2019-01-21 10:45:53 +00:00
let stmt = new ParameterizedSQL(
2019-02-18 07:37:26 +00:00
`SELECT * FROM (
SELECT
zg.id,
zg.name,
zg.lft,
zg.rgt,
zg.depth,
zg.sons,
2019-03-12 14:04:09 +00:00
IF(ch.id = zg.id, isIncluded, null) selected
2019-02-18 07:37:26 +00:00
FROM zoneGeo zg
2019-02-18 12:23:24 +00:00
JOIN tmp.checkedChilds ch
ON zg.lft <= ch.lft AND zg.rgt >= ch.rgt
2019-02-18 07:37:26 +00:00
UNION ALL
SELECT
child.id,
child.name,
child.lft,
child.rgt,
child.depth,
child.sons,
2019-03-12 14:04:09 +00:00
zi.isIncluded AS selected
2019-02-18 07:37:26 +00:00
FROM zoneGeo parent
JOIN zoneGeo child ON child.lft > parent.lft
AND child.rgt < parent.rgt
AND child.depth = parent.depth + 1
LEFT JOIN zoneIncluded zi ON zi.geoFk = child.id
2019-04-02 11:00:02 +00:00
AND zi.zoneFk = ?
2019-02-18 07:37:26 +00:00
WHERE parent.id = ?) AS nst`, [zoneFk, parentFk]);
2019-01-21 10:45:53 +00:00
2019-02-18 07:37:26 +00:00
// Get nodes from depth greather than Origin
stmt.merge(conn.makeSuffix(filter));
stmt.merge('GROUP BY nst.id');
2019-01-21 10:45:53 +00:00
2019-02-18 07:37:26 +00:00
const resultIndex = stmts.push(stmt) - 1;
2019-01-21 10:45:53 +00:00
const sql = ParameterizedSQL.join(stmts, ';');
const result = await Self.rawStmt(sql);
2019-02-18 07:37:26 +00:00
const nodes = result[resultIndex];
2019-02-18 12:23:24 +00:00
if (nodes.length == 0)
return nodes;
2019-02-18 07:37:26 +00:00
// Get parent nodes
2019-02-18 12:23:24 +00:00
const minorDepth = nodes.reduce((a, b) => {
return b < a ? b : a;
}).depth;
2019-02-18 07:37:26 +00:00
const parentNodes = nodes.filter(element => {
2019-02-18 12:23:24 +00:00
return element.depth === minorDepth;
2019-02-18 07:37:26 +00:00
});
2019-02-20 11:31:08 +00:00
const leaves = Object.assign([], sortNodes(parentNodes));
2019-02-18 07:37:26 +00:00
nestLeaves(leaves);
function nestLeaves(elements) {
elements.forEach(element => {
2019-03-12 14:04:09 +00:00
let childs = Object.assign([], getLeaves(element));
if (childs.length > 0) {
element.childs = childs;
nestLeaves(element.childs);
}
2019-02-18 07:37:26 +00:00
});
}
function getLeaves(parent) {
let elements = nodes.filter(element => {
return element.lft > parent.lft && element.rgt < parent.rgt
&& element.depth === parent.depth + 1;
});
2019-02-20 11:31:08 +00:00
return sortNodes(elements);
2019-02-18 07:37:26 +00:00
}
2019-01-21 10:45:53 +00:00
2019-02-18 07:37:26 +00:00
return leaves;
2019-01-21 10:45:53 +00:00
};
2019-02-20 11:31:08 +00:00
function sortNodes(nodes) {
return nodes.sort((a, b) => {
2019-03-12 14:04:09 +00:00
if (b.selected !== a.selected) {
if (a.selected == null)
2019-02-20 11:31:08 +00:00
return 1;
2019-03-12 14:04:09 +00:00
if (b.selected == null)
2019-02-20 11:31:08 +00:00
return -1;
2019-03-12 14:04:09 +00:00
return b.selected - a.selected;
2019-02-20 11:31:08 +00:00
}
return a.name.localeCompare(b.name);
});
}
2019-01-21 10:45:53 +00:00
};