diff --git a/db/changes/10370-pickles/00-ticket_getProblems.sql b/db/changes/10370-pickles/00-ticket_getProblems.sql
new file mode 100644
index 000000000..2ee057cd2
--- /dev/null
+++ b/db/changes/10370-pickles/00-ticket_getProblems.sql
@@ -0,0 +1,48 @@
+drop procedure `vn`.`ticket_getProblems`;
+
+DELIMITER $$
+$$
+create
+ definer = root@`%` procedure `vn`.`ticket_getProblems`(IN vIsTodayRelative tinyint(1))
+BEGIN
+/**
+ * Calcula los problemas para un conjunto de tickets.
+ * Agrupados por ticket
+ *
+ * @table tmp.sale_getProblems(ticketFk, clientFk, warehouseFk, shipped) Identificadores de los tickets a calcular
+ * @return tmp.ticket_problems
+ */
+ CALL sale_getProblems(vIsTodayRelative);
+
+ DROP TEMPORARY TABLE IF EXISTS tmp.ticket_problems;
+ CREATE TEMPORARY TABLE tmp.ticket_problems
+ (PRIMARY KEY (ticketFk))
+ ENGINE = MEMORY
+ SELECT
+ ticketFk,
+ MAX(p.isFreezed) AS isFreezed,
+ MAX(p.risk) AS risk,
+ MAX(p.hasHighRisk) AS hasHighRisk,
+ MAX(p.hasTicketRequest) AS hasTicketRequest,
+ MIN(p.isAvailable) AS isAvailable,
+ MAX(p.itemShortage) AS itemShortage,
+ MIN(p.isTaxDataChecked) AS isTaxDataChecked,
+ MAX(p.hasComponentLack) AS hasComponentLack,
+ 0 AS totalProblems
+ FROM tmp.sale_problems p
+ GROUP BY ticketFk;
+
+ UPDATE tmp.ticket_problems tp
+ SET tp.totalProblems = (
+ (tp.isFreezed) +
+ IF(tp.risk, TRUE, FALSE) +
+ (tp.hasTicketRequest) +
+ (tp.isAvailable = 0) +
+ (tp.isTaxDataChecked = 0) +
+ (tp.hasComponentLack)
+ );
+
+ DROP TEMPORARY TABLE
+ tmp.sale_problems;
+END;;$$
+DELIMITER ;
\ No newline at end of file
diff --git a/db/changes/10370-pickles/delete.keep b/db/changes/10370-pickles/delete.keep
deleted file mode 100644
index e69de29bb..000000000
diff --git a/front/core/components/pagination/pagination.html b/front/core/components/pagination/pagination.html
index 6809018dd..72d7c31ff 100644
--- a/front/core/components/pagination/pagination.html
+++ b/front/core/components/pagination/pagination.html
@@ -1,9 +1,10 @@
-
-
+
-
+
+
+
diff --git a/front/core/components/pagination/style.scss b/front/core/components/pagination/style.scss
index 413a6fb5f..02dcb43e4 100644
--- a/front/core/components/pagination/style.scss
+++ b/front/core/components/pagination/style.scss
@@ -1,7 +1,13 @@
+@import "variables";
vn-pagination {
display: block;
text-align: center;
+ color: $color-primary;
+
+ vn-button, vn-icon {
+ display: block
+ }
& > div > vn-icon-button {
font-size: 2rem;
diff --git a/modules/monitor/back/methods/sales-monitor/salesFilter.js b/modules/monitor/back/methods/sales-monitor/salesFilter.js
index b598d79b1..5627975d8 100644
--- a/modules/monitor/back/methods/sales-monitor/salesFilter.js
+++ b/modules/monitor/back/methods/sales-monitor/salesFilter.js
@@ -129,54 +129,20 @@ module.exports = Self => {
const where = buildFilter(ctx.args, (param, value) => {
switch (param) {
- case 'search':
- return /^\d+$/.test(value)
- ? {'t.id': {inq: value}}
- : {'t.nickname': {like: `%${value}%`}};
case 'from':
return {'t.shipped': {gte: value}};
case 'to':
return {'t.shipped': {lte: value}};
- case 'nickname':
- return {'t.nickname': {like: `%${value}%`}};
- case 'refFk':
- return {'t.refFk': value};
case 'salesPersonFk':
return {'c.salesPersonFk': value};
- case 'provinceFk':
- return {'a.provinceFk': value};
- case 'stateFk':
- return {'ts.stateFk': value};
case 'mine':
case 'myTeam':
if (value)
return {'c.salesPersonFk': {inq: teamMembersId}};
else
return {'c.salesPersonFk': {nin: teamMembersId}};
-
- case 'alertLevel':
- return {'ts.alertLevel': value};
- case 'pending':
- if (value) {
- return {and: [
- {'st.alertLevel': 0},
- {'st.code': {nin: [
- 'OK',
- 'BOARDING',
- 'PRINTED',
- 'PRINTED_AUTO',
- 'PICKER_DESIGNED'
- ]}}
- ]};
- } else {
- return {and: [
- {'st.alertLevel': {gt: 0}}
- ]};
- }
case 'id':
case 'clientFk':
- case 'agencyModeFk':
- case 'warehouseFk':
param = `t.${param}`;
return {[param]: value};
}
@@ -216,6 +182,7 @@ module.exports = Self => {
ts.code AS alertLevelCode,
u.name AS userName,
c.salesPersonFk,
+ c.credit,
z.hour AS zoneLanding,
z.name AS zoneName,
z.id AS zoneFk,
@@ -246,6 +213,47 @@ module.exports = Self => {
stmt.merge(conn.makeWhere(filter.where));
stmts.push(stmt);
+ // Get client debt balance
+ stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt');
+ stmts.push(`
+ CREATE TEMPORARY TABLE tmp.clientGetDebt
+ (INDEX (clientFk))
+ ENGINE = MEMORY
+ SELECT DISTINCT clientFk FROM tmp.filter`);
+
+ stmt = new ParameterizedSQL('CALL clientGetDebt(?)', [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
+ (INDEX (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');
stmts.push(`
CREATE TEMPORARY TABLE tmp.sale_getProblems
@@ -258,27 +266,39 @@ module.exports = Self => {
AND f.shipped >= CURDATE()`);
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
+ `);
+
stmt = new ParameterizedSQL(`
- SELECT f.*, tp.*
- FROM tmp.filter f
- LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = f.id`);
+ SELECT t.*, tp.*,
+ ((tp.risk) + cc.riskTolerance < 0) AS hasHighRisk
+ FROM tmp.tickets t
+ LEFT JOIN tmp.ticket_problems tp ON tp.ticketFk = t.id
+ JOIN clientConfig cc`);
const hasProblems = args.problems;
if (hasProblems != undefined && (!args.from && !args.to))
throw new UserError('Choose a date range or days forward');
- let problemsFilter;
+ let finalFilter = {};
+ let whereProblems;
if (hasProblems === true) {
- problemsFilter = {or: [
+ whereProblems = {or: [
{'tp.isFreezed': true},
- {'tp.risk': {gt: 0}},
+ {'tp.risk': {lt: 0}},
{'tp.hasTicketRequest': true},
{'tp.hasComponentLack': true},
{'tp.isTaxDataChecked': false},
{'tp.isAvailable': false}
]};
} else if (hasProblems === false) {
- problemsFilter = {and: [
+ whereProblems = {and: [
{'tp.isFreezed': false},
{'tp.risk': 0},
{'tp.hasTicketRequest': false},
@@ -288,8 +308,53 @@ module.exports = Self => {
]};
}
- if (problemsFilter)
- stmt.merge(conn.makeWhere(problemsFilter));
+ if (whereProblems) finalFilter.where = whereProblems;
+
+ const myWhere = buildFilter(ctx.args, (param, value) => {
+ switch (param) {
+ case 'search':
+ return /^\d+$/.test(value)
+ ? {'t.id': {inq: value}}
+ : {'t.nickname': {like: `%${value}%`}};
+
+ case 'nickname':
+ return {'t.nickname': {like: `%${value}%`}};
+ case 'refFk':
+ return {'t.refFk': value};
+
+ case 'provinceFk':
+ return {'t.provinceFk': value};
+ case 'stateFk':
+ return {'t.stateFk': value};
+ case 'alertLevel':
+ return {'t.alertLevel': value};
+ case 'pending':
+ if (value) {
+ return {and: [
+ {'t.alertLevel': 0},
+ {'t.alertLevelCode': {nin: [
+ 'OK',
+ 'BOARDING',
+ 'PRINTED',
+ 'PRINTED_AUTO',
+ 'PICKER_DESIGNED'
+ ]}}
+ ]};
+ } else {
+ return {and: [
+ {'t.alertLevel': {gt: 0}}
+ ]};
+ }
+ case 'agencyModeFk':
+ case 'warehouseFk':
+ param = `t.${param}`;
+ return {[param]: value};
+ }
+ });
+
+ finalFilter = mergeFilters(finalFilter, {where: myWhere});
+ if (finalFilter.where)
+ stmt.merge(conn.makeWhere(finalFilter.where));
stmt.merge(conn.makeOrderBy(filter.order));
stmt.merge(conn.makeLimit(filter));
@@ -298,7 +363,9 @@ module.exports = Self => {
stmts.push(
`DROP TEMPORARY TABLE
tmp.filter,
- tmp.ticket_problems`);
+ tmp.ticket_problems,
+ tmp.sale_getProblems,
+ tmp.risk`);
let sql = ParameterizedSQL.join(stmts, ';');
let result = await conn.executeStmt(sql);
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 ceea82ca8..28e2b5571 100644
--- a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js
+++ b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js
@@ -23,7 +23,7 @@ describe('SalesMonitor salesFilter()', () => {
const filter = {};
const result = await models.SalesMonitor.salesFilter(ctx, filter);
- expect(result.length).toEqual(9);
+ expect(result.length).toEqual(13);
});
it('should now return the tickets matching the problems on false', async() => {
diff --git a/modules/monitor/front/index/search-panel/index.html b/modules/monitor/front/index/search-panel/index.html
index dc24c778b..5458202d2 100644
--- a/modules/monitor/front/index/search-panel/index.html
+++ b/modules/monitor/front/index/search-panel/index.html
@@ -70,7 +70,7 @@
diff --git a/modules/monitor/front/index/search-panel/index.js b/modules/monitor/front/index/search-panel/index.js
index 057d555e4..ef6625e8a 100644
--- a/modules/monitor/front/index/search-panel/index.js
+++ b/modules/monitor/front/index/search-panel/index.js
@@ -14,7 +14,7 @@ class Controller extends SearchPanel {
this.$http.get('AlertLevels').then(res => {
for (let state of res.data) {
groupedStates.push({
- alertLevel: state.alertLevel,
+ id: state.id,
code: state.code,
name: this.$t(state.code)
});
diff --git a/modules/monitor/front/index/search-panel/index.spec.js b/modules/monitor/front/index/search-panel/index.spec.js
index 0d19fd35f..f862e8d77 100644
--- a/modules/monitor/front/index/search-panel/index.spec.js
+++ b/modules/monitor/front/index/search-panel/index.spec.js
@@ -18,7 +18,7 @@ describe('Monitor Component vnMonitorSalesSearchPanel', () => {
jest.spyOn(controller, '$t').mockReturnValue('miCodigo');
const data = [
{
- alertLevel: 9999,
+ id: 9999,
code: 'myCode'
}
];
@@ -27,7 +27,7 @@ describe('Monitor Component vnMonitorSalesSearchPanel', () => {
$httpBackend.flush();
expect(controller.groupedStates).toEqual([{
- alertLevel: 9999,
+ id: 9999,
code: 'myCode',
name: 'miCodigo'
}]);
diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html
index 690e0cdb0..4a166d51a 100644
--- a/modules/monitor/front/index/tickets/index.html
+++ b/modules/monitor/front/index/tickets/index.html
@@ -50,7 +50,7 @@
-
+
{
case 'sourceApp':
return {'o.source_app': value};
case 'ticketFk':
- return {'ort.ticketFk': value};
+ return {'ot.ticketFk': value};
case 'isConfirmed':
return {'o.confirmed': value ? 1 : 0};
case 'myTeam':
@@ -137,7 +137,10 @@ module.exports = Self => {
let stmt;
stmt = new ParameterizedSQL(
- `SELECT
+ `CREATE TEMPORARY TABLE tmp.filter
+ (INDEX (id))
+ ENGINE = MEMORY
+ SELECT
o.id,
o.total,
o.date_send landed,
@@ -168,20 +171,20 @@ module.exports = Self => {
LEFT JOIN ticket t ON t.id = ot.ticketFk
LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`);
- if (args && args.ticketFk) {
- stmt.merge({
- sql: `LEFT JOIN orderTicket ort ON ort.orderFk = o.id`
- });
- }
-
stmt.merge(conn.makeWhere(filter.where));
- stmt.merge(`GROUP BY o.id`);
stmt.merge(conn.makePagination(filter));
stmts.push(stmt);
+ stmt = new ParameterizedSQL(`SELECT * FROM tmp.filter`);
+ stmt.merge(`GROUP BY id`);
+ stmt.merge(conn.makeOrderBy(filter.order));
+ const ordersIndex = stmts.push(stmt) - 1;
+
+ stmts.push(`DROP TEMPORARY TABLE tmp.filter`);
+
const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql);
- return result;
+ return result[ordersIndex];
};
};
diff --git a/modules/order/front/index/index.html b/modules/order/front/index/index.html
index 288e81226..a2a4a5226 100644
--- a/modules/order/front/index/index.html
+++ b/modules/order/front/index/index.html
@@ -17,7 +17,7 @@
Landed
Hour
Agency
- Total
+ Total
diff --git a/modules/ticket/front/search-panel/index.html b/modules/ticket/front/search-panel/index.html
index 79dfabb58..445729952 100644
--- a/modules/ticket/front/search-panel/index.html
+++ b/modules/ticket/front/search-panel/index.html
@@ -89,7 +89,7 @@
diff --git a/modules/ticket/front/search-panel/index.js b/modules/ticket/front/search-panel/index.js
index 6ef47757a..ed86921e0 100644
--- a/modules/ticket/front/search-panel/index.js
+++ b/modules/ticket/front/search-panel/index.js
@@ -14,7 +14,7 @@ class Controller extends SearchPanel {
this.$http.get('AlertLevels').then(res => {
for (let state of res.data) {
groupedStates.push({
- alertLevel: state.alertLevel,
+ id: state.id,
code: state.code,
name: this.$t(state.code)
});
diff --git a/modules/ticket/front/search-panel/index.spec.js b/modules/ticket/front/search-panel/index.spec.js
index f3a2f39ed..41c32c047 100644
--- a/modules/ticket/front/search-panel/index.spec.js
+++ b/modules/ticket/front/search-panel/index.spec.js
@@ -18,7 +18,7 @@ describe('Ticket Component vnTicketSearchPanel', () => {
jest.spyOn(controller, '$t').mockReturnValue('miCodigo');
const data = [
{
- alertLevel: 9999,
+ id: 9999,
code: 'myCode'
}
];
@@ -27,7 +27,7 @@ describe('Ticket Component vnTicketSearchPanel', () => {
$httpBackend.flush();
expect(controller.groupedStates).toEqual([{
- alertLevel: 9999,
+ id: 9999,
code: 'myCode',
name: 'miCodigo'
}]);