diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e75b6986..74109c7c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ -# Version 24.36 - 2024-08-27 +# Version 24.36 - 2024-09-03 ### Added 🆕 - chore: refs #7524 WIP limit call by:jorgep +- chore: refs #7524 modify ormConfig table col (origin/7524-warmfix-modifyColumn) by:jorgep - feat(update-user): refs #7848 add twoFactor by:alexm - feat: #3199 Requested changes by:guillermo - feat: refs #3199 Added more scopes ticket_recalcByScope by:guillermo @@ -16,6 +17,7 @@ - feat: refs #7524 add default limit (origin/7524-limitSelect) by:jorgep - feat: refs #7524 add mock limit on find query by:jorgep - feat: refs #7524 wip remote hooks by:jorgep +- feat: refs #7562 Requested changes by:guillermo - feat: refs #7567 Changed time to call event by:guillermo - feat: refs #7567 Requested changes by:guillermo - feat: refs #7710 pr revision by:jgallego @@ -31,6 +33,7 @@ - feat: refs #7799 Added Fk in vn.item.itemPackingTypeFk by:guillermo - feat: refs #7800 Added company Fk by:guillermo - feat: refs #7842 Added editorFk in vn.host by:guillermo +- feat: refs #7860 Update new packagings (origin/7860-newPackaging) by:guillermo - feat: refs #7862 roadmap new fields by:ivanm - feat: refs #7882 Added quadMindsConfig table by:guillermo @@ -55,6 +58,8 @@ - fix: refs #7756 id 0 by:guillermo - fix: refs #7800 tpvMerchantEnable PRIMARY KEY (origin/7800-tpvMerchantEnable) by:guillermo - fix: refs #7800 tpvMerchantEnable PRIMARY KEY by:guillermo +- fix: refs #7916 itemShelving_transfer (origin/test, test) by:guillermo +- fix: refs #pako Deleted duplicated version by:guillermo # Version 24.34 - 2024-08-20 diff --git a/db/routines/vn/procedures/sale_getProblems.sql b/db/routines/vn/procedures/sale_getProblems.sql index 6f65a3722..8df28dbc0 100644 --- a/db/routines/vn/procedures/sale_getProblems.sql +++ b/db/routines/vn/procedures/sale_getProblems.sql @@ -35,6 +35,7 @@ BEGIN saleFk INT(11), isFreezed INTEGER(1) DEFAULT 0, risk DECIMAL(10,1) DEFAULT 0, + hasRisk TINYINT(1) DEFAULT 0, hasHighRisk TINYINT(1) DEFAULT 0, hasTicketRequest INTEGER(1) DEFAULT 0, itemShortage VARCHAR(255), @@ -52,6 +53,7 @@ BEGIN saleFk, isFreezed, risk, + hasRisk, hasHighRisk, hasTicketRequest, isTaxDataChecked, @@ -62,6 +64,7 @@ BEGIN s.id, IF(FIND_IN_SET('isFreezed', t.problem), TRUE, FALSE) isFreezed, t.risk, + IF(FIND_IN_SET('hasRisk', t.problem), TRUE, FALSE) hasRisk, IF(FIND_IN_SET('hasHighRisk', t.problem), TRUE, FALSE) hasHighRisk, IF(FIND_IN_SET('hasTicketRequest', t.problem), TRUE, FALSE) hasTicketRequest, IF(FIND_IN_SET('isTaxDataChecked', t.problem), FALSE, TRUE) isTaxDataChecked, @@ -70,11 +73,15 @@ BEGIN LEFT(GROUP_CONCAT('RE: ', i.id, ' ', IFNULL(i.longName,'') SEPARATOR ', '), 250), NULL ) hasRounding, - IF(FIND_IN_SET('isTooLittle', t.problem), TRUE, FALSE) isTooLittle + IF(FIND_IN_SET('isTooLittle', t.problem) + AND util.VN_NOW() < (util.VN_CURDATE() + INTERVAL HOUR(zc.`hour`) HOUR) + INTERVAL MINUTE(zc.`hour`) MINUTE, + TRUE, FALSE) isTooLittle FROM tmp.sale_getProblems sgp JOIN ticket t ON t.id = sgp.ticketFk LEFT JOIN sale s ON s.ticketFk = t.id LEFT JOIN item i ON i.id = s.itemFk + LEFT JOIN zoneClosure zc ON zc.zoneFk = t.zoneFk + AND zc.dated = util.VN_CURDATE() WHERE s.problem <> '' OR t.problem <> '' OR t.risk GROUP BY t.id, s.id; diff --git a/db/routines/vn/procedures/sale_setProblemRoundingByBuy.sql b/db/routines/vn/procedures/sale_setProblemRoundingByBuy.sql new file mode 100644 index 000000000..b0e286d25 --- /dev/null +++ b/db/routines/vn/procedures/sale_setProblemRoundingByBuy.sql @@ -0,0 +1,75 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`sale_setProblemRoundingByBuy`( + vBuyFk INT +) +BEGIN +/** + * Update rounding problem for all sales related to a buy. + * + * @param vBuyFk Buy id + */ + DECLARE vItemFk INT; + DECLARE vWarehouseFk INT; + DECLARE vMaxDated DATE; + DECLARE vMinDated DATE; + DECLARE vLanding DATE; + DECLARE vLastBuy INT; + DECLARE vCurrentBuy INT; + DECLARE vGrouping INT; + + SELECT b.itemFk, t.warehouseInFk + INTO vItemFk, vWarehouseFk + FROM buy b + JOIN entry e ON e.id = b.entryFk + JOIN travel t ON t.id = e.travelFk + WHERE b.id = vBuyFk; + + IF vItemFk AND vWarehouseFk THEN + SELECT DATE(MAX(t.shipped)) + INTERVAL 1 DAY, DATE(MIN(t.shipped)) + INTO vMaxDated, vMinDated + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + WHERE t.shipped >= util.VN_CURDATE() + AND s.itemFk = vItemFk + AND s.quantity > 0; + + CALL buy_getUltimate(vItemFk, vWarehouseFk, vMinDated); + + SELECT bu.buyFk, b.grouping INTO vLastBuy, vGrouping + FROM tmp.buyUltimate bu + JOIN buy b ON b.id = bu.buyFk; + + DROP TEMPORARY TABLE tmp.buyUltimate; + + SET vLanding = vMaxDated; + + WHILE vCurrentBuy <> vLastBuy OR vLanding > vMinDated DO + SET vMaxDated = vLanding - INTERVAL 1 DAY; + + CALL buy_getUltimate(vItemFk, vWarehouseFk, vMaxDated); + + SELECT buyFk, landing + INTO vCurrentBuy, vLanding + FROM tmp.buyUltimate; + + DROP TEMPORARY TABLE tmp.buyUltimate; + END WHILE; + + CREATE OR REPLACE TEMPORARY TABLE tmp.sale + (INDEX(saleFk, isProblemCalcNeeded)) + ENGINE = MEMORY + SELECT s.id saleFk, + MOD(s.quantity, vGrouping) hasProblem, + ticket_isProblemCalcNeeded(t.id) isProblemCalcNeeded + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + WHERE s.itemFk = vItemFk + AND s.quantity > 0 + AND t.shipped BETWEEN vMinDated AND util.dayEnd(vMaxDated); + + CALL sale_setProblem('hasRounding'); + + DROP TEMPORARY TABLE tmp.sale; + END IF; +END$$ +DELIMITER ; \ No newline at end of file diff --git a/db/routines/vn/procedures/ticket_getProblems.sql b/db/routines/vn/procedures/ticket_getProblems.sql index e9becab2a..f83351456 100644 --- a/db/routines/vn/procedures/ticket_getProblems.sql +++ b/db/routines/vn/procedures/ticket_getProblems.sql @@ -18,6 +18,7 @@ BEGIN SELECT ticketFk, MAX(isFreezed) isFreezed, MAX(risk) risk, + MAX(hasRisk) hasRisk, MAX(hasHighRisk) hasHighRisk, MAX(hasTicketRequest) hasTicketRequest, MAX(itemShortage) itemShortage, @@ -32,19 +33,19 @@ BEGIN FROM tmp.sale_problems GROUP BY ticketFk; - UPDATE tmp.ticket_problems tp - SET tp.totalProblems = ( - (tp.isFreezed) + - IF(tp.risk,TRUE, FALSE) + - (tp.hasTicketRequest) + - (tp.isTaxDataChecked = 0) + - (tp.hasComponentLack) + - (tp.itemDelay) + - (tp.isTooLittle) + - (tp.itemLost) + - (tp.hasRounding) + - (tp.itemShortage) + - (tp.isVip) + UPDATE tmp.ticket_problems + SET totalProblems = ( + (isFreezed) + + (hasRisk) + + (hasTicketRequest) + + (!isTaxDataChecked) + + (hasComponentLack) + + (itemDelay IS NOT NULL) + + (isTooLittle) + + (itemLost IS NOT NULL) + + (hasRounding IS NOT NULL) + + (itemShortage IS NOT NULL) + + (isVip) ); DROP TEMPORARY TABLE tmp.sale_problems; diff --git a/loopback/common/models/vn-model.js b/loopback/common/models/vn-model.js index a11bed11d..6fcb6f0e3 100644 --- a/loopback/common/models/vn-model.js +++ b/loopback/common/models/vn-model.js @@ -27,25 +27,25 @@ module.exports = function(Self) { }; }); - this.beforeRemote('**', async ctx => { - if (!this.hasFilter(ctx)) return; + // this.beforeRemote('**', async ctx => { + // if (!this.hasFilter(ctx)) return; - const defaultLimit = this.app.orm.selectLimit; - const filter = ctx.args.filter || {limit: defaultLimit}; + // const defaultLimit = this.app.orm.selectLimit; + // const filter = ctx.args.filter || {limit: defaultLimit}; - if (filter.limit > defaultLimit) { - filter.limit = defaultLimit; - ctx.args.filter = filter; - } - }); + // if (filter.limit > defaultLimit) { + // filter.limit = defaultLimit; + // ctx.args.filter = filter; + // } + // }); - this.afterRemote('**', async ctx => { - if (!this.hasFilter(ctx)) return; + // this.afterRemote('**', async ctx => { + // if (!this.hasFilter(ctx)) return; - const {result} = ctx; - const length = Array.isArray(result) ? result.length : result ? 1 : 0; - if (length >= this.app.orm.selectLimit) throw new UserError('Too many records'); - }); + // const {result} = ctx; + // const length = Array.isArray(result) ? result.length : result ? 1 : 0; + // if (length >= this.app.orm.selectLimit) throw new UserError('Too many records'); + // }); // Register field ACL validation /* diff --git a/loopback/server/boot/orm.js b/loopback/server/boot/orm.js index 8bbd969e1..ccd9d4eca 100644 --- a/loopback/server/boot/orm.js +++ b/loopback/server/boot/orm.js @@ -1,6 +1,6 @@ -module.exports = async function(app) { - if (!app.orm) { - const ormConfig = await app.models.OrmConfig.findOne(); - app.orm = ormConfig; - } -}; +// module.exports = async function(app) { +// if (!app.orm) { +// const ormConfig = await app.models.OrmConfig.findOne(); +// app.orm = ormConfig; +// } +// }; diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js index 33b37d8a4..8ef51a0d1 100644 --- a/modules/monitor/back/methods/sales-monitor/salesFilter.js +++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js @@ -238,51 +238,8 @@ module.exports = Self => { stmts.push(`SET SESSION optimizer_search_depth = @_optimizer_search_depth`); - // Get client debt balance - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt'); - stmts.push(` - CREATE TEMPORARY TABLE tmp.clientGetDebt - (PRIMARY KEY (clientFk)) - ENGINE = MEMORY - SELECT DISTINCT clientFk FROM tmp.filter`); - - stmt = new ParameterizedSQL('CALL client_getDebt(?)', [args.to]); - stmts.push(stmt); - stmts.push('DROP TEMPORARY TABLE tmp.clientGetDebt'); - - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.tickets'); stmt = new ParameterizedSQL(` - CREATE TEMPORARY TABLE tmp.tickets - (PRIMARY KEY (id)) - ENGINE = MEMORY - SELECT f.*, r.risk AS debt - FROM tmp.filter f - LEFT JOIN tmp.risk r ON f.clientFk = r.clientFk`); - stmts.push(stmt); - - // Sum risk to future - stmts.push(`SET @client:= 0`); - stmts.push('SET @risk := 0'); - stmts.push(` - UPDATE tmp.tickets - SET debt = IF(@client <> @client:= clientFk, - -totalWithVat + @risk:= - debt + totalWithVat, - -totalWithVat + @risk:= @risk + totalWithVat - ) - ORDER BY clientFk, shipped DESC - `); - - // Remove positive risks - stmts.push(` - UPDATE tmp.tickets t - SET debt = 0 - WHERE t.debt + t.credit >= 0 - `); - - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.sale_getProblems'); - - stmt = new ParameterizedSQL(` - CREATE TEMPORARY TABLE tmp.sale_getProblems + CREATE OR REPLACE TEMPORARY TABLE tmp.sale_getProblems (INDEX (ticketFk)) ENGINE = MEMORY SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped @@ -294,36 +251,30 @@ module.exports = Self => { stmts.push('CALL ticket_getProblems(FALSE)'); - stmts.push(` - INSERT INTO tmp.ticket_problems (ticketFk, risk, totalProblems) - SELECT t.id, t.debt + t.credit AS risk, 1 - FROM tmp.tickets t - WHERE (t.debt + t.credit) < 0 - ON DUPLICATE KEY UPDATE - risk = t.debt + t.credit, totalProblems = totalProblems + 1 - `); - - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.sale_getWarnings'); - stmt = new ParameterizedSQL(` - CREATE TEMPORARY TABLE tmp.sale_getWarnings - (INDEX (ticketFk, agencyModeFk)) - ENGINE = MEMORY - SELECT f.id ticketFk, f.agencyModeFk - FROM tmp.filter f`); + CREATE OR REPLACE TEMPORARY TABLE tmp.sale_getWarnings + (INDEX (ticketFk, agencyModeFk)) + ENGINE = MEMORY + SELECT f.id ticketFk, f.agencyModeFk + FROM tmp.filter f + `); stmts.push(stmt); stmts.push('CALL ticket_getWarnings()'); stmt = new ParameterizedSQL(` - SELECT t.*, - tp.*, - ((tp.risk) + cc.riskTolerance < 0) AS hasHighRisk, - tw.* - FROM tmp.tickets t - LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = t.id - LEFT JOIN tmp.ticket_warnings tw ON tw.ticketFk = t.id - JOIN clientConfig cc`); + UPDATE tmp.ticket_problems + SET risk = IF(hasRisk, risk, 0) + `); + stmts.push(stmt); + + stmt = new ParameterizedSQL(` + SELECT * + FROM tmp.filter f + LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id + LEFT JOIN tmp.ticket_warnings tw ON tw.ticketFk = f.id + `); + stmts.push(stmt); const hasProblems = args.problems; if (hasProblems != undefined && (!args.from && !args.to)) @@ -359,23 +310,23 @@ module.exports = Self => { switch (param) { case 'search': return /^\d+$/.test(value) - ? {'t.id': {inq: value}} - : {'t.nickname': {like: `%${value}%`}}; + ? {'f.id': {inq: value}} + : {'f.nickname': {like: `%${value}%`}}; case 'nickname': - return {'t.nickname': {like: `%${value}%`}}; + return {'f.nickname': {like: `%${value}%`}}; case 'refFk': - return {'t.refFk': value}; + return {'f.refFk': value}; case 'provinceFk': - return {'t.provinceFk': value}; + return {'f.provinceFk': value}; case 'stateFk': - return {'t.stateFk': value}; + return {'f.stateFk': value}; case 'alertLevel': - return {'t.alertLevel': value}; + return {'f.alertLevel': value}; case 'pending': if (value) { - return {'t.alertLevelCode': {inq: [ + return {'f.alertLevelCode': {inq: [ 'FIXING', 'FREE', 'NOT_READY', @@ -385,7 +336,7 @@ module.exports = Self => { 'WAITING_FOR_PAYMENT' ]}}; } else { - return {'t.alertLevelCode': {inq: [ + return {'f.alertLevelCode': {inq: [ 'ON_PREPARATION', 'ON_CHECKING', 'CHECKED', @@ -409,7 +360,7 @@ module.exports = Self => { } case 'agencyModeFk': case 'warehouseFk': - param = `t.${param}`; + param = `f.${param}`; return {[param]: value}; } }); @@ -422,14 +373,14 @@ module.exports = Self => { stmt.merge(conn.makeLimit(filter)); const ticketsIndex = stmts.push(stmt) - 1; - stmts.push( - `DROP TEMPORARY TABLE + stmts.push(` + DROP TEMPORARY TABLE tmp.filter, tmp.ticket_problems, tmp.sale_getProblems, tmp.sale_getWarnings, - tmp.ticket_warnings, - tmp.risk`); + tmp.ticket_warnings + `); const sql = ParameterizedSQL.join(stmts, ';'); const result = await conn.executeStmt(sql, myOptions); diff --git a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js index c3da7f08b..9460addfa 100644 --- a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js +++ b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js @@ -39,7 +39,7 @@ describe('SalesMonitor salesFilter()', () => { const filter = {}; const result = await models.SalesMonitor.salesFilter(ctx, filter, options); - expect(result.length).toBeGreaterThan(11); + expect(result.length).toBeGreaterThan(10); await tx.rollback(); } catch (e) { @@ -68,7 +68,7 @@ describe('SalesMonitor salesFilter()', () => { const filter = {}; const result = await models.SalesMonitor.salesFilter(ctx, filter, options); - expect(result.length).toEqual(0); + expect(result.length).toEqual(4); await tx.rollback(); } catch (e) { @@ -218,8 +218,8 @@ describe('SalesMonitor salesFilter()', () => { const firstTicket = result.shift(); const secondTicket = result.shift(); - expect(firstTicket.totalProblems).toEqual(1); - expect(secondTicket.totalProblems).toEqual(1); + expect(firstTicket.totalProblems).toEqual(3); + expect(secondTicket.totalProblems).toEqual(3); await tx.rollback(); } catch (e) { diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js index 3e8b732af..2209c8df4 100644 --- a/modules/ticket/back/methods/ticket/filter.js +++ b/modules/ticket/back/methods/ticket/filter.js @@ -306,6 +306,12 @@ module.exports = Self => { stmts.push(stmt); stmts.push('CALL ticket_getProblems(FALSE)'); + stmt = new ParameterizedSQL(` + UPDATE tmp.ticket_problems + SET risk = IF(hasRisk, risk, 0) + `); + stmts.push(stmt); + stmt = new ParameterizedSQL(` SELECT f.*, tp.* FROM tmp.filter f diff --git a/modules/ticket/back/methods/ticket/getTicketsFuture.js b/modules/ticket/back/methods/ticket/getTicketsFuture.js index 0fd21ea74..9f455ec03 100644 --- a/modules/ticket/back/methods/ticket/getTicketsFuture.js +++ b/modules/ticket/back/methods/ticket/getTicketsFuture.js @@ -158,10 +158,16 @@ module.exports = Self => { stmts.push(stmt); stmts.push('CALL ticket_getProblems(FALSE)'); + stmt = new ParameterizedSQL(` + UPDATE tmp.ticket_problems + SET risk = IF(hasRisk, risk, 0) + `); + stmts.push(stmt); + stmt = new ParameterizedSQL(` SELECT f.*, tp.* - FROM tmp.filter f - LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id + FROM tmp.filter f + LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id `); if (args.problems != undefined && (!args.originDated && !args.futureDated)) diff --git a/modules/ticket/back/models/ticket.json b/modules/ticket/back/models/ticket.json index d8a3206c6..3f073806e 100644 --- a/modules/ticket/back/models/ticket.json +++ b/modules/ticket/back/models/ticket.json @@ -69,6 +69,9 @@ }, "cmrFk": { "type": "number" + }, + "problem": { + "type": "string" } }, "relations": { diff --git a/modules/ticket/front/descriptor/index.html b/modules/ticket/front/descriptor/index.html index 75bcd2801..32a30833b 100644 --- a/modules/ticket/front/descriptor/index.html +++ b/modules/ticket/front/descriptor/index.html @@ -58,7 +58,7 @@ + ng-if="$ctrl.ticket.problem.includes('hasRisk')">