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

157 lines
5.0 KiB
JavaScript

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,
},
{
arg: 'filter',
type: 'Object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
http: {source: 'query'}
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/getLeaves`,
verb: 'GET'
}
});
Self.getLeaves = async(zoneFk, parentFk, filter) => {
let conn = Self.dataSource.connector;
let stmts = [];
stmts.push(`DROP TEMPORARY TABLE IF EXISTS tmp.checkedChilds`);
stmts.push(new ParameterizedSQL(
`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`));
if (!parentFk) {
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]));
}
let stmt = new ParameterizedSQL(
`SELECT * FROM (
SELECT
zg.id,
zg.name,
zg.lft,
zg.rgt,
zg.depth,
zg.sons,
IF(ch.id = zg.id, isIncluded, null) selected
FROM zoneGeo zg
JOIN tmp.checkedChilds ch
ON zg.lft <= ch.lft AND zg.rgt >= ch.rgt
UNION ALL
SELECT
child.id,
child.name,
child.lft,
child.rgt,
child.depth,
child.sons,
zi.isIncluded AS selected
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 zi.zoneFk = ?
WHERE parent.id = ?) AS nst`, [zoneFk, parentFk]);
// Get nodes from depth greather than Origin
stmt.merge(conn.makeSuffix(filter));
stmt.merge('GROUP BY nst.id');
const resultIndex = stmts.push(stmt) - 1;
const sql = ParameterizedSQL.join(stmts, ';');
const result = await Self.rawStmt(sql);
const nodes = result[resultIndex];
if (nodes.length == 0)
return nodes;
// Get parent nodes
const minorDepth = nodes.reduce((a, b) => {
return b < a ? b : a;
}).depth;
const parentNodes = nodes.filter(element => {
return element.depth === minorDepth;
});
const leaves = Object.assign([], sortNodes(parentNodes));
nestLeaves(leaves);
function nestLeaves(elements) {
elements.forEach(element => {
let childs = Object.assign([], getLeaves(element));
if (childs.length > 0) {
element.childs = childs;
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 sortNodes(elements);
}
return leaves;
};
function sortNodes(nodes) {
return nodes.sort((a, b) => {
if (b.selected !== a.selected) {
if (a.selected == null)
return 1;
if (b.selected == null)
return -1;
return b.selected - a.selected;
}
return a.name.localeCompare(b.name);
});
}
};