From 65e32f5e7fc1b0c3b1ff0d9a7fa5564d12f0e84b Mon Sep 17 00:00:00 2001 From: vicent Date: Wed, 26 Oct 2022 12:40:13 +0200 Subject: [PATCH] feat: client search panel add find by zone --- .../10500-november/00-zone_getPostalCode.sql | 56 ++++++ modules/client/back/methods/client/filter.js | 174 ++++++++++++++++++ modules/client/back/models/client-methods.js | 1 + modules/client/front/main/index.html | 5 +- modules/client/front/main/index.js | 26 --- modules/client/front/search-panel/index.html | 7 + 6 files changed, 240 insertions(+), 29 deletions(-) create mode 100644 db/changes/10500-november/00-zone_getPostalCode.sql create mode 100644 modules/client/back/methods/client/filter.js diff --git a/db/changes/10500-november/00-zone_getPostalCode.sql b/db/changes/10500-november/00-zone_getPostalCode.sql new file mode 100644 index 000000000..b71306a58 --- /dev/null +++ b/db/changes/10500-november/00-zone_getPostalCode.sql @@ -0,0 +1,56 @@ +DROP PROCEDURE IF EXISTS `vn`.`zone_getPostalCode`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`zone_getPostalCode`(vSelf INT) +BEGIN +/** + * Devuelve los códigos postales incluidos en una zona + * + * @return vNewTicket + */ + DECLARE vGeoFk INT DEFAULT NULL; + + DROP TEMPORARY TABLE IF EXISTS tmp.zoneNodes; + CREATE TEMPORARY TABLE tmp.zoneNodes ( + geoFk INT, + name VARCHAR(100), + parentFk INT, + sons INT, + isChecked BOOL DEFAULT 0, + zoneFk INT, + PRIMARY KEY zoneNodesPk (zoneFk, geoFk), + INDEX(geoFk)) + ENGINE = MEMORY; + + CALL zone_getLeaves2(vSelf, NULL , NULL); + + UPDATE tmp.zoneNodes zn + SET isChecked = 0 + WHERE parentFk IS NULL; + + myLoop: LOOP + SET vGeoFk = NULL; + SELECT geoFk INTO vGeoFk + FROM tmp.zoneNodes zn + WHERE NOT isChecked + LIMIT 1; + + CALL zone_getLeaves2(vSelf, vGeoFk, NULL); + UPDATE tmp.zoneNodes + SET isChecked = TRUE + WHERE geoFk = vGeoFk; + + IF vGeoFk IS NULL THEN + LEAVE myLoop; + END IF; + END LOOP; + + DELETE FROM tmp.zoneNodes + WHERE sons > 0; + + SELECT zn.geoFk, zn.name + FROM tmp.zoneNodes zn + JOIN zone z ON z.id = zn.zoneFk; +END$$ +DELIMITER ; diff --git a/modules/client/back/methods/client/filter.js b/modules/client/back/methods/client/filter.js new file mode 100644 index 000000000..0e9eaf160 --- /dev/null +++ b/modules/client/back/methods/client/filter.js @@ -0,0 +1,174 @@ + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const buildFilter = require('vn-loopback/util/filter').buildFilter; +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; + +module.exports = Self => { + Self.remoteMethodCtx('filter', { + description: 'Find all clients matched by the filter', + accessType: 'READ', + accepts: [ + { + arg: 'filter', + type: 'object', + }, + { + arg: 'search', + type: 'string', + description: `If it's and integer searchs by id, otherwise it searchs by name`, + }, + { + arg: 'name', + type: 'string', + description: 'The client name', + }, + { + arg: 'salesPersonFk', + type: 'number', + }, + { + arg: 'fi', + type: 'string', + description: 'The client fiscal id', + }, + { + arg: 'socialName', + type: 'string', + }, + { + arg: 'city', + type: 'string', + }, + { + arg: 'postcode', + type: 'string', + }, + { + arg: 'provinceFk', + type: 'number', + }, + { + arg: 'email', + type: 'string', + }, + { + arg: 'phone', + type: 'string', + }, + { + arg: 'zoneFk', + type: 'number', + }, + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/filter`, + verb: 'GET' + } + }); + + Self.filter = async(ctx, filter, options) => { + const conn = Self.dataSource.connector; + const myOptions = {}; + const postalCode = []; + const args = ctx.args; + if (typeof options == 'object') + Object.assign(myOptions, options); + if (args.zoneFk) { + query = `CALL vn.zone_getPostalCode(?)`; + const [geos] = await Self.rawSql(query, [args.zoneFk]); + for (let geo of geos) + postalCode.push(geo.name); + } + + const where = buildFilter(ctx.args, (param, value) => { + switch (param) { + case 'search': + return /^\d+$/.test(value) + ? {'c.id': {inq: value}} + : {'c.name': {like: `%${value}%`}}; + case 'name': + case 'salesPersonFk': + case 'fi': + case 'socialName': + case 'city': + case 'postcode': + case 'provinceFk': + case 'email': + case 'phone': + param = `c.${param}`; + return {[param]: value}; + case 'zoneFk': + param = 'a.postalCode'; + return {[param]: {inq: postalCode}}; + } + }); + + filter = mergeFilters(filter, {where}); + + const stmts = []; + const stmt = new ParameterizedSQL( + `SELECT + c.id, + c.name, + c.socialName, + c.fi, + c.credit, + c.creditInsurance, + c.phone, + c.mobile, + c.street, + c.city, + c.postcode, + c.email, + c.created, + c.isActive, + c.isVies, + c.isTaxDataChecked, + c.isEqualizated, + c.isFreezed, + c.hasToInvoice, + c.hasToInvoiceByAddress, + c.isToBeMailed, + c.hasSepaVnl, + c.hasLcr, + c.hasCoreVnl, + ct.id AS countryFk, + ct.country, + p.id AS provinceFk, + p.name AS province, + u.id AS salesPersonFk, + u.name AS salesPerson, + bt.code AS businessTypeFk, + bt.description AS businessType, + pm.id AS payMethodFk, + pm.name AS payMethod, + sti.CodigoIva AS sageTaxTypeFk, + sti.Iva AS sageTaxType, + stt.CodigoTransaccion AS sageTransactionTypeFk, + stt.Transaccion AS sageTransactionType + FROM client c + LEFT JOIN account.user u ON u.id = c.salesPersonFk + LEFT JOIN country ct ON ct.id = c.countryFk + LEFT JOIN province p ON p.id = c.provinceFk + LEFT JOIN businessType bt ON bt.code = c.businessTypeFk + LEFT JOIN payMethod pm ON pm.id = c.payMethodFk + LEFT JOIN sage.TiposIva sti ON sti.CodigoIva = c.taxTypeSageFk + LEFT JOIN sage.TiposTransacciones stt ON stt.CodigoTransaccion = c.transactionTypeSageFk + LEFT JOIN vn.address a ON a.id = c.defaultAddressFk + ` + ); + + stmt.merge(conn.makeWhere(filter.where)); + stmt.merge(conn.makePagination(filter)); + + const clientsIndex = stmts.push(stmt) - 1; + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql, myOptions); + + return clientsIndex === 0 ? result : result[clientsIndex]; + }; +}; diff --git a/modules/client/back/models/client-methods.js b/modules/client/back/models/client-methods.js index 04d10413a..5134e3942 100644 --- a/modules/client/back/models/client-methods.js +++ b/modules/client/back/models/client-methods.js @@ -47,4 +47,5 @@ module.exports = Self => { require('../methods/client/incotermsAuthorizationHtml')(Self); require('../methods/client/incotermsAuthorizationEmail')(Self); require('../methods/client/consumptionSendQueued')(Self); + require('../methods/client/filter')(Self); }; diff --git a/modules/client/front/main/index.html b/modules/client/front/main/index.html index e8bc4b988..0787858ae 100644 --- a/modules/client/front/main/index.html +++ b/modules/client/front/main/index.html @@ -1,6 +1,6 @@ @@ -10,8 +10,7 @@ vn-focus panel="vn-client-search-panel" info="Search client by id or name" - model="model" - expr-builder="$ctrl.exprBuilder(param, value)"> + model="model"> diff --git a/modules/client/front/main/index.js b/modules/client/front/main/index.js index 1069d3487..346880f4c 100644 --- a/modules/client/front/main/index.js +++ b/modules/client/front/main/index.js @@ -2,32 +2,6 @@ import ngModule from '../module'; import ModuleMain from 'salix/components/module-main'; export default class Client extends ModuleMain { - exprBuilder(param, value) { - switch (param) { - case 'search': - return /^\d+$/.test(value) - ? {id: value} - : {or: [{name: {like: `%${value}%`}}, {socialName: {like: `%${value}%`}}]}; - case 'phone': - return { - or: [ - {phone: value}, - {mobile: value} - ] - }; - case 'name': - case 'socialName': - case 'city': - case 'email': - return {[param]: {like: `%${value}%`}}; - case 'id': - case 'fi': - case 'postcode': - case 'provinceFk': - case 'salesPersonFk': - return {[param]: value}; - } - } } ngModule.vnComponent('vnClient', { diff --git a/modules/client/front/search-panel/index.html b/modules/client/front/search-panel/index.html index 234cb6f53..a02f93882 100644 --- a/modules/client/front/search-panel/index.html +++ b/modules/client/front/search-panel/index.html @@ -58,6 +58,13 @@ value-field="id" label="Province"> + +