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

152 lines
4.7 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',
accessType: '',
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-02-18 07:37:26 +00:00
Self.getLeaves = async(zoneFk, parentFk = 1, 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-02-18 07:37:26 +00:00
if (parentFk === 1) {
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,
IF(ch.id = zg.id, isIncluded, null) isIncluded
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
AND zg.depth > 0
2019-02-18 07:37:26 +00:00
UNION ALL
SELECT
child.id,
child.name,
child.lft,
child.rgt,
child.depth,
child.sons,
zi.isIncluded
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
AND zoneFk = ?
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-18 12:23:24 +00:00
const sortedLeaves = parentNodes.sort((a, b) => {
2019-02-18 12:37:36 +00:00
let priority = (b.isIncluded - a.isIncluded) - 1;
2019-02-18 12:23:24 +00:00
if (b.name > a.name)
priority++;
return priority;
});
2019-02-18 07:37:26 +00:00
const leaves = Object.assign([], sortedLeaves);
nestLeaves(leaves);
function nestLeaves(elements) {
elements.forEach(element => {
element.childs = Object.assign([], getLeaves(element));
nestLeaves(element.childs);
});
}
function getLeaves(parent) {
let elements = nodes.filter(element => {
return element.lft > parent.lft && element.rgt < parent.rgt
&& element.depth === parent.depth + 1;
});
return elements;
}
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
};
};