From 80e32e1c5c80d25269fb59905696e58893b2109e Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Wed, 20 May 2020 16:34:53 +0200
Subject: [PATCH 001/109] zone descriptor path

---
 e2e/paths/11-zone/02_descriptor.spec.js | 33 +++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 e2e/paths/11-zone/02_descriptor.spec.js

diff --git a/e2e/paths/11-zone/02_descriptor.spec.js b/e2e/paths/11-zone/02_descriptor.spec.js
new file mode 100644
index 0000000000..fab9b308b0
--- /dev/null
+++ b/e2e/paths/11-zone/02_descriptor.spec.js
@@ -0,0 +1,33 @@
+import selectors from '../../helpers/selectors.js';
+import getBrowser from '../../helpers/puppeteer';
+
+describe('Zone descriptor path', () => {
+    let browser;
+    let page;
+
+    beforeAll(async() => {
+        browser = await getBrowser();
+        page = browser.page;
+        await page.loginAndModule('deliveryBoss', 'zone');
+        await page.accessToSearchResult('10');
+        await page.accessToSection('zone.card.basicData');
+    });
+
+    afterAll(async() => {
+        await browser.close();
+    });
+
+    it('should reach the basic data section', async() => {
+        await page.waitForState('zone.card.basicData');
+    });
+
+    it('should edit de form and then save', async() => {
+        await page.clearInput(selectors.zoneBasicData.name);
+        await page.write(selectors.zoneBasicData.name, 'Brimstone teleportation');
+        await page.autocompleteSearch(selectors.zoneBasicData.agency, 'Quantum break device');
+        await page.write(selectors.zoneBasicData.maxVolume, '10');
+        const message = await page.waitForSnackbar();
+
+        expect(message.type).toBe('success');
+    });
+});

From 5d9ed494514c68e642ae0749abf820ea912ece06 Mon Sep 17 00:00:00 2001
From: Joan Sanchez <joan@verdnatura.es>
Date: Tue, 16 Jun 2020 08:17:01 +0200
Subject: [PATCH 002/109] 2285 - Added closure paths

---
 .../ticket_closeByAgency.sql                  |  32 ++++
 .../ticket_closeByAllWarehouses.sql           |  42 +++++
 .../ticket_closeByRoute.sql                   |  29 ++++
 .../ticket_closeByTicket.sql                  |  28 +++
 .../ticket_closeByWarehouse.sql               |  29 ++++
 print/methods/closure.js                      | 163 ++++++++++++++++--
 6 files changed, 304 insertions(+), 19 deletions(-)
 create mode 100644 db/changes/10200-DeEscalation/ticket_closeByAgency.sql
 create mode 100644 db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
 create mode 100644 db/changes/10200-DeEscalation/ticket_closeByRoute.sql
 create mode 100644 db/changes/10200-DeEscalation/ticket_closeByTicket.sql
 create mode 100644 db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql

diff --git a/db/changes/10200-DeEscalation/ticket_closeByAgency.sql b/db/changes/10200-DeEscalation/ticket_closeByAgency.sql
new file mode 100644
index 0000000000..155305afe2
--- /dev/null
+++ b/db/changes/10200-DeEscalation/ticket_closeByAgency.sql
@@ -0,0 +1,32 @@
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByAgencyList`(vWarehouseFk INT, vDateTo DATE)
+BEGIN
+/**
+ * Inserta los tickets de todos los almacenes en la tabla temporal
+ * para ser cerrados.
+ *
+ * @param vWarehouseFk Id del almacén
+ * @param vDate Fecha del cierre
+ */
+
+	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
+
+	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
+		SELECT 
+			t.id AS ticketFk
+		FROM expedition e
+			JOIN ticket t ON t.id = e.ticketFk
+			JOIN tmp.ticketClosureAgencyList al ON al.agencyModeFk = t.agencyModeFk
+			JOIN ticketState ts ON ts.ticketFk = t.id
+		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+		WHERE al.code = 'PACKED'
+			AND t.warehouseFk = vWarehouseFk
+			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
+			AND t.refFk IS NULL
+		GROUP BY e.ticketFk);
+		
+        
+	CALL ticket_close();
+    
+	DROP TEMPORARY TABLE tmp.ticketClosureAgencyList;
+    DROP TEMPORARY TABLE tmp.ticketClosure;
+END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql b/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
new file mode 100644
index 0000000000..4a3ae76c82
--- /dev/null
+++ b/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
@@ -0,0 +1,42 @@
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByAllWarehouses`(vDateTo DATE)
+BEGIN
+/**
+ * Inserta los tickets de todos los almacenes en la tabla temporal
+ * para ser cerrados.
+ *
+ * @param vDate Fecha del cierre
+ */
+	DECLARE vDateToEndDay DATETIME DEFAULT util.dayEnd(vDateTo);
+    
+	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
+
+	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
+		SELECT 
+			t.id AS ticketFk
+		FROM expedition e
+			JOIN ticket t ON t.id = e.ticketFk
+			JOIN warehouse w ON w.id = t.warehouseFk AND hasComission
+			JOIN ticketState ts ON ts.ticketFk = t.id
+		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+		WHERE al.code = 'PACKED'
+			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
+			AND t.refFk IS NULL
+		GROUP BY e.ticketFk);
+        
+	CALL ticket_close();
+    
+    -- cau 15033
+    UPDATE ticket t
+				JOIN ticketState ts ON t.id = ts.ticketFk
+                JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                JOIN agencyMode am ON am.id = t.agencyModeFk 
+                JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
+                JOIN zone z ON z.id = t.zoneFk
+		SET t.routeFk = NULL
+            WHERE shipped BETWEEN vDateTo AND vDateToEndDay
+				AND al.code NOT IN('DELIVERED','PACKED')
+                AND t.routeFk
+				AND z.`name` LIKE '%MADRID%';
+            
+    DROP TEMPORARY TABLE tmp.ticketClosure;
+END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByRoute.sql b/db/changes/10200-DeEscalation/ticket_closeByRoute.sql
new file mode 100644
index 0000000000..3c1500bd6b
--- /dev/null
+++ b/db/changes/10200-DeEscalation/ticket_closeByRoute.sql
@@ -0,0 +1,29 @@
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByRoute`( vRouteFk INT)
+BEGIN
+/**
+ * Inserta los tickets de la ruta en la tabla temporal
+ * para ser cerrados.
+ *
+ * @param vWarehouseFk Almacén a cerrar
+ * @param vRouteFk Ruta a cerrar
+ * @param vDate Fecha del cierre
+ */
+
+	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
+
+	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
+		SELECT 
+			t.id AS ticketFk
+		FROM expedition e
+			JOIN ticket t ON t.id = e.ticketFk
+			JOIN ticketState ts ON ts.ticketFk = t.id
+		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+		WHERE al.code = 'PACKED'
+			AND t.routeFk = vRouteFk
+			AND t.refFk IS NULL
+		GROUP BY e.ticketFk);
+        
+	CALL ticket_close();
+    
+    DROP TEMPORARY TABLE tmp.ticketClosure;
+END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByTicket.sql b/db/changes/10200-DeEscalation/ticket_closeByTicket.sql
new file mode 100644
index 0000000000..1ffb5a2653
--- /dev/null
+++ b/db/changes/10200-DeEscalation/ticket_closeByTicket.sql
@@ -0,0 +1,28 @@
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByTicket`(vTicketFk INT)
+BEGIN
+
+/**
+ * Inserta el ticket en la tabla temporal
+ * para ser cerrado.
+ *
+ * @param vTicketFk Id del ticket
+ */
+
+	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
+
+	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
+		SELECT 
+			t.id AS ticketFk
+		FROM expedition e
+			JOIN ticket t ON t.id = e.ticketFk
+			JOIN ticketState ts ON ts.ticketFk = t.id
+            JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+		WHERE al.code = 'PACKED'
+            AND t.id = vTicketFk
+			AND t.refFk IS NULL
+		GROUP BY e.ticketFk);
+        
+	CALL ticket_close();
+    
+    DROP TEMPORARY TABLE tmp.ticketClosure;
+END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql b/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql
new file mode 100644
index 0000000000..e7996edb07
--- /dev/null
+++ b/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql
@@ -0,0 +1,29 @@
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByWarehouse`(vWarehouseFk INT, vDateTo DATE)
+BEGIN
+/**
+ * Inserta los tickets del almacen en la tabla temporal
+ * para ser cerrados.
+ *
+ * @param vWarehouseFk Almacén a cerrar
+ * @param vDate Fecha del cierre
+ */
+
+	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
+
+	CREATE TEMPORARY TABLE ticketClosure ENGINE = MEMORY(
+		SELECT 
+			t.id AS ticketFk
+		FROM expedition e
+			JOIN ticket t ON t.id = e.ticketFk
+			JOIN ticketState ts ON ts.ticketFk = t.id
+		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+		WHERE al.code = 'PACKED' 
+			AND t.warehouseFk = vWarehouseFk
+			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
+			AND t.refFk IS NULL
+		GROUP BY e.ticketFk);
+        
+	CALL ticket_close();
+    
+    DROP TEMPORARY TABLE tmp.ticketClosure;
+END
\ No newline at end of file
diff --git a/print/methods/closure.js b/print/methods/closure.js
index 3bcca9d4e7..15023263b9 100644
--- a/print/methods/closure.js
+++ b/print/methods/closure.js
@@ -4,34 +4,157 @@ const smtp = require('../core/smtp');
 const config = require('../core/config');
 
 module.exports = app => {
-    app.get('/api/closure/by-ticket', async function(req, res) {
+    app.get('/api/closure/all', async function(req, res, next) {
+        try {
+            res.status(200).json({
+                message: 'Task executed successfully'
+            });
+
+            await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`);
+            await db.rawSql(`
+            CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY (
+                SELECT 
+                    t.id AS ticketFk
+                FROM expedition e
+                    JOIN ticket t ON t.id = e.ticketFk
+                    JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission
+                    JOIN ticketState ts ON ts.ticketFk = t.id
+                    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                WHERE al.code = 'PACKED'
+                    AND DATE(t.shipped) BETWEEN DATE_ADD(CURDATE(), INTERVAL -2 DAY) AND CURDATE()
+                    AND t.refFk IS NULL
+                GROUP BY e.ticketFk)`);
+
+            await closeAll(req.args);
+        } catch (error) {
+            next(error);
+        }
     });
 
-    app.get('/api/closure/all', async function(req, res) {
-        res.status(200).json({
-            message: 'Task executed successfully'
-        });
+    app.get('/api/closure/by-ticket', async function(req, res, next) {
+        try {
+            const reqArgs = req.args;
+            if (!reqArgs.ticketId)
+                throw new Error('The argument ticketId is required');
 
+            res.status(200).json({
+                message: 'Task executed successfully'
+            });
+
+            await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`);
+            await db.rawSql(`
+            CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY (
+                SELECT 
+                    t.id AS ticketFk
+                FROM expedition e
+                    JOIN ticket t ON t.id = e.ticketFk
+                    JOIN ticketState ts ON ts.ticketFk = t.id
+                    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                WHERE al.code = 'PACKED'
+                    AND t.id = :ticketId
+                    AND t.refFk IS NULL
+                GROUP BY e.ticketFk)`, {
+                ticketId: reqArgs.ticketId
+            });
+
+            await closeAll(reqArgs);
+        } catch (error) {
+            next(error);
+        }
+    });
+
+    app.get('/api/closure/by-agency', async function(req, res) {
+        try {
+            const reqArgs = req.args;
+            if (!reqArgs.agencyModeId)
+                throw new Error('The argument agencyModeId is required');
+
+            if (!reqArgs.warehouseId)
+                throw new Error('The argument warehouseId is required');
+
+            if (!reqArgs.to)
+                throw new Error('The argument to is required');
+
+            res.status(200).json({
+                message: 'Task executed successfully'
+            });
+
+            await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`);
+            await db.rawSql(`
+            CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY (
+                SELECT 
+                    t.id AS ticketFk
+                FROM expedition e
+                    JOIN ticket t ON t.id = e.ticketFk
+                    JOIN ticketState ts ON ts.ticketFk = t.id
+                    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                WHERE al.code = 'PACKED'
+                    AND t.agencyModeFk = :agencyModeId
+                    AND t.warehouseFk = :warehouseId
+                    AND DATE(t.shipped) BETWEEN DATE_ADD(:to, INTERVAL -2 DAY) AND :to
+                    AND t.refFk IS NULL
+                GROUP BY e.ticketFk)`, {
+                agencyModeId: reqArgs.agencyModeId,
+                warehouseId: reqArgs.warehouseId,
+                to: reqArgs.to
+            });
+
+            await closeAll(reqArgs);
+        } catch (error) {
+            next(error);
+        }
+    });
+
+    app.get('/api/closure/by-route', async function(req, res) {
+        try {
+            const reqArgs = req.args;
+            if (!reqArgs.routeId)
+                throw new Error('The argument routeId is required');
+
+            res.status(200).json({
+                message: 'Task executed successfully'
+            });
+
+            await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`);
+            await db.rawSql(`
+            CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY (
+                SELECT 
+                    t.id AS ticketFk
+                FROM expedition e
+                    JOIN ticket t ON t.id = e.ticketFk
+                    JOIN ticketState ts ON ts.ticketFk = t.id
+                    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                WHERE al.code = 'PACKED'
+                    AND t.routeFk = :routeId
+                    AND t.refFk IS NULL
+                GROUP BY e.ticketFk)`, {
+                routeId: reqArgs.routeId
+            });
+
+            await closeAll(reqArgs);
+        } catch (error) {
+            next(error);
+        }
+    });
+
+    async function closeAll(reqArgs) {
         const failedtickets = [];
         const tickets = await db.rawSql(`
             SELECT 
                 t.id,
                 t.clientFk,
                 c.email recipient,
-                c.isToBeMailed,
                 c.salesPersonFk,
+                c.isToBeMailed,
+                c.hasToInvoice,
+                co.hasDailyInvoice,
                 eu.email salesPersonEmail
-            FROM expedition e
-                JOIN ticket t ON t.id = e.ticketFk
+            FROM tmp.ticket_close tt
+                JOIN ticket t ON t.id = tt.ticketFk
                 JOIN client c ON c.id = t.clientFk
-                JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission
-                JOIN ticketState ts ON ts.ticketFk = t.id
-                JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-                LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
-            WHERE al.code = 'PACKED'
-                AND DATE(t.shipped) BETWEEN DATE_ADD(CURDATE(), INTERVAL -2 DAY) AND CURDATE()
-                AND t.refFk IS NULL
-            GROUP BY e.ticketFk`);
+                JOIN province p ON p.id = c.provinceFk
+                JOIN country co ON co.id = p.countryFk
+                LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk`);
 
         for (const ticket of tickets) {
             try {
@@ -39,7 +162,8 @@ module.exports = app => {
                     ticketId: ticket.id
                 });
 
-                if (!ticket.salesPersonFk || !ticket.isToBeMailed) continue;
+                const hasToInvoice = ticket.hasToInvoice && ticket.hasDailyInvoice;
+                if (!ticket.salesPersonFk || !ticket.isToBeMailed || hasToInvoice) continue;
 
                 if (!ticket.recipient) {
                     const body = `No se ha podido enviar el albarán <strong>${ticket.id}</strong> 
@@ -54,7 +178,6 @@ module.exports = app => {
                     continue;
                 }
 
-                const reqArgs = req.args;
                 const args = Object.assign({
                     ticketId: ticket.id,
                     recipientId: ticket.clientFk,
@@ -88,5 +211,7 @@ module.exports = app => {
                 html: body
             });
         }
-    });
+
+        await db.rawSql(`DROP TEMPORARY TABLE tmp.ticket_close`);
+    }
 };

From 0b8e749939175fff8671358e518151b8cead7327 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 3 Jul 2020 15:14:57 +0200
Subject: [PATCH 003/109] removed autoLoad from vnTable

---
 front/core/components/table/index.js | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/front/core/components/table/index.js b/front/core/components/table/index.js
index 0b9236c849..baed54821c 100644
--- a/front/core/components/table/index.js
+++ b/front/core/components/table/index.js
@@ -7,7 +7,6 @@ export default class Table {
         this.table = $element[0];
         this.field = null;
         this.order = null;
-        this.autoLoad = true;
     }
 
     setOrder(field, order) {
@@ -25,9 +24,7 @@ export default class Table {
     }
 
     $onChanges() {
-        // FIXME: The autoload property should be removed from vnTable
-        // because it's already implemented at vnModel
-        if (this.autoLoad && this.model && !this.model.data)
+        if (this.model && !this.model.data)
             this.applyOrder();
     }
 

From f2730dd51c033d89feb1a740e6a71585831a5bbe Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Mon, 20 Jul 2020 11:31:47 +0200
Subject: [PATCH 004/109] some parts of latestsBuys WIP

---
 front/core/directives/index.js                |   2 +-
 .../directives/{uvc.html => smart-table.html} |  13 +-
 .../directives/{uvc.js => smart-table.js}     |  29 ++--
 .../directives/{uvc.scss => smart-table.scss} |   2 +-
 front/core/styles/icons/salixfont.css         |   4 +-
 front/core/styles/icons/salixfont.svg         |   1 +
 front/core/styles/icons/salixfont.ttf         | Bin 32980 -> 33496 bytes
 front/core/styles/icons/salixfont.woff        | Bin 33056 -> 33572 bytes
 .../back/methods/entry/latestBuysFilter.js    | 111 ++++++++++++
 .../entry/specs/latestBuysFilter.spec.js      |  15 ++
 modules/entry/back/models/entry.js            |   2 +-
 modules/entry/front/index.js                  |   2 +
 modules/entry/front/index/locale/es.yml       |   4 +-
 .../front/latest-buys-search-panel/index.html | 162 ++++++++++++++++++
 .../front/latest-buys-search-panel/index.js   |  79 +++++++++
 .../latest-buys-search-panel/index.spec.js    |  45 +++++
 .../latest-buys-search-panel/locale/es.yml    |   8 +
 modules/entry/front/latest-buys/index.html    | 120 +++++++++++++
 modules/entry/front/latest-buys/index.js      |  31 ++++
 modules/entry/front/latest-buys/locale/es.yml |   1 +
 modules/entry/front/locale/es.yml             |   1 +
 modules/entry/front/routes.json               |   8 +-
 modules/item/back/methods/item/filter.js      |   2 +-
 modules/item/front/index/index.html           |   2 +-
 24 files changed, 615 insertions(+), 29 deletions(-)
 rename front/core/directives/{uvc.html => smart-table.html} (77%)
 rename front/core/directives/{uvc.js => smart-table.js} (81%)
 rename front/core/directives/{uvc.scss => smart-table.scss} (76%)
 create mode 100644 modules/entry/back/methods/entry/latestBuysFilter.js
 create mode 100644 modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js
 create mode 100644 modules/entry/front/latest-buys-search-panel/index.html
 create mode 100644 modules/entry/front/latest-buys-search-panel/index.js
 create mode 100644 modules/entry/front/latest-buys-search-panel/index.spec.js
 create mode 100644 modules/entry/front/latest-buys-search-panel/locale/es.yml
 create mode 100644 modules/entry/front/latest-buys/index.html
 create mode 100644 modules/entry/front/latest-buys/index.js
 create mode 100644 modules/entry/front/latest-buys/locale/es.yml

diff --git a/front/core/directives/index.js b/front/core/directives/index.js
index 4377afe8c4..af05c9b38e 100644
--- a/front/core/directives/index.js
+++ b/front/core/directives/index.js
@@ -11,7 +11,7 @@ import './visible-by';
 import './bind';
 import './repeat-last';
 import './title';
-import './uvc';
+import './smart-table';
 import './droppable';
 import './http-click';
 import './http-submit';
diff --git a/front/core/directives/uvc.html b/front/core/directives/smart-table.html
similarity index 77%
rename from front/core/directives/uvc.html
rename to front/core/directives/smart-table.html
index 9de13b6755..6808b56181 100644
--- a/front/core/directives/uvc.html
+++ b/front/core/directives/smart-table.html
@@ -1,12 +1,13 @@
 <div style="position: relative;">
-    <div style="position: absolute; top: 0; left: 0; padding: .3em; z-index: 1">
+    <div style="position: absolute; top: 0; left: 0; z-index: 1">
         <vn-icon-button
-            icon="menu"
-            ng-click="$ctrl.showUvc($event)">
+            class="vn-pt-sm"
+            icon="more_vert"
+            ng-click="$ctrl.showSmartTable($event)">
         </vn-icon-button>
-        <vn-dialog
+        <vn-popover
             class="modal-form"
-            vn-id="uvc"
+            vn-id="smart-table"
             message="Fields to show">
             <tpl-body>
                 <div class="vn-pa-md">
@@ -24,6 +25,6 @@
                     </vn-horizontal>
                 </div>
             </tpl-body>
-        </vn-dialog>
+        </vn-popover>
     </div>
 </div>
diff --git a/front/core/directives/uvc.js b/front/core/directives/smart-table.js
similarity index 81%
rename from front/core/directives/uvc.js
rename to front/core/directives/smart-table.js
index e464a93abf..2d5a24ade4 100644
--- a/front/core/directives/uvc.js
+++ b/front/core/directives/smart-table.js
@@ -1,6 +1,6 @@
 import ngModule from '../module';
-import template from './uvc.html';
-import './uvc.scss';
+import template from './smart-table.html';
+import './smart-table.scss';
 
 directive.$inject = ['$http', '$compile', 'vnApp', '$translate'];
 export function directive($http, $compile, vnApp, $translate) {
@@ -42,30 +42,29 @@ export function directive($http, $compile, vnApp, $translate) {
                     return (el.getAttribute('th-id') == key || el.getAttribute('field') == key);
                 });
 
-                let baseSelector = `vn-table[vn-uvc=${userConfig.tableCode}] > div`;
+                let baseSelector = `vn-table[vn-smart-table=${userConfig.tableCode}] > div`;
                 selectors.push(`${baseSelector} vn-thead > vn-tr > vn-th:nth-child(${index + 1})`);
                 selectors.push(`${baseSelector} vn-tbody > vn-tr > vn-td:nth-child(${index + 1})`);
                 selectors.push(`${baseSelector} vn-tbody > .vn-tr > vn-td:nth-child(${index + 1})`);
             }
         });
 
-
-        if (document.querySelector('style[id="uvc"]')) {
-            let child = document.querySelector('style[id="uvc"]');
+        if (document.querySelector('style[id="smart-table"]')) {
+            let child = document.querySelector('style[id="smart-table"]');
             child.parentNode.removeChild(child);
         }
 
         if (selectors.length) {
             let rule = selectors.join(', ') + '{display: none;}';
             $scope.css = document.createElement('style');
-            $scope.css.setAttribute('id', 'uvc');
+            $scope.css.setAttribute('id', 'smart-table');
             document.head.appendChild($scope.css);
             $scope.css.appendChild(document.createTextNode(rule));
         }
 
         $scope.$on('$destroy', () => {
-            if ($scope.css && document.querySelector('style[id="uvc"]')) {
-                let child = document.querySelector('style[id="uvc"]');
+            if ($scope.css && document.querySelector('style[id="smart-table"]')) {
+                let child = document.querySelector('style[id="smart-table"]');
                 child.parentNode.removeChild(child);
             }
         });
@@ -80,13 +79,13 @@ export function directive($http, $compile, vnApp, $translate) {
         restrict: 'A',
         link: async function($scope, $element, $attrs) {
             let cTemplate = $compile(template)($scope)[0];
-            $scope.$ctrl.showUvc = event => {
+            $scope.$ctrl.showSmartTable = event => {
                 event.preventDefault();
                 event.stopImmediatePropagation();
-                $scope.uvc.show();
+                $scope.smartTable.show(event.target);
             };
 
-            let tableCode = $attrs.vnUvc.trim();
+            let tableCode = $attrs.vnSmartTable.trim();
             let headerList = getHeaderList($element, $scope);
 
             let defaultConfigView = {tableCode: tableCode, configuration: {}};
@@ -98,16 +97,16 @@ export function directive($http, $compile, vnApp, $translate) {
 
             addHideClass($scope, headerList, config);
 
-            let table = document.querySelector(`vn-table[vn-uvc=${tableCode}]`);
+            let table = document.querySelector(`vn-table[vn-smart-table=${tableCode}]`);
 
             table.insertBefore(cTemplate, table.firstChild);
             $scope.$ctrl.saveConfiguration = async tableConfiguration => {
                 let newConfig = await saveConfiguration(tableConfiguration);
                 vnApp.showSuccess($translate.instant('Data saved!'));
                 addHideClass($scope, headerList, newConfig.data);
-                $scope.uvc.hide();
+                $scope.smartTable.hide();
             };
         }
     };
 }
-ngModule.directive('vnUvc', directive);
+ngModule.directive('vnSmartTable', directive);
diff --git a/front/core/directives/uvc.scss b/front/core/directives/smart-table.scss
similarity index 76%
rename from front/core/directives/uvc.scss
rename to front/core/directives/smart-table.scss
index 0cdf0ba1a4..a156c060ba 100644
--- a/front/core/directives/uvc.scss
+++ b/front/core/directives/smart-table.scss
@@ -1,4 +1,4 @@
-vn-table vn-dialog[vn-id="uvc"]{
+vn-table vn-popover[vn-id="smart-table"]{
     & > div {
         min-width: 288px;
         align-items: center;
diff --git a/front/core/styles/icons/salixfont.css b/front/core/styles/icons/salixfont.css
index 8805815e85..52a2308b44 100644
--- a/front/core/styles/icons/salixfont.css
+++ b/front/core/styles/icons/salixfont.css
@@ -22,7 +22,9 @@
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
 }
-
+.icon-latestBuys:before {
+  content: "\e95f";
+}
 .icon-zone:before {
   content: "\e95d";
 }
diff --git a/front/core/styles/icons/salixfont.svg b/front/core/styles/icons/salixfont.svg
index 9ca57000d5..7e8695d633 100644
--- a/front/core/styles/icons/salixfont.svg
+++ b/front/core/styles/icons/salixfont.svg
@@ -102,6 +102,7 @@
 <glyph unicode="&#xe95c;" glyph-name="anonymous" d="M230.4 605.867c12.8 46.933 29.867 93.867 46.933 140.8 8.533 34.133 21.333 64 29.867 98.133 4.267 12.8 8.533 12.8 21.333 12.8 38.4-12.8 72.533-21.333 110.933-25.6 12.8-4.267 29.867 0 46.933 0 34.133 4.267 68.267 8.533 102.4 12.8s72.533 12.8 106.667 17.067c4.267 0 8.533 0 12.8 0s8.533 0 12.8-8.533c12.8-46.933 29.867-93.867 42.667-136.533 12.8-38.4 25.6-76.8 34.133-115.2-192 4.267-379.733 4.267-567.467 4.267zM456.533 247.467c34.133 8.533 64 12.8 98.133 4.267 8.533 0 12.8 0 12.8 8.533 17.067 34.133 42.667 59.733 76.8 72.533 38.4 17.067 76.8 21.333 115.2 8.533 34.133-8.533 59.733-29.867 81.067-55.467 25.6-34.133 38.4-72.533 34.133-119.467-8.533-51.2-34.133-89.6-76.8-115.2-51.2-34.133-132.267-29.867-179.2 12.8-42.667 34.133-59.733 76.8-64 128 0 8.533-4.267 12.8-12.8 17.067-21.333 4.267-42.667 4.267-64 0-8.533-4.267-8.533-4.267-8.533-12.8 0-21.333-4.267-46.933-12.8-68.267-12.8-29.867-34.133-55.467-64-72.533-55.467-38.4-136.533-34.133-183.467 8.533-42.667 34.133-64 76.8-59.733 128 0 59.733 29.867 106.667 85.333 136.533s115.2 25.6 170.667-12.8c12.8-8.533 21.333-17.067 34.133-29.867 0-8.533 8.533-21.333 17.067-38.4zM307.2 302.933c-64 0-115.2-51.2-115.2-110.933 0-64 46.933-115.2 110.933-115.2s115.2 46.933 115.2 110.933c4.267 64-46.933 115.2-110.933 115.2zM712.533 302.933c-64 0-115.2-51.2-115.2-110.933 0-64 46.933-115.2 110.933-115.2 59.733 0 115.2 46.933 115.2 110.933 0 59.733-46.933 115.2-110.933 115.2zM1024 409.6c-341.333 0-682.667 0-1024 0 0 0 0 0 0 0 17.067 8.533 29.867 17.067 46.933 21.333 42.667 12.8 85.333 29.867 132.267 42.667 34.133 8.533 68.267 17.067 102.4 21.333 89.6 17.067 183.467 21.333 277.333 17.067 55.467-4.267 110.933-8.533 166.4-17.067 38.4-4.267 72.533-12.8 110.933-21.333s72.533-21.333 110.933-34.133c21.333-4.267 51.2-17.067 76.8-29.867 0 0 0 0 0 0z" />
 <glyph unicode="&#xe95d;" glyph-name="zone" d="M243.2 448c-12.8 17.067-25.6 34.133-38.4 51.2-34.133 46.933-68.267 98.133-89.6 153.6-17.067 34.133-25.6 72.533-17.067 110.933 8.533 51.2 38.4 89.6 85.333 110.933 59.733 25.6 132.267 8.533 174.933-34.133 34.133-38.4 42.667-81.067 34.133-132.267-8.533-46.933-29.867-85.333-51.2-123.733-29.867-46.933-59.733-89.6-89.6-132.267-4.267 0-4.267 0-8.533-4.267zM247.467 823.467c-46.933 0-89.6-38.4-89.6-89.6 0-46.933 38.4-89.6 85.333-89.6s89.6 38.4 89.6 85.333c0 55.467-38.4 93.867-85.333 93.867zM490.667 379.733l-17.067 25.6 12.8 8.533-34.133 183.467c0 0 0 8.533-8.533 8.533l-42.667 4.267c0 0-68.267-110.933-157.867-217.6 4.267 4.267-93.867 110.933-132.267 187.733l-110.933-51.2c0 0-4.267 0-4.267-8.533l25.6-145.067 34.133-21.333-8.533-21.333-17.067 8.533 59.733-332.8 213.333 102.4 238.933-21.333-51.2 290.133zM149.333 285.867c-12.8 4.267-29.867 12.8-42.667 17.067 4.267 8.533 4.267 17.067 8.533 21.333 17.067 0 29.867-4.267 42.667-12.8-4.267-8.533-4.267-17.067-8.533-25.6zM256 268.8c-17.067 0-34.133 4.267-46.933 4.267 0 8.533 4.267 17.067 4.267 25.6 12.8 0 29.867-4.267 42.667-4.267 0-8.533 0-17.067 0-25.6zM315.733 277.333c-4.267 8.533-4.267 12.8-8.533 21.333 17.067 8.533 29.867 17.067 42.667 21.333 4.267-8.533 8.533-12.8 8.533-21.333-12.8-8.533-25.6-12.8-42.667-21.333zM405.333 328.533c-4.267 8.533-8.533 12.8-12.8 21.333 12.8 8.533 25.6 17.067 38.4 25.6 4.267-4.267 8.533-12.8 12.8-21.333-8.533-8.533-21.333-17.067-38.4-25.6zM972.8 460.8l-29.867 25.6 12.8 21.333 12.8-8.533-34.133 187.733c0 0 0 8.533-8.533 8.533l-226.133 17.067-209.067-93.867c0 0-8.533-4.267-4.267-12.8l29.867-170.667 21.333-12.8-17.067-17.067 55.467-307.2 213.333 102.4 234.667-21.333-51.2 281.6zM580.267 465.067c-4.267 4.267-8.533 12.8-12.8 17.067 12.8 12.8 21.333 21.333 29.867 34.133 4.267-4.267 12.8-12.8 17.067-17.067-12.8-8.533-25.6-21.333-34.133-34.133zM657.067 541.867c-4.267 4.267-8.533 12.8-12.8 21.333 12.8 8.533 25.6 17.067 38.4 25.6 8.533-8.533 12.8-17.067 12.8-21.333-12.8-8.533-25.6-17.067-38.4-25.6zM797.867 571.733c-12.8 4.267-25.6 4.267-42.667 4.267 0 8.533 0 17.067 0 25.6 17.067 0 34.133 0 51.2-4.267-4.267-8.533-4.267-17.067-8.533-25.6zM891.733 520.533c-12.8 8.533-25.6 17.067-38.4 25.6 4.267 8.533 8.533 12.8 12.8 21.333 12.8-8.533 25.6-17.067 38.4-25.6-4.267-8.533-8.533-12.8-12.8-21.333z" />
 <glyph unicode="&#xe95e;" glyph-name="inventory" d="M273.067 226.133c4.267 0 8.533 4.267 8.533 8.533v85.333h98.133v-221.867h-217.6v221.867h98.133v-81.067c0-8.533 8.533-12.8 12.8-12.8zM512 226.133c4.267 0 8.533 4.267 8.533 8.533v85.333h98.133v-221.867h-217.6v221.867h98.133v-81.067c0-8.533 8.533-12.8 12.8-12.8zM750.933 226.133c4.267 0 8.533 4.267 8.533 8.533v85.333h98.133v-221.867h-217.6v221.867h98.133v-81.067c4.267-8.533 8.533-12.8 12.8-12.8zM644.267 780.8h98.133v-81.067c0-4.267 4.267-8.533 8.533-8.533s8.533 4.267 8.533 8.533v81.067h98.133v-221.867h-217.6v221.867h4.267zM401.067 780.8h98.133v-81.067c0-4.267 4.267-8.533 8.533-8.533s8.533 4.267 8.533 8.533v81.067h98.133v-221.867h-213.333v221.867zM162.133 780.8h98.133v-81.067c0-4.267 4.267-8.533 8.533-8.533s8.533 4.267 8.533 8.533v81.067h98.133v-221.867h-213.333v221.867zM153.6 537.6h780.8v-38.4h-844.8v38.4zM68.267-42.667h-42.667v981.333h42.667v-908.8zM89.6 38.4v38.4h844.8v-38.4zM998.4-42.667h-42.667v981.333h42.667z" />
+<glyph unicode="&#xe95f;" glyph-name="latestBuys" d="M183.467 750.933h712.533v-38.4h-768v38.4zM89.6 64c8.533 0 12.8 0 21.333-4.267v900.267h-42.667v-900.267c8.533 4.267 12.8 4.267 21.333 4.267zM955.733 512v448h-42.667v-413.867c17.067-12.8 29.867-21.333 42.667-34.133zM145.067-8.533c0-30.633-24.833-55.467-55.467-55.467s-55.467 24.833-55.467 55.467c0 30.633 24.833 55.467 55.467 55.467s55.467-24.833 55.467-55.467zM418.133 426.667h-290.133v-38.4h273.067c4.267 17.067 8.533 29.867 17.067 38.4zM392.533 106.667h-264.533v-38.4h281.6c-8.533 12.8-12.8 25.6-17.067 38.4zM725.333 247.467c-12.8 0-21.333-8.533-21.333-21.333s8.533-21.333 21.333-21.333c12.8 0 21.333 8.533 21.333 21.333 0 8.533-12.8 21.333-21.333 21.333zM721.067 541.867c-166.4 0-298.667-136.533-298.667-302.933s132.267-302.933 298.667-302.933c166.4 0 298.667 136.533 298.667 302.933 0 170.667-132.267 302.933-298.667 302.933zM725.333 34.133c-98.133 0-174.933 72.533-187.733 162.133h-34.133l51.2 64 59.733-64h-38.4c8.533-68.267 72.533-123.733 149.333-123.733 81.067 0 149.333 64 149.333 145.067s-68.267 145.067-149.333 145.067c-68.267 0-128-46.933-145.067-110.933l-21.333 29.867-17.067-12.8c8.533 29.867 25.6 55.467 46.933 76.8l-25.6 21.333c-4.267 4.267-4.267 12.8 0 17.067l12.8 12.8c4.267 4.267 12.8 4.267 17.067 0l25.6-25.6c21.333 12.8 51.2 25.6 76.8 25.6v29.867h-8.533c-8.533 0-12.8 4.267-12.8 12.8v17.067c0 8.533 4.267 12.8 12.8 12.8h59.733c8.533 0 12.8-4.267 12.8-12.8v-17.067c0-8.533-4.267-12.8-12.8-12.8h-8.533v-21.333c29.867-4.267 55.467-12.8 81.067-29.867l34.133 29.867c4.267 4.267 12.8 4.267 17.067 0l12.8-12.8c4.267-4.267 4.267-12.8 0-17.067l-25.6-25.6c29.867-34.133 51.2-76.8 51.2-128 4.267-102.4-81.067-187.733-183.467-187.733zM772.267 226.133c0-25.6-21.333-46.933-46.933-46.933s-46.933 21.333-46.933 46.933c0 25.6 21.333 46.933 46.933 46.933 8.533 0 17.067-4.267 21.333-4.267l46.933 46.933 21.333-21.333-46.933-46.933c4.267-4.267 4.267-12.8 4.267-21.333z" />
 <glyph unicode="&#xe968;" glyph-name="wiki" d="M793.6 733.867c0 0 4.267 0 4.267 0l76.8 12.8v-42.667c0-34.133-21.333-68.267-46.933-72.533 0 0-4.267 0-4.267 0l-76.8-12.8v42.667c0 34.133 21.333 64 46.933 72.533zM742.4 597.333l38.4 4.267c12.8 0 25.6-12.8 25.6-29.867v-21.333l-38.4-4.267c-12.8 0-25.6 12.8-25.6 29.867v21.333zM618.667 699.733l68.267 8.533c25.6 4.267 42.667-21.333 42.667-55.467v-38.4l-68.267-8.533c-25.6-4.267-42.667 21.333-42.667 55.467v38.4zM665.6 588.8c4.267 0 4.267 0 0 0l59.733 4.267v-29.867c0-25.6-17.067-46.933-34.133-55.467 0 0-4.267 0-4.267 0l-55.467-8.533v29.867c4.267 29.867 17.067 51.2 34.133 59.733zM443.733 648.533c0 0-4.267 0-4.267 0-119.467 85.333-273.067 46.933-277.333 46.933s-8.533 0-12.8 8.533c0 4.267 0 8.533 8.533 12.8 0 0 42.667 12.8 98.133 8.533 51.2 0 128-12.8 196.267-59.733 4.267-4.267 4.267-8.533 4.267-12.8-4.267-4.267-8.533-4.267-12.8-4.267zM443.733 512c0 0-4.267 0-4.267 0-119.467 85.333-273.067 46.933-277.333 46.933s-8.533 0-12.8 8.533c0 4.267 0 8.533 8.533 12.8 0 0 42.667 12.8 98.133 8.533 51.2 0 128-12.8 196.267-59.733 4.267-4.267 4.267-8.533 4.267-12.8-4.267 0-8.533-4.267-12.8-4.267zM443.733 379.733c0 0-4.267 0-4.267 0-119.467 85.333-273.067 46.933-277.333 46.933s-8.533 0-12.8 8.533c0 4.267 0 8.533 8.533 12.8 0 0 42.667 12.8 98.133 8.533 51.2 0 128-12.8 196.267-59.733 4.267-4.267 4.267-8.533 4.267-12.8-4.267 0-8.533-4.267-12.8-4.267zM443.733 247.467c0 0-4.267 0-4.267 0-119.467 85.333-273.067 46.933-277.333 46.933s-8.533 0-12.8 8.533c0 4.267 0 8.533 8.533 12.8 0 0 42.667 12.8 98.133 8.533 51.2 0 128-12.8 196.267-59.733 4.267-4.267 4.267-8.533 4.267-12.8-4.267 0-8.533-4.267-12.8-4.267zM588.8 379.733c-4.267 0-4.267 0-8.533 4.267s0 8.533 4.267 12.8c68.267 46.933 140.8 59.733 196.267 59.733s93.867-8.533 98.133-8.533c4.267 0 8.533-8.533 8.533-12.8s-8.533-8.533-12.8-8.533v0c0 0-153.6 38.4-277.333-46.933-4.267 4.267-4.267 0-8.533 0zM588.8 247.467c-4.267 0-4.267 0-8.533 4.267s0 8.533 4.267 12.8c68.267 46.933 140.8 59.733 196.267 59.733s93.867-8.533 98.133-8.533c4.267 0 8.533-8.533 8.533-12.8s-8.533-8.533-12.8-8.533v0c0 0-153.6 38.4-277.333-46.933-4.267 4.267-4.267 0-8.533 0zM985.6 738.133v64l-8.533 4.267c-4.267 0-81.067 29.867-179.2 29.867-106.667 0-200.533-34.133-277.333-98.133-76.8 64-170.667 98.133-277.333 98.133-102.4 0-174.933-29.867-179.2-29.867l-12.8-4.267v-59.733c-34.133-4.267-51.2-17.067-51.2-34.133v-614.4h452.267c17.067-12.8 38.4-21.333 64-21.333s46.933 8.533 64 21.333h443.733v614.4c0 17.067-17.067 25.6-38.4 29.867v0zM512 145.067c-38.4 17.067-166.4 64-298.667 64-51.2 0-98.133-8.533-136.533-21.333v597.333c21.333 8.533 85.333 25.6 162.133 25.6 98.133 0 183.467-29.867 256-89.6v-358.4l17.067 17.067v-234.667zM955.733 183.467c-42.667 17.067-89.6 25.6-140.8 25.6-128 0-251.733-51.2-290.133-64v238.933l17.067-17.067v349.867c68.267 59.733 153.6 89.6 256 89.6 76.8 0 136.533-17.067 162.133-25.6v-597.333z" />
 <glyph unicode="&#xe96c;" glyph-name="attach" d="M960 866.133c-42.667 42.667-98.133 64-157.867 64s-115.2-21.333-157.867-64l-593.067-593.067c-34.133-34.133-55.467-85.333-51.2-136.533 0-42.667 17.067-81.067 46.933-110.933 34.133-38.4 81.067-59.733 132.267-59.733 46.933 0 93.867 17.067 128 51.2l541.867 546.133c25.6 25.6 42.667 64 42.667 98.133s-12.8 68.267-38.4 93.867c-25.6 25.6-59.733 38.4-98.133 38.4-34.133 0-72.533-17.067-98.133-42.667l-354.133-354.133c-4.267 0-4.267-4.267-4.267-12.8s4.267-12.8 8.533-17.067 25.6-8.533 34.133 0l354.133 354.133c12.8 17.067 38.4 25.6 59.733 25.6 25.6 0 51.2-12.8 68.267-34.133 8.533-12.8 17.067-25.6 17.067-42.667 4.267-25.6-4.267-55.467-25.6-72.533l-541.867-541.867c-25.6-25.6-55.467-38.4-93.867-38.4-34.133 0-68.267 12.8-93.867 38.4s-38.4 59.733-38.4 93.867c0 34.133 12.8 68.267 38.4 93.867l588.8 584.533c34.133 34.133 76.8 51.2 123.733 51.2s89.6-17.067 123.733-51.2c34.133-34.133 51.2-76.8 51.2-123.733s-17.067-89.6-51.2-123.733l-401.067-401.067c-4.267-4.267-8.533-12.8-8.533-17.067 0-8.533 4.267-12.8 8.533-17.067 8.533-8.533 25.6-8.533 34.133 0l401.067 401.067c89.6 89.6 89.6 230.4 4.267 320z" />
 <glyph unicode="&#xe96d;" glyph-name="zone2" d="M98.133 17.067c-4.267 29.867-12.8 64-17.067 93.867-17.067 98.133-34.133 192-51.2 290.133-12.8 46.933-21.333 98.133-29.867 149.333 0 4.267 0 8.533 4.267 8.533 42.667 21.333 85.333 42.667 128 59.733 0 0 0 0 4.267 0 4.267-8.533 8.533-12.8 12.8-21.333-21.333-8.533-42.667-21.333-64-29.867-17.067-8.533-34.133-17.067-51.2-21.333-4.267 0-4.267-4.267-4.267-8.533 8.533-42.667 17.067-85.333 25.6-132.267 0-4.267 4.267-4.267 4.267-8.533 8.533-4.267 17.067-8.533 25.6-17.067 0-4.267-4.267-12.8-8.533-17.067-4.267 4.267-12.8 4.267-17.067 8.533 17.067-102.4 38.4-209.067 55.467-311.467 17.067 8.533 29.867 12.8 42.667 21.333 51.2 25.6 102.4 51.2 153.6 72.533 4.267 0 8.533 0 17.067 0 68.267-4.267 136.533-12.8 204.8-17.067 0 0 4.267 0 8.533 0-4.267 17.067-4.267 34.133-8.533 51.2-12.8 68.267-25.6 136.533-38.4 204.8 0 8.533-4.267 17.067-12.8 25.6-4.267 4.267-4.267 8.533-8.533 12.8 12.8 4.267 8.533 17.067 8.533 25.6-8.533 51.2-17.067 106.667-29.867 157.867 0 4.267 0 4.267-8.533 4.267-17.067 0-38.4 4.267-55.467 4.267 4.267 8.533 8.533 17.067 12.8 21.333 0 0 4.267 4.267 8.533 4.267 17.067 0 34.133-4.267 46.933-4.267 4.267 0 8.533 0 12.8 0 68.267 29.867 132.267 64 200.533 93.867 4.267 4.267 8.533 8.533 12.8 8.533 68.267-4.267 136.533-8.533 204.8-17.067 8.533 0 17.067 0 29.867-4.267 4.267 0 8.533-4.267 8.533-8.533 12.8-64 25.6-132.267 34.133-196.267 17.067-102.4 38.4-204.8 55.467-311.467 0-8.533 4.267-17.067 4.267-25.6-17.067 0-34.133 4.267-51.2 4.267-42.667 4.267-89.6 8.533-132.267 12.8-17.067 0-38.4 4.267-55.467 4.267-4.267 0-12.8 0-17.067-4.267-68.267-29.867-132.267-64-200.533-93.867 0 0-4.267 0-8.533 0-76.8 8.533-149.333 12.8-226.133 21.333-4.267 0-8.533 0-12.8 0-72.533-34.133-140.8-68.267-213.333-102.4 0-4.267 0-8.533-4.267-8.533zM989.867 217.6c0 4.267 0 4.267 0 8.533-8.533 34.133-12.8 72.533-21.333 106.667-8.533 46.933-17.067 89.6-25.6 136.533 0 8.533-4.267 12.8-8.533 17.067-8.533 4.267-12.8 12.8-21.333 17.067 4.267 8.533 8.533 12.8 12.8 17.067 4.267-4.267 8.533-4.267 12.8-8.533-4.267 12.8-4.267 21.333-4.267 34.133-8.533 46.933-17.067 93.867-25.6 145.067 0 4.267-4.267 8.533-8.533 8.533-68.267 4.267-136.533 12.8-209.067 17.067-4.267 0-8.533 0-12.8-4.267-64-29.867-123.733-59.733-187.733-85.333-4.267-4.267-8.533-4.267-4.267-12.8 4.267-29.867 12.8-64 17.067-93.867 4.267-21.333 8.533-42.667 12.8-59.733 12.8-4.267 12.8-12.8 21.333-21.333-12.8-4.267-12.8-12.8-12.8-25.6 12.8-68.267 25.6-132.267 38.4-200.533 4.267-25.6 8.533-51.2 12.8-76.8 4.267 0 4.267 0 8.533 4.267 59.733 29.867 119.467 59.733 183.467 89.6-4.267 4.267 0 4.267 4.267 4.267 51.2-4.267 106.667-8.533 157.867-12.8 21.333 0 38.4-4.267 59.733-4.267zM260.267 469.333c-12.8 17.067-25.6 34.133-38.4 46.933-29.867 46.933-59.733 93.867-85.333 145.067-12.8 29.867-21.333 64-17.067 102.4 8.533 51.2 34.133 85.333 81.067 102.4 55.467 21.333 123.733 8.533 162.133-34.133 34.133-34.133 42.667-76.8 34.133-123.733-8.533-42.667-25.6-76.8-46.933-115.2-25.6-42.667-55.467-81.067-85.333-123.733 0 4.267-4.267 0-4.267 0zM260.267 819.2c-46.933 0-81.067-34.133-81.067-81.067s38.4-81.067 81.067-81.067c46.933 0 81.067 38.4 85.333 81.067 0 42.667-38.4 81.067-85.333 81.067zM358.4 349.867c4.267-8.533 4.267-12.8 8.533-21.333-12.8-4.267-25.6-12.8-38.4-17.067-4.267 8.533-4.267 12.8-8.533 21.333 12.8 4.267 25.6 12.8 38.4 17.067zM226.133 302.933c0 8.533 4.267 17.067 4.267 21.333 12.8 0 25.6-4.267 38.4-4.267 0-8.533 0-12.8 0-25.6-12.8 8.533-29.867 8.533-42.667 8.533zM413.867 354.133c-4.267 8.533-8.533 12.8-12.8 21.333 12.8 8.533 21.333 17.067 34.133 25.6 4.267-4.267 8.533-12.8 12.8-17.067-12.8-12.8-21.333-21.333-34.133-29.867zM179.2 341.333c-4.267-8.533-4.267-12.8-8.533-21.333-12.8 4.267-25.6 8.533-38.4 17.067 4.267 8.533 4.267 12.8 8.533 21.333 12.8-8.533 25.6-12.8 38.4-17.067zM682.667 580.267c-12.8-8.533-21.333-17.067-34.133-21.333-4.267 4.267-8.533 12.8-12.8 17.067 12.8 8.533 25.6 17.067 38.4 25.6 4.267-8.533 4.267-17.067 8.533-21.333zM878.933 558.933c-4.267-8.533-8.533-12.8-12.8-21.333-12.8 8.533-25.6 17.067-34.133 21.333 4.267 8.533 8.533 12.8 8.533 21.333 12.8-8.533 25.6-17.067 38.4-21.333zM571.733 486.4c-4.267 4.267-8.533 12.8-12.8 17.067 8.533 8.533 21.333 21.333 29.867 29.867 4.267-4.267 8.533-12.8 12.8-17.067-8.533-8.533-17.067-21.333-29.867-29.867zM785.067 610.133c-4.267-8.533-4.267-17.067-8.533-21.333-12.8 0-25.6 4.267-38.4 4.267 0 8.533 0 12.8 0 21.333 17.067 0 29.867-4.267 46.933-4.267z" />
diff --git a/front/core/styles/icons/salixfont.ttf b/front/core/styles/icons/salixfont.ttf
index ab5de35ff5704093f92f0a42ab96502a9010e385..608dd7c80c653928df2a89af6a5851ad8237c19d 100644
GIT binary patch
delta 739
zcmYjPOKTHR6h0?+m`Nr{lQ_xDB&O3m+8HHiY92Fbo1_63TCj_hR;h?3wKWl%w%95a
zLeq*x7X_^WS6UT81y_=V6<h>dxvC2VAE5XH#Fh9Ujov7NXK}yto$oxp#eKDEdb4J_
z7OeI>+Xg^C08AAN3-c76l&?@U7iTV<eze*5iSjD|m4~J2!j$*igQoz?y;Rprw7@-Q
zx+yPF-d!p$E^S=4-lcq<&fJ`tJ5?C&DW3pX*+cc0<-*cDteMVJ{+;r`Y@s|YpFH;V
z5WuQT2R7&D78Zd}2`+AJY}Ih0b_BafQ~Xh%MeXcy9zwqwq)8gUKnJ)X02=IrJ{W`B
z@EAY{dV)z36D3#JmBlzxP!Qd0IHV>MdORi~ZOEcQDD20c5bJS^@tB@WsH8TS_g6!z
z7B-}?f`5zQ5X)&C?bp=AAnLI$q)U@@Sq2mO0LH{lx;ug%1tp`cif#ug=n>hl@!!q3
zA#n;mF}>IUm9?-D&dia?h~3@%7?7l3P?7@ZYJET#F;`h{>l^ww4u>o@n}xSItXV_P
zOR_BGbtC&<-amB45>5=L?9sl=_;@Csw|iWy*Xbj~POQY|+$)$_j$_j-4U41+A%>?4
z@rs>fb~w7*E%^NcXJw+EC_&Q~Ro%%WA(yJn3PEgOqcv%9?0l92e+=R+%`R}QhQ<pw
ztbE%T*MXWWkEE!jlrbXH7%@`WoRP}QQj3{5n9Icvk7m+igT0Df)SMn_i5~ayPK9N6
zwJp&{Bpr5zVQdV~czro_c&;J%dA}g|nWz{g*825@`)0qnsc%m>(qF;Kw7&$rj~ux7
k4{M_p1B><b%2mWrO<sO&X9w=2`?I5fw53@8x%>`)1FhMZ8~^|S

delta 247
zcmcc7%5<fXX@X+C%AT_f42&`i3=AphiNys#S^&sz0MZ=kIhASO=8GQ&@;ew9s#avA
zCZ<SO8SH0Zs4)P_n`Hn6*blQP1Nj+1zDh=JNkwlvcRi5b1JpAkCqFsS@21`&28KEn
zp!~Vq#EJrj7N#;F{|k_>ke8U7DiIfc)185#UIeINUO|3w2?H}wilJf4#2u3v<0kts
z$}|5K`>{EXQN3vM)Y8QqGF80aF30oRd}ZKf0V!m-)mx?pqbG;dnKPzs?y2i%oGjmP
WiFbjum2C)6k`aj0Hven5#RveSx=3>X

diff --git a/front/core/styles/icons/salixfont.woff b/front/core/styles/icons/salixfont.woff
index d9ade1e3129ece954807ff792cef7900670c114b..ecea37f50a42ae1cf1d2f2b11bd78a1956797899 100644
GIT binary patch
delta 782
zcmYjP-Ahwp9DaX$59e$<n{J)$oNdn2KJ*-7)oNd7>NW?3<%PsV3nP-5HUp=URtCeR
z_Hh|9h@di~sGzG@5JeY*u7bcW3ar5B4~VWJg1Pz~EAR);`@HY-`+6?k)kVXDs|Lq~
zBRxF?2*y$y;dNeIUv{L+?XT7f`I%`#;4Ny#f3OuME}lm1Jt3vXI-aa_d>tRlj}kIp
z!kUB*_qj(e#!*D=8NS<eaIcxR@#5?pYU|j4TgUP>{@%pYDXhCRi#6|b^tBgH6!UY_
zy9rr1h=OkmR}AMT^TjdLa1pHNIC<>jq3Nj^Y+PcN>$hOIauasay7;U564bND%_Q)<
zM(eaj7}7)>I7cOWNCz1tcga&i1i#ZCrx8)I2kjY%0+I~iV1ofA9!o?cB49xVG>Wtr
z+5@c9Ax0yKcub*{1-Ye61Bx2dq@WCc)nI_-R1O<dCDsjz$WFkiah#ThSfUFeVk-_0
zfl~%a)3c(Z8DwyZY*5>_G^$CQ49^X3Hi^QT*bryr=t#)wsDJTElHV^$KCm}7z)s6X
z*4_9C9*%=vlf_~(TblWdmdHsimy}CrnQiyZ-ZQ3PtV>~!cBF@f($SpNX=mLw52aSh
zQ;%(zU}QOtO|cjzNfiQ&88g%^w$jPIaEn9mdIgSW!p<-S!*@m5%mJn4%k>fks6nkU
zVrt&}Ci%7u!X4EraE+R37H;rn-5A#ds>{`%L`zAn--XeyB{NwqnR7`EX81rh8$CRb
zP7QYNldYm^bD||&?lIeBmffLS!b7A@R+(WejG1wJvP$1nP2ka#;AO&MnDW()nTJNN
zv7T5PZchCmJcB=mkk6t0_y2QcwWL9zx?Z{t5U7mKf3UJ$tEtY+z}CMnRC~&w;16&b
BpuGS9

delta 295
zcmZ3|#<ZY`Nvz!8&5ePP0SFou7`Q=n!xaX`$%4(o6E!vJRrZ`sPb@BAU|>80l;MD4
zf%KfpG@#fO28OB?ApC8<_~DGy#1saGni`-QGZ2=rGT5I16a<QG0rFKqnEfz|az<`R
z1yJk;Q2z`N?rrC;&&f{)s;dLq!*C9S{ch?l%1x{&&|zSxcK`|~fN={`SzcmpDo`u|
zsBs<$$A#Z?FUT)00lJ=H;-A@!ag%2-$}|5K`>}Z!qk7Tihoy@-WU6?-U5@9s`O3h}
v0yKt!;Z|>%8jPO2pw65zZS#$~e#Xh!4VQQqSX<eK03|^IlD65a@fITh#xGJU

diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js
new file mode 100644
index 0000000000..edfc46e3b2
--- /dev/null
+++ b/modules/entry/back/methods/entry/latestBuysFilter.js
@@ -0,0 +1,111 @@
+
+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('latestBuysFilter', {
+        description: 'Find all instances of the model matched by filter from the data source.',
+        accessType: 'READ',
+        accepts: [
+            {
+                arg: 'filter',
+                type: 'Object',
+                description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
+                http: {source: 'query'}
+            },
+            {
+                arg: 'tags',
+                type: ['Object'],
+                description: 'List of tags to filter with',
+                http: {source: 'query'}
+            }, {
+                arg: 'search',
+                type: 'String',
+                description: `If it's and integer searchs by id, otherwise it searchs by name`,
+                http: {source: 'query'}
+            }, {
+                arg: 'id',
+                type: 'Integer',
+                description: 'Item id',
+                http: {source: 'query'}
+            }, {
+                arg: 'categoryFk',
+                type: 'Integer',
+                description: 'Category id',
+                http: {source: 'query'}
+            }, {
+                arg: 'typeFk',
+                type: 'Integer',
+                description: 'Type id',
+                http: {source: 'query'}
+            }, {
+                arg: 'isActive',
+                type: 'Boolean',
+                description: 'Whether the the item is or not active',
+                http: {source: 'query'}
+            }, {
+                arg: 'salesPersonFk',
+                type: 'Integer',
+                description: 'The buyer of the item',
+                http: {source: 'query'}
+            }
+        ],
+        returns: {
+            type: ['Object'],
+            root: true
+        },
+        http: {
+            path: `/latestBuysFilter`,
+            verb: 'GET'
+        }
+    });
+
+    Self.latestBuysFilter = async(ctx, filter) => {
+        let conn = Self.dataSource.connector;
+        let where = buildFilter(ctx.args, (param, value) => {
+            // switch (param) {
+            // case 'search':
+            //     return /^\d+$/.test(value)
+            //         ? {or: [{'i.id': value}]}
+            //         : {or: [{'i.name': {like: `%${value}%`}}]};
+            // case 'id':
+            //     return {'i.id': value};
+            // case 'description':
+            //     return {'i.description': {like: `%${value}%`}};
+            // case 'categoryFk':
+            //     return {'ic.id': value};
+            // case 'salesPersonFk':
+            //     return {'t.workerFk': value};
+            // case 'typeFk':
+            //     return {'i.typeFk': value};
+            // case 'isActive':
+            //     return {'i.isActive': value};
+            // }
+        });
+        filter = mergeFilters(ctx.args.filter, {where});
+
+        let stmts = [];
+        let stmt;
+
+        stmt = new ParameterizedSQL('CALL cache.last_buy_refresh(FALSE)');
+        stmts.push(stmt);
+
+        stmt = new ParameterizedSQL(`
+            SELECT 
+                size
+            FROM cache.last_buy lb
+                JOIN item i ON i.id = lb.item_id
+                JOIN itemType it ON it.id = i.typeFk AND lb.warehouse_id = it.warehouseFk
+                JOIN buy b ON b.id = lb.buy_id`
+        );
+
+        stmt.merge(conn.makeSuffix(filter));
+        let buysIndex = stmts.push(stmt) - 1;
+
+        let sql = ParameterizedSQL.join(stmts, ';');
+        let result = await conn.executeStmt(sql);
+        return buysIndex === 0 ? result : result[buysIndex];
+    };
+};
+
diff --git a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js
new file mode 100644
index 0000000000..2e2cab3464
--- /dev/null
+++ b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js
@@ -0,0 +1,15 @@
+const app = require('vn-loopback/server/server');
+
+fdescribe('Entry latests buys filter()', () => {
+    it('should return the entry matching "search"', async() => {
+        let ctx = {
+            args: {
+                search: 1
+            }
+        };
+
+        let result = await app.models.Entry.latestBuysFilter(ctx);
+
+        expect(result[0].size).toEqual(300);
+    });
+});
diff --git a/modules/entry/back/models/entry.js b/modules/entry/back/models/entry.js
index b1f71b4bd3..40f89ebf09 100644
--- a/modules/entry/back/models/entry.js
+++ b/modules/entry/back/models/entry.js
@@ -1,5 +1,5 @@
-
 module.exports = Self => {
+    require('../methods/entry/latestBuysFilter')(Self);
     require('../methods/entry/filter')(Self);
     require('../methods/entry/getEntry')(Self);
 };
diff --git a/modules/entry/front/index.js b/modules/entry/front/index.js
index f0c845b149..eb2c823c40 100644
--- a/modules/entry/front/index.js
+++ b/modules/entry/front/index.js
@@ -2,7 +2,9 @@ export * from './module';
 
 import './main';
 import './index/';
+import './latest-buys';
 import './search-panel';
+import './latest-buys-search-panel';
 import './descriptor';
 import './card';
 import './summary';
diff --git a/modules/entry/front/index/locale/es.yml b/modules/entry/front/index/locale/es.yml
index 8ef9b2c7af..2770ccfe9b 100644
--- a/modules/entry/front/index/locale/es.yml
+++ b/modules/entry/front/index/locale/es.yml
@@ -12,4 +12,6 @@ Reference: Referencia
 Created: Creado
 Booked: Facturado
 Is inventory: Inventario
-Notes: Notas
\ No newline at end of file
+Notes: Notas
+Status: Estado
+Selection: Selección
\ No newline at end of file
diff --git a/modules/entry/front/latest-buys-search-panel/index.html b/modules/entry/front/latest-buys-search-panel/index.html
new file mode 100644
index 0000000000..f30442ec61
--- /dev/null
+++ b/modules/entry/front/latest-buys-search-panel/index.html
@@ -0,0 +1,162 @@
+<mg-ajax path="Tags" options="mgIndex as tags"></mg-ajax>
+<div class="search-panel">
+    <form ng-submit="$ctrl.onSearch()">
+        <vn-horizontal>
+            <vn-textfield
+                vn-one
+                label="General search"
+                ng-model="filter.search"
+                info="Search items by id, name or barcode"
+                vn-focus>
+            </vn-textfield>
+        </vn-horizontal>
+        <vn-horizontal>
+            <vn-autocomplete
+                vn-one
+                vn-focus
+                url="ItemCategories"
+                label="Category"
+                show-field="name"
+                value-field="id"
+                ng-model="filter.categoryFk">
+            </vn-autocomplete>
+            <vn-autocomplete vn-one
+                url="ItemTypes"
+                label="Type"
+                where="{categoryFk: filter.categoryFk}"
+                show-field="name"
+                value-field="id"
+                ng-model="filter.typeFk"
+                fields="['categoryFk']"
+                include="'category'">
+                <tpl-item>
+                    <div>{{name}}</div>
+                    <div class="text-caption text-secondary">
+                        {{category.name}}
+                    </div>
+                </tpl-item>>
+            </vn-autocomplete>
+        </vn-horizontal>
+        <vn-horizontal>
+            <vn-autocomplete 
+                vn-one
+                disabled="false"
+                ng-model="filter.salesPersonFk"
+                url="Clients/activeWorkersWithRole"
+                show-field="nickname"
+                search-function="{firstName: $search}"
+                value-field="id"
+                where="{role: 'employee'}"
+                label="Buyer">
+            </vn-autocomplete>
+        </vn-horizontal>
+        <vn-horizontal class="vn-pt-sm">
+            <vn-one class="text-subtitle1" translate>
+                Tags
+            </vn-one>
+            <vn-icon-button
+                vn-none
+                vn-bind="+"
+                vn-tooltip="Add tag"
+                icon="add_circle"
+                ng-click="filter.tags.push({})">
+            </vn-icon-button>
+        </vn-horizontal>
+        <vn-horizontal ng-repeat="itemTag in filter.tags">
+            <vn-autocomplete
+                vn-id="tag"
+                vn-one
+                ng-model="itemTag.tagFk"
+                data="tags.model"
+                show-field="name"
+                label="Tag"
+                on-change="itemTag.value = null">
+            </vn-autocomplete>
+            <vn-textfield
+                vn-one
+                ng-show="tag.selection.isFree !== false"
+                vn-id="text"
+                label="Value"
+                ng-model="itemTag.value">
+            </vn-textfield>
+            <vn-autocomplete
+                vn-one
+                ng-show="tag.selection.isFree === false"
+                url="{{$ctrl.getSourceTable(tag.selection)}}"
+                label="Value"
+                ng-model="itemTag.value"
+                show-field="name"
+                value-field="name">
+            </vn-autocomplete>
+            <vn-icon-button
+                vn-none
+                vn-tooltip="Remove tag"
+                icon="delete"
+                ng-click="filter.tags.splice($index, 1)"
+                tabindex="-1">
+            </vn-icon-button>
+        </vn-horizontal>
+        <vn-horizontal class="vn-pt-sm">
+            <vn-one class="text-subtitle1" translate>
+                More fields
+            </vn-one>
+            <vn-icon-button
+                vn-none
+                vn-bind="+"
+                vn-tooltip="Add field"
+                icon="add_circle"
+                ng-click="$ctrl.fieldFilters.push({})">
+            </vn-icon-button>
+        </vn-horizontal>
+        <vn-horizontal ng-repeat="fieldFilter in $ctrl.fieldFilters">
+            <vn-autocomplete
+                vn-one
+                label="Field"
+                ng-model="fieldFilter.name"
+                data="$ctrl.moreFields"
+                value-field="name"
+                show-field="label"
+                show-filter="false"
+                translate-fields="['label']"
+                selection="info"
+                on-change="fieldFilter.value = null">
+            </vn-autocomplete>
+            <vn-one ng-switch="info.type">
+                <div ng-switch-when="Number">
+                    <vn-input-number
+                        label="Value"
+                        ng-model="fieldFilter.value">
+                    </vn-input-number>
+                </div>
+                <div ng-switch-when="Boolean">
+                    <vn-check
+                        label="Value"
+                        ng-model="fieldFilter.value">
+                    </vn-check>
+                </div>
+                <div ng-switch-when="Date">
+                    <vn-date-picker
+                        label="Value"
+                        ng-model="fieldFilter.value">
+                    </vn-date-picker>
+                </div>
+                <div ng-switch-default>
+                    <vn-textfield
+                        label="Value"
+                        ng-model="fieldFilter.value">
+                    </vn-textfield>
+                </div>
+            </vn-one>
+            <vn-icon-button
+                vn-none
+                vn-tooltip="Remove field"
+                icon="delete"
+                ng-click="$ctrl.removeField($index, fieldFilter.name)"
+                tabindex="-1">
+            </vn-icon-button>
+        </vn-horizontal>
+        <vn-horizontal class="vn-mt-lg">
+            <vn-submit label="Search"></vn-submit>
+        </vn-horizontal>
+    </form>
+</div>
diff --git a/modules/entry/front/latest-buys-search-panel/index.js b/modules/entry/front/latest-buys-search-panel/index.js
new file mode 100644
index 0000000000..bcb1ca23be
--- /dev/null
+++ b/modules/entry/front/latest-buys-search-panel/index.js
@@ -0,0 +1,79 @@
+import ngModule from '../module';
+import SearchPanel from 'core/components/searchbar/search-panel';
+
+class Controller extends SearchPanel {
+    constructor($element, $) {
+        super($element, $);
+        let model = 'Item';
+        let moreFields = ['id', 'description', 'name', 'isActive'];
+
+        let properties;
+        let validations = window.validations;
+
+        if (validations && validations[model])
+            properties = validations[model].properties;
+        else
+            properties = {};
+
+        this.moreFields = [];
+        for (let field of moreFields) {
+            let prop = properties[field];
+            this.moreFields.push({
+                name: field,
+                label: prop ? prop.description : field,
+                type: prop ? prop.type : null
+            });
+        }
+    }
+
+    get filter() {
+        let filter = this.$.filter;
+
+        for (let fieldFilter of this.fieldFilters)
+            filter[fieldFilter.name] = fieldFilter.value;
+
+        return filter;
+    }
+
+    set filter(value) {
+        if (!value)
+            value = {};
+        if (!value.tags)
+            value.tags = [{}];
+
+        this.fieldFilters = [];
+        for (let field of this.moreFields) {
+            if (value[field.name] != undefined) {
+                this.fieldFilters.push({
+                    name: field.name,
+                    value: value[field.name],
+                    info: field
+                });
+            }
+        }
+
+        this.$.filter = value;
+    }
+
+    getSourceTable(selection) {
+        if (!selection || selection.isFree === true)
+            return null;
+
+        if (selection.sourceTable) {
+            return ''
+                + selection.sourceTable.charAt(0).toUpperCase()
+                + selection.sourceTable.substring(1) + 's';
+        } else if (selection.sourceTable == null)
+            return `ItemTags/filterItemTags/${selection.id}`;
+    }
+
+    removeField(index, field) {
+        this.fieldFilters.splice(index, 1);
+        this.$.filter[field] = undefined;
+    }
+}
+
+ngModule.component('vnLatestBuysSearchPanel', {
+    template: require('./index.html'),
+    controller: Controller
+});
diff --git a/modules/entry/front/latest-buys-search-panel/index.spec.js b/modules/entry/front/latest-buys-search-panel/index.spec.js
new file mode 100644
index 0000000000..cc0cf03753
--- /dev/null
+++ b/modules/entry/front/latest-buys-search-panel/index.spec.js
@@ -0,0 +1,45 @@
+import './index.js';
+
+describe('Item', () => {
+    describe('Component vnItemSearchPanel', () => {
+        let $element;
+        let controller;
+
+        beforeEach(ngModule('item'));
+
+        beforeEach(angular.mock.inject($componentController => {
+            $element = angular.element(`<div></div>`);
+            controller = $componentController('vnItemSearchPanel', {$element});
+        }));
+
+        describe('getSourceTable()', () => {
+            it(`should return null if there's no selection`, () => {
+                let selection = null;
+                let result = controller.getSourceTable(selection);
+
+                expect(result).toBeNull();
+            });
+
+            it(`should return null if there's a selection but its isFree property is truthy`, () => {
+                let selection = {isFree: true};
+                let result = controller.getSourceTable(selection);
+
+                expect(result).toBeNull();
+            });
+
+            it(`should return the formated sourceTable concatenated to a path`, () => {
+                let selection = {sourceTable: 'hello guy'};
+                let result = controller.getSourceTable(selection);
+
+                expect(result).toEqual('Hello guys');
+            });
+
+            it(`should return a path if there's no sourceTable and the selection has an id`, () => {
+                let selection = {id: 99};
+                let result = controller.getSourceTable(selection);
+
+                expect(result).toEqual(`ItemTags/filterItemTags/${selection.id}`);
+            });
+        });
+    });
+});
diff --git a/modules/entry/front/latest-buys-search-panel/locale/es.yml b/modules/entry/front/latest-buys-search-panel/locale/es.yml
new file mode 100644
index 0000000000..197da0695c
--- /dev/null
+++ b/modules/entry/front/latest-buys-search-panel/locale/es.yml
@@ -0,0 +1,8 @@
+Ink: Tinta
+Origin: Origen
+Producer: Productor.
+With visible: Con visible
+Field: Campo
+More fields: Más campos
+Add field: Añadir campo
+Remove field: Quitar campo
\ No newline at end of file
diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
new file mode 100644
index 0000000000..ecf36c63be
--- /dev/null
+++ b/modules/entry/front/latest-buys/index.html
@@ -0,0 +1,120 @@
+<vn-crud-model
+    vn-id="model"
+    url="Entries/latestBuysFilter"
+    limit="20"
+    data="buys"
+    auto-load="true">
+</vn-crud-model>
+<vn-portal slot="topbar">
+    <vn-searchbar
+        panel="vn-latest-buys-search-panel"
+        suggested-filter="$ctrl.filterParams"
+        info="Search buys"
+        filter="$ctrl.filterParams"
+        model="model"
+        auto-state="false">
+    </vn-searchbar>
+</vn-portal>
+<!-- <vn-portal slot="topbar">
+    <vn-searchbar
+        panel="vn-latest-buys-search-panel"
+        info="Search buys"
+        model="model"
+        auto-state="false">
+    </vn-searchbar>
+</vn-portal> -->
+<vn-data-viewer
+    model="model"
+    class="vn-mb-xl vn-w-xl">
+    <vn-card>
+    <vn-table
+        model="model"
+        show-fields="$ctrl.showFields"
+        vn-smart-table="latestBuys">
+        <vn-thead>
+            <vn-tr>
+                <vn-th shrink
+                    field='Selection'>
+                    <vn-multi-check 
+                        model="model">
+                    </vn-multi-check>
+                </vn-th>
+                <vn-th shrink field='status'></vn-th>
+                <vn-th field="id" number>Id</vn-th>
+                <vn-th field="landed" center>Landed</vn-th>
+                <vn-th>Reference</vn-th>
+                <vn-th field="supplierFk">Supplier</vn-th>
+                <vn-th field="currencyFk" center>Currency</vn-th>
+                <vn-th field="companyFk" center>Company</vn-th>
+                <vn-th field="isBooked" center>Booked</vn-th>
+                <vn-th field="isConfirmed" center>Confirmed</vn-th>
+                <vn-th field="isOrdered" center>Ordered</vn-th>
+                <vn-th>Notes</vn-th>
+            </vn-tr>
+        </vn-thead>
+        <vn-tbody>
+            <a ng-repeat="buy in $ctrl.buys" 
+                class="clickable vn-tr search-result"
+                ui-sref="buy.card.summary({id: {{::buy.id}}})">
+                <vn-td shrink>
+                    <vn-check 
+                        ng-model="buy.checked"
+                        vn-click-stop>
+                    </vn-check>
+                </vn-td>
+                <vn-td shrink>
+                    <vn-icon
+                        ng-show="buy.isInventory"
+                        class="bright"
+                        vn-tooltip="Inventory buy"
+                        icon="icon-inventory">
+                    </vn-icon>
+                    <vn-icon
+                        ng-show="buy.isRaid"
+                        class="bright"
+                        vn-tooltip="Virtual buy"
+                        icon="icon-net">
+                    </vn-icon>
+                </vn-td>
+                <vn-td number>{{::buy.size}}</vn-td>
+                <vn-td center>
+                    <span 
+                        class="link" 
+                        vn-click-stop="travelDescriptor.show($event, buy.travelFk)">
+                        {{::buy.landed | date:'dd/MM/yyyy'}}
+                    </span>
+                </vn-td>
+                <vn-td expand>{{::buy.ref}}</vn-td>
+                <vn-td expand>{{::buy.supplierName}}</vn-td>
+                <vn-td center expand>{{::buy.currencyCode}}</vn-td>
+                <vn-td center expand>{{::buy.companyCode}}</vn-td>
+                <vn-td center><vn-check ng-model="buy.isBooked" disabled="true"></vn-check></vn-td>
+                <vn-td center><vn-check ng-model="buy.isConfirmed" disabled="true"></vn-check></vn-td>
+                <vn-td center><vn-check ng-model="buy.isOrdered" disabled="true"></vn-check></vn-td>
+                <vn-td shrink> 
+                    <vn-icon
+                        ng-if="buy.notes.length"
+                        vn-tooltip="{{::buy.notes}}"
+                        icon="insert_drive_file"
+                        class="bright">
+                    </vn-icon>
+                </vn-td>
+            </a>
+        </vn-tbody>
+    </vn-table>
+    </vn-card>
+</vn-data-viewer>
+<div fixed-bottom-right>
+    <vn-vertical style="align-items: center;">
+        <vn-button class="round sm vn-mb-sm"
+            icon="edit"
+            ng-show="$ctrl.totalChecked > 0"
+            ng-click="$ctrl.edit()"
+            vn-tooltip="Edit buys"
+            tooltip-position="left">
+        </vn-button>
+    </vn-vertical>
+</div>
+<vn-travel-descriptor-popover 
+    vn-id="travelDescriptor">
+</vn-travel-descriptor-popover>
\ No newline at end of file
diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js
new file mode 100644
index 0000000000..7f2de41853
--- /dev/null
+++ b/modules/entry/front/latest-buys/index.js
@@ -0,0 +1,31 @@
+import ngModule from '../module';
+import Section from 'salix/components/section';
+
+export default class Controller extends Section {
+    constructor($element, $) {
+        super($element, $);
+        this.showFields = {
+            id: false,
+            actions: false
+        };
+    }
+    get checked() {
+        const buys = this.$.model.data || [];
+        const checkedBuys = [];
+        for (let buy of buys) {
+            if (buy.checked)
+                checkedBuys.push(buy);
+        }
+
+        return checkedBuys;
+    }
+
+    get totalChecked() {
+        return this.checked.length;
+    }
+}
+
+ngModule.component('vnEntryLatestBuys', {
+    template: require('./index.html'),
+    controller: Controller
+});
diff --git a/modules/entry/front/latest-buys/locale/es.yml b/modules/entry/front/latest-buys/locale/es.yml
new file mode 100644
index 0000000000..9eeab7bce4
--- /dev/null
+++ b/modules/entry/front/latest-buys/locale/es.yml
@@ -0,0 +1 @@
+Edit buys: Editar compras
\ No newline at end of file
diff --git a/modules/entry/front/locale/es.yml b/modules/entry/front/locale/es.yml
index 0858bb7f92..b28cbe7352 100644
--- a/modules/entry/front/locale/es.yml
+++ b/modules/entry/front/locale/es.yml
@@ -1,5 +1,6 @@
 #Ordenar alfabeticamente
 
 entry: entrada
+Latest buys: Últimas compras
 
 # Sections
diff --git a/modules/entry/front/routes.json b/modules/entry/front/routes.json
index 084ff7bb22..32c046a3d6 100644
--- a/modules/entry/front/routes.json
+++ b/modules/entry/front/routes.json
@@ -6,7 +6,8 @@
     "validations": true,
     "menus": {
         "main": [
-            {"state": "entry.index", "icon": "icon-entry"}
+            {"state": "entry.index", "icon": "icon-entry"},
+            {"state": "entry.latestBuys", "icon": "icon-latestBuys"}
         ],
         "card": [
             {"state": "entry.card.buy", "icon": "icon-lines"},
@@ -25,6 +26,11 @@
             "state": "entry.index",
             "component": "vn-entry-index",
             "description": "Entries"
+        }, {
+            "url": "/latest-buys?q",
+            "state": "entry.latestBuys",
+            "component": "vn-entry-latest-buys",
+            "description": "Latest buys"
         }, {
             "url": "/:id",
             "state": "entry.card",
diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js
index ad7edfa8ce..5d9ae9e0fb 100644
--- a/modules/item/back/methods/item/filter.js
+++ b/modules/item/back/methods/item/filter.js
@@ -41,7 +41,7 @@ module.exports = Self => {
             }, {
                 arg: 'isActive',
                 type: 'Boolean',
-                description: 'Whether the the item is o not active',
+                description: 'Whether the the item is or not active',
                 http: {source: 'query'}
             }, {
                 arg: 'salesPersonFk',
diff --git a/modules/item/front/index/index.html b/modules/item/front/index/index.html
index 0ee6a8815b..296ac97473 100644
--- a/modules/item/front/index/index.html
+++ b/modules/item/front/index/index.html
@@ -8,7 +8,7 @@
     <vn-table
         model="model"
         show-fields="$ctrl.showFields"
-        vn-uvc="itemIndex">
+        vn-smart-table="itemIndex">
         <vn-thead>
             <vn-tr>
                 <vn-th th-id="picture" shrink></vn-th>

From f9da489a96cd5ca2419377faf4d5fe8cb458ad88 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Mon, 20 Jul 2020 11:50:21 +0200
Subject: [PATCH 005/109] excluded unfinished tests WIP

---
 modules/entry/front/latest-buys-search-panel/index.spec.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/entry/front/latest-buys-search-panel/index.spec.js b/modules/entry/front/latest-buys-search-panel/index.spec.js
index cc0cf03753..0fb8b2128f 100644
--- a/modules/entry/front/latest-buys-search-panel/index.spec.js
+++ b/modules/entry/front/latest-buys-search-panel/index.spec.js
@@ -1,6 +1,6 @@
 import './index.js';
 
-describe('Item', () => {
+xdescribe('Item', () => {
     describe('Component vnItemSearchPanel', () => {
         let $element;
         let controller;
@@ -9,7 +9,7 @@ describe('Item', () => {
 
         beforeEach(angular.mock.inject($componentController => {
             $element = angular.element(`<div></div>`);
-            controller = $componentController('vnItemSearchPanel', {$element});
+            controller = $componentController('vnLatestBuysSearchPanel', {$element});
         }));
 
         describe('getSourceTable()', () => {

From f2bff056e94dd999a09fa1ded656338d16775b95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 10 Aug 2020 10:36:37 +0200
Subject: [PATCH 006/109] Changes

---
 front/core/components/calendar/index.html | 49 +++++++++++++----------
 front/core/components/calendar/style.scss |  9 ++++-
 2 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/front/core/components/calendar/index.html b/front/core/components/calendar/index.html
index eb6d196bad..fb600231b7 100644
--- a/front/core/components/calendar/index.html
+++ b/front/core/components/calendar/index.html
@@ -19,28 +19,33 @@
             ng-if="$ctrl.displayControls">
         </vn-button>
     </div>
-    <div class="weekdays">
-        <section
-            ng-repeat="day in ::$ctrl.weekDays"
-            translate-attr="::{title: day.name}" 
-            ng-click="$ctrl.selectWeekDay($event, day.index)">
-            <span>{{::day.localeChar}}</span>
-        </section>
-    </div>
-    <div
-        class="days"
-        ng-class="{'hide-contiguous': $ctrl.hideContiguous}">
-        <section
-            ng-repeat="day in $ctrl.days"
-            class="day"
-            ng-class="::$ctrl.getDayClasses(day)"
-            vn-repeat-last
-            on-last="$ctrl.repeatLast()">
-            <div
-                class="day-number"
-                ng-click="$ctrl.select($event, day)">
-                {{::day | date: 'd'}}
+    <div class="rows">
+        <div class="weeksNumber">a</div>
+        <div class="weeks">
+            <div class="weekdays">
+                <section
+                    ng-repeat="day in ::$ctrl.weekDays"
+                    translate-attr="::{title: day.name}" 
+                    ng-click="$ctrl.selectWeekDay($event, day.index)">
+                    <span>{{::day.localeChar}}</span>
+                </section>
             </div>
-        </section>
+            <div
+                class="days"
+                ng-class="{'hide-contiguous': $ctrl.hideContiguous}">
+                <section
+                    ng-repeat="day in $ctrl.days"
+                    class="day"
+                    ng-class="::$ctrl.getDayClasses(day)"
+                    vn-repeat-last
+                    on-last="$ctrl.repeatLast()">
+                    <div
+                        class="day-number"
+                        ng-click="$ctrl.select($event, day)">
+                        {{::day | date: 'd'}}
+                    </div>
+                </section>
+            </div>
+        </div>
     </div>
 </div>
\ No newline at end of file
diff --git a/front/core/components/calendar/style.scss b/front/core/components/calendar/style.scss
index 28c87793b2..4ef253f1fe 100644
--- a/front/core/components/calendar/style.scss
+++ b/front/core/components/calendar/style.scss
@@ -19,7 +19,12 @@
                 color: inherit;
             }
         }
-        & > .weekdays {
+        & > .rows > .weeksNumber,
+        & > .rows > .weeks {
+            float: left
+        }
+        
+        & > .rows > .weeks > .weekdays {
             display: flex;
             color: $color-font-secondary;
             margin-bottom: 8px;
@@ -33,7 +38,7 @@
                 cursor: pointer;
             }
         }
-        & > .days {
+        & > .rows > .weeks > .days {
             display: flex;
             justify-content: center;
             align-items: center;

From 7833b87475c5c0751cde5bf4bf2633c251c51c03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 10 Aug 2020 14:44:57 +0200
Subject: [PATCH 007/109] Added filter

---
 modules/worker/front/calendar/index.html    |  9 ++++++++
 modules/worker/front/calendar/index.js      | 23 +++++++++++++++++++++
 modules/worker/front/calendar/locale/es.yml |  1 +
 3 files changed, 33 insertions(+)

diff --git a/modules/worker/front/calendar/index.html b/modules/worker/front/calendar/index.html
index 197fb07972..621d6c23f9 100644
--- a/modules/worker/front/calendar/index.html
+++ b/modules/worker/front/calendar/index.html
@@ -29,6 +29,15 @@
                 {{'of' | translate}} {{$ctrl.calendar.totalHolidays}} {{'days' | translate}}
             </div>
         </div>
+        <div class="vn-pt-md">
+            <vn-autocomplete label="Year"
+                data="$ctrl.yearFilter"
+                ng-model="$ctrl.year"
+                show-field="year"
+                value-field="year"
+                order="DESC">
+            </vn-autocomplete>
+        </div>
         <div class="vn-pt-md" style="overflow: hidden;">
             <vn-chip ng-repeat="absenceType in absenceTypes" ng-class="::{'selectable': $ctrl.isSubordinate}"
                 ng-click="$ctrl.pick(absenceType)">
diff --git a/modules/worker/front/calendar/index.js b/modules/worker/front/calendar/index.js
index e473358045..676a91ee49 100644
--- a/modules/worker/front/calendar/index.js
+++ b/modules/worker/front/calendar/index.js
@@ -7,6 +7,18 @@ class Controller extends Section {
         super($element, $);
         this.date = new Date();
         this.events = {};
+        this.buildYearFilter();
+    }
+
+    get year() {
+        return this.date.getFullYear();
+    }
+
+    set year(value) {
+        const newYear = new Date();
+        newYear.setFullYear(value);
+
+        this.date = newYear;
     }
 
     get date() {
@@ -50,6 +62,17 @@ class Controller extends Section {
         }
     }
 
+    buildYearFilter() {
+        const currentYear = new Date().getFullYear();
+        const minRange = currentYear - 5;
+
+        const years = [];
+        for (let i = currentYear; i > minRange; i--)
+            years.push({year: i});
+
+        this.yearFilter = years;
+    }
+
     getIsSubordinate() {
         this.$http.get(`Workers/${this.worker.id}/isSubordinate`).then(res =>
             this.isSubordinate = res.data
diff --git a/modules/worker/front/calendar/locale/es.yml b/modules/worker/front/calendar/locale/es.yml
index 6681f730f9..f48a67c7bd 100644
--- a/modules/worker/front/calendar/locale/es.yml
+++ b/modules/worker/front/calendar/locale/es.yml
@@ -1,6 +1,7 @@
 Calendar: Calendario
 Holidays: Vacaciones
 Used: Utilizados
+Year: Año
 of: de
 days: días
 Choose an absence type from the right menu: Elige un tipo de ausencia desde el menú de la derecha

From 64abd2925756ae83b26c9731280883474136e321 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 11 Aug 2020 12:10:37 +0200
Subject: [PATCH 008/109] Reverted structure

---
 front/core/components/calendar/index.html | 47 ++++++++++-------------
 front/core/components/calendar/style.scss |  9 +----
 2 files changed, 23 insertions(+), 33 deletions(-)

diff --git a/front/core/components/calendar/index.html b/front/core/components/calendar/index.html
index fb600231b7..eb6d196bad 100644
--- a/front/core/components/calendar/index.html
+++ b/front/core/components/calendar/index.html
@@ -19,33 +19,28 @@
             ng-if="$ctrl.displayControls">
         </vn-button>
     </div>
-    <div class="rows">
-        <div class="weeksNumber">a</div>
-        <div class="weeks">
-            <div class="weekdays">
-                <section
-                    ng-repeat="day in ::$ctrl.weekDays"
-                    translate-attr="::{title: day.name}" 
-                    ng-click="$ctrl.selectWeekDay($event, day.index)">
-                    <span>{{::day.localeChar}}</span>
-                </section>
-            </div>
+    <div class="weekdays">
+        <section
+            ng-repeat="day in ::$ctrl.weekDays"
+            translate-attr="::{title: day.name}" 
+            ng-click="$ctrl.selectWeekDay($event, day.index)">
+            <span>{{::day.localeChar}}</span>
+        </section>
+    </div>
+    <div
+        class="days"
+        ng-class="{'hide-contiguous': $ctrl.hideContiguous}">
+        <section
+            ng-repeat="day in $ctrl.days"
+            class="day"
+            ng-class="::$ctrl.getDayClasses(day)"
+            vn-repeat-last
+            on-last="$ctrl.repeatLast()">
             <div
-                class="days"
-                ng-class="{'hide-contiguous': $ctrl.hideContiguous}">
-                <section
-                    ng-repeat="day in $ctrl.days"
-                    class="day"
-                    ng-class="::$ctrl.getDayClasses(day)"
-                    vn-repeat-last
-                    on-last="$ctrl.repeatLast()">
-                    <div
-                        class="day-number"
-                        ng-click="$ctrl.select($event, day)">
-                        {{::day | date: 'd'}}
-                    </div>
-                </section>
+                class="day-number"
+                ng-click="$ctrl.select($event, day)">
+                {{::day | date: 'd'}}
             </div>
-        </div>
+        </section>
     </div>
 </div>
\ No newline at end of file
diff --git a/front/core/components/calendar/style.scss b/front/core/components/calendar/style.scss
index 4ef253f1fe..28c87793b2 100644
--- a/front/core/components/calendar/style.scss
+++ b/front/core/components/calendar/style.scss
@@ -19,12 +19,7 @@
                 color: inherit;
             }
         }
-        & > .rows > .weeksNumber,
-        & > .rows > .weeks {
-            float: left
-        }
-        
-        & > .rows > .weeks > .weekdays {
+        & > .weekdays {
             display: flex;
             color: $color-font-secondary;
             margin-bottom: 8px;
@@ -38,7 +33,7 @@
                 cursor: pointer;
             }
         }
-        & > .rows > .weeks > .days {
+        & > .days {
             display: flex;
             justify-content: center;
             align-items: center;

From b50b30c792a49b68e889e185879c37e426857673 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 11 Aug 2020 12:16:19 +0200
Subject: [PATCH 009/109] Updated unit test

---
 modules/worker/front/calendar/index.spec.js | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/modules/worker/front/calendar/index.spec.js b/modules/worker/front/calendar/index.spec.js
index 97ea897878..6b5025dae4 100644
--- a/modules/worker/front/calendar/index.spec.js
+++ b/modules/worker/front/calendar/index.spec.js
@@ -22,6 +22,22 @@ describe('Worker', () => {
             controller._worker = {id: 106};
         }));
 
+        describe('year() getter', () => {
+            it(`should return the year number of the calendar date`, () => {
+                expect(controller.year).toEqual(year);
+            });
+        });
+
+        describe('year() setter', () => {
+            it(`should set the year of the calendar date`, () => {
+                const previousYear = year - 1;
+                controller.year = previousYear;
+
+                expect(controller.year).toEqual(previousYear);
+                expect(controller.date.getFullYear()).toEqual(previousYear);
+            });
+        });
+
         describe('started property', () => {
             it(`should return first day and month of current year`, () => {
                 let started = new Date(year, 0, 1);

From 88c5b6f8a6c620d08edbbd098fdcf4d5607ba81e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 13 Aug 2020 08:23:55 +0200
Subject: [PATCH 010/109] Changed ticket problems min date

---
 modules/ticket/back/methods/ticket/filter.js | 8 +++++---
 modules/ticket/front/main/index.html         | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js
index 801563b93c..61f2bd2674 100644
--- a/modules/ticket/back/methods/ticket/filter.js
+++ b/modules/ticket/back/methods/ticket/filter.js
@@ -241,9 +241,11 @@ module.exports = Self => {
             CREATE TEMPORARY TABLE tmp.ticketGetProblems 
                 (INDEX (ticketFk))
                 ENGINE = MEMORY
-                SELECT id ticketFk, clientFk, warehouseFk, shipped 
-                    FROM tmp.filter 
-                    WHERE alertLevel = 0 OR alertLevel IS NULL`);
+                SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped 
+                    FROM tmp.filter f
+                        LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel
+                    WHERE (f.code = 'FREE' OR f.alertLevel IS NULL)
+                        AND f.shipped >= CURDATE()`);
         stmts.push('CALL ticketGetProblems()');
 
         stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticket');
diff --git a/modules/ticket/front/main/index.html b/modules/ticket/front/main/index.html
index bcb77cca5b..a21b28992a 100644
--- a/modules/ticket/front/main/index.html
+++ b/modules/ticket/front/main/index.html
@@ -2,7 +2,7 @@
     vn-id="model"
     url="Tickets/filter"
     limit="20"
-    order="shipped DESC, zoneHour ASC, zoneMinute ASC, clientFk">
+    order="shipped DESC, zoneHour DESC, zoneMinute DESC, clientFk">
 </vn-crud-model>
 <vn-portal slot="topbar">
     <vn-searchbar

From f38701bb43509be53df60258e303f92020a2633a Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Thu, 13 Aug 2020 10:03:50 +0200
Subject: [PATCH 011/109] unit testing filter

---
 jest.config.js                              |  4 ++-
 print/core/config.js                        |  4 +--
 print/core/filters/currency.js              |  8 ++++--
 print/core/filters/date.js                  |  8 ++++--
 print/core/filters/number.js                |  8 ++++--
 print/core/filters/percentage.js            |  8 ++++--
 print/core/filters/specs/currency.spec.js   | 16 ++++++++++++
 print/core/filters/specs/date.spec.js       | 27 +++++++++++++++++++++
 print/core/filters/specs/number.spec.js     |  9 +++++++
 print/core/filters/specs/percentage.spec.js | 11 +++++++++
 print/core/filters/specs/uppercase.spec.js  | 10 ++++++++
 print/core/filters/uppercase.js             |  8 ++++--
 12 files changed, 108 insertions(+), 13 deletions(-)
 create mode 100644 print/core/filters/specs/currency.spec.js
 create mode 100644 print/core/filters/specs/date.spec.js
 create mode 100644 print/core/filters/specs/number.spec.js
 create mode 100644 print/core/filters/specs/percentage.spec.js
 create mode 100644 print/core/filters/specs/uppercase.spec.js

diff --git a/jest.config.js b/jest.config.js
index facd1c8a72..874d9ac0b8 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -70,7 +70,8 @@ module.exports = {
         `front`,
         `modules`,
         `front/node_modules`,
-        `node_modules`
+        `node_modules`,
+        `print`
     ],
 
     // An array of file extensions your modules use
@@ -153,6 +154,7 @@ module.exports = {
     // The glob patterns Jest uses to detect test files
     testMatch: [
         '**/front/**/*.spec.js',
+        '**/print/**/*.spec.js',
     // 'loopback/**/*.spec.js',
     // 'modules/*/back/**/*.spec.js'
     //   "**/__tests__/**/*.[jt]s?(x)",
diff --git a/print/core/config.js b/print/core/config.js
index 864e1658a9..5194762b45 100644
--- a/print/core/config.js
+++ b/print/core/config.js
@@ -4,8 +4,8 @@ let env = process.env.NODE_ENV ? process.env.NODE_ENV : 'development';
 let configPath = `/etc/salix`;
 let config = require('../config/print.json');
 let configFiles = [
-    `${appPath}/config/print.local.json`,
-    `${appPath}/config/print.${env}.json`,
+    `../config/print.local.json`,
+    `../config/print.${env}.json`,
     `${configPath}/print.json`,
     `${configPath}/print.local.json`,
     `${configPath}/print.${env}.json`
diff --git a/print/core/filters/currency.js b/print/core/filters/currency.js
index ec68089062..098c2fe209 100644
--- a/print/core/filters/currency.js
+++ b/print/core/filters/currency.js
@@ -2,9 +2,13 @@ const Vue = require('vue');
 const config = require('../config');
 const defaultLocale = config.i18n.locale;
 
-Vue.filter('currency', function(value, currency = 'EUR', locale = defaultLocale) {
+const currency = function(value, currency = 'EUR', locale = defaultLocale) {
     if (!locale) locale = defaultLocale;
     return new Intl.NumberFormat(locale, {
         style: 'currency', currency
     }).format(parseFloat(value));
-});
+};
+
+Vue.filter('currency', currency);
+
+module.exports = currency;
diff --git a/print/core/filters/date.js b/print/core/filters/date.js
index 5d1bc0de53..70267c76e4 100644
--- a/print/core/filters/date.js
+++ b/print/core/filters/date.js
@@ -1,7 +1,11 @@
 const Vue = require('vue');
 const strftime = require('strftime');
 
-Vue.filter('date', function(value, specifiers = '%d-%m-%Y') {
+const date = function(value, specifiers = '%d-%m-%Y') {
     if (!(value instanceof Date)) value = new Date(value);
     return strftime(specifiers, value);
-});
+};
+
+Vue.filter('date', date);
+
+module.exports = date;
diff --git a/print/core/filters/number.js b/print/core/filters/number.js
index c785706fe4..a0c5e61f76 100644
--- a/print/core/filters/number.js
+++ b/print/core/filters/number.js
@@ -2,9 +2,13 @@ const Vue = require('vue');
 const config = require('../config');
 const defaultLocale = config.i18n.locale;
 
-Vue.filter('number', function(value, locale = defaultLocale) {
+const number = function(value, locale = defaultLocale) {
     if (!locale) locale = defaultLocale;
     return new Intl.NumberFormat(locale, {
         style: 'decimal'
     }).format(parseFloat(value));
-});
+};
+
+Vue.filter('number', number);
+
+module.exports = number;
diff --git a/print/core/filters/percentage.js b/print/core/filters/percentage.js
index 078d2fd89a..c535fe9447 100644
--- a/print/core/filters/percentage.js
+++ b/print/core/filters/percentage.js
@@ -2,11 +2,15 @@ const Vue = require('vue');
 const config = require('../config');
 const defaultLocale = config.i18n.locale;
 
-Vue.filter('percentage', function(value, minFraction = 2, maxFraction = 2, locale = defaultLocale) {
+const percentage = function(value, minFraction = 2, maxFraction = 2, locale = defaultLocale) {
     if (!locale) locale = defaultLocale;
     return new Intl.NumberFormat(locale, {
         style: 'percent',
         minimumFractionDigits: minFraction,
         maximumFractionDigits: maxFraction
     }).format(parseFloat(value));
-});
+};
+
+Vue.filter('percentage', percentage);
+
+module.exports = percentage;
diff --git a/print/core/filters/specs/currency.spec.js b/print/core/filters/specs/currency.spec.js
new file mode 100644
index 0000000000..5a345ddbe9
--- /dev/null
+++ b/print/core/filters/specs/currency.spec.js
@@ -0,0 +1,16 @@
+// Extended locale intl polyfill
+const IntlPolyfill = require('intl');
+Intl.NumberFormat = IntlPolyfill.NumberFormat;
+Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
+
+import currency from '../currency.js';
+
+describe('currency filter', () => {
+    it('should filter the currency in spanish as default', () => {
+        expect(currency(999, 'EUR')).toEqual('999,00 €');
+    });
+
+    it('should filter the currency in english', () => {
+        expect(currency(999, 'EUR', 'en')).toEqual('€999.00');
+    });
+});
diff --git a/print/core/filters/specs/date.spec.js b/print/core/filters/specs/date.spec.js
new file mode 100644
index 0000000000..aa38af5159
--- /dev/null
+++ b/print/core/filters/specs/date.spec.js
@@ -0,0 +1,27 @@
+import date from '../date.js';
+
+describe('date filter', () => {
+    const superDuperDate = new Date('February 18, 1984 @ 11:30:00 am');
+
+    it('should filter the date as %d-%m-%Y by default', () => {
+        expect(date(superDuperDate)).toEqual('18-02-1984');
+    });
+
+    it('should filter the date as %m-%d-%Y', () => {
+        const dateFormat = '%m-%d-%Y';
+
+        expect(date(superDuperDate, dateFormat)).toEqual('02-18-1984');
+    });
+
+    it('should filter the date as %y-%d-%m', () => {
+        const dateFormat = '%y-%d-%m';
+
+        expect(date(superDuperDate, dateFormat)).toEqual('84-18-02');
+    });
+
+    it('should filter the date as %Y-%d-%m', () => {
+        const dateFormat = '%Y-%d-%m';
+
+        expect(date(superDuperDate, dateFormat)).toEqual('1984-18-02');
+    });
+});
diff --git a/print/core/filters/specs/number.spec.js b/print/core/filters/specs/number.spec.js
new file mode 100644
index 0000000000..7522006949
--- /dev/null
+++ b/print/core/filters/specs/number.spec.js
@@ -0,0 +1,9 @@
+import number from '../number.js';
+
+describe('number filter', () => {
+    const superDuperNumber = 18021984;
+
+    it('should filter the number with commas by default', () => {
+        expect(number(superDuperNumber)).toEqual('18,021,984');
+    });
+});
diff --git a/print/core/filters/specs/percentage.spec.js b/print/core/filters/specs/percentage.spec.js
new file mode 100644
index 0000000000..0a9111cbc2
--- /dev/null
+++ b/print/core/filters/specs/percentage.spec.js
@@ -0,0 +1,11 @@
+import percentage from '../percentage.js';
+
+describe('percentage filter', () => {
+    it('should filter the percentage also round it correctly', () => {
+        expect(percentage(99.9999999999999999 / 100)).toEqual('100.00%');
+    });
+
+    it('should filter the percentage and round it correctly', () => {
+        expect(percentage(1.25444444444444444 / 100)).toEqual('1.25%');
+    });
+});
diff --git a/print/core/filters/specs/uppercase.spec.js b/print/core/filters/specs/uppercase.spec.js
new file mode 100644
index 0000000000..77c4933593
--- /dev/null
+++ b/print/core/filters/specs/uppercase.spec.js
@@ -0,0 +1,10 @@
+import uppercase from '../uppercase.js';
+
+describe('uppercase filter', () => {
+    it('should filter the string to uppercase', () => {
+        let lowerCase = 'text';
+        let upperCase = 'TEXT';
+
+        expect(uppercase(lowerCase)).toEqual(upperCase);
+    });
+});
diff --git a/print/core/filters/uppercase.js b/print/core/filters/uppercase.js
index a4a8260704..806b996f2e 100644
--- a/print/core/filters/uppercase.js
+++ b/print/core/filters/uppercase.js
@@ -1,5 +1,9 @@
 const Vue = require('vue');
 
-Vue.filter('uppercase', function(value) {
+const uppercase = function(value) {
     return value.toUpperCase();
-});
+};
+
+Vue.filter('uppercase', uppercase);
+
+module.exports = uppercase;

From c9ed17d981defac7e36080ef64c1135d6d59e5e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 13 Aug 2020 12:16:25 +0200
Subject: [PATCH 012/109] Changes to dowload item photos endpoint

---
 .../item-image-queue/downloadImages.js        | 46 +++++++++++++------
 .../item/back/models/item-image-queue.json    |  4 ++
 2 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index 372648dd6c..c7054b3400 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -20,9 +20,8 @@ module.exports = Self => {
         const models = Self.app.models;
 
         try {
-            const imageQueue = await Self.find({limit: 25});
-            const rootPath = models.Image.getPath();
-            const tempPath = path.join(rootPath, 'temp');
+            const imageQueue = await Self.find({where: {error: null}});
+            const tempPath = path.join('/temp/salix-image');
 
             // Create temporary path
             await fs.mkdir(tempPath, {recursive: true});
@@ -33,24 +32,43 @@ module.exports = Self => {
                 const file = fs.createWriteStream(filePath);
 
                 https.get(image.url, async response => {
+                    if (response.statusCode != 200) {
+                        const error = new Error(`Could not download the image. Status code ${response.statusCode}`);
+
+                        file.close();
+                        await errorHandler(image.itemFk, error, filePath);
+                    }
+
                     response.pipe(file);
-                });
 
-                file.on('finish', async function() {
-                    await models.Image.registerImage('catalog', fileName, filePath);
-                    await image.destroy();
-                });
+                    file.on('error', async error => {
+                        await errorHandler(image.itemFk, error, filePath);
+                    });
 
-                file.on('error', err => {
-                    fs.unlink(filePath);
-
-                    throw err;
+                    file.on('finish', async function() {
+                        try {
+                            await models.Image.registerImage('catalog', fileName, filePath);
+                            await image.destroy();
+                        } catch (error) {
+                            await errorHandler(image.itemFk, error, filePath);
+                        }
+                    });
+                }).on('error', async error => {
+                    await errorHandler(image.itemFk, error, filePath);
                 });
             }
 
             return imageQueue;
-        } catch (e) {
-            throw e;
+        } catch (error) {
+            await errorHandler(image.itemFk, error);
+        }
+
+        async function errorHandler(rowId, error, filePath) {
+            const row = await Self.findById(rowId);
+            await row.updateAttribute('error', error);
+
+            if (filePath)
+                await fs.unlink(filePath);
         }
     };
 };
diff --git a/modules/item/back/models/item-image-queue.json b/modules/item/back/models/item-image-queue.json
index 61cb7b0180..6e248ac96d 100644
--- a/modules/item/back/models/item-image-queue.json
+++ b/modules/item/back/models/item-image-queue.json
@@ -16,6 +16,10 @@
         "url": {
             "type": "String",
             "required": true
+        },
+        "error": {
+            "type": "String",
+            "required": true
         }
     },
     "relations": {

From c0794808f03cd8db22c482fc3d509bf2a9baa2fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 13 Aug 2020 13:09:53 +0200
Subject: [PATCH 013/109] Updated tmp directory

---
 modules/item/back/methods/item-image-queue/downloadImages.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index c7054b3400..2e32a57b8a 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -21,7 +21,7 @@ module.exports = Self => {
 
         try {
             const imageQueue = await Self.find({where: {error: null}});
-            const tempPath = path.join('/temp/salix-image');
+            const tempPath = path.join('/tmp/salix-image');
 
             // Create temporary path
             await fs.mkdir(tempPath, {recursive: true});

From bbf15da16fa893cd603e790e8990d0ef364fea6d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 13 Aug 2020 13:38:52 +0200
Subject: [PATCH 014/109] Changed tmp uri

---
 back/models/image.js                                        | 2 +-
 .../item/back/methods/item-image-queue/downloadImages.js    | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/back/models/image.js b/back/models/image.js
index 079acd2935..8d79d1d5f5 100644
--- a/back/models/image.js
+++ b/back/models/image.js
@@ -4,7 +4,7 @@ const path = require('path');
 
 module.exports = Self => {
     Self.getPath = function() {
-        return '/var/lib/salix/image';
+        return 'C:\\Users\\jsanc\\Desktop\\image';
     };
 
     Self.registerImage = async(collectionName, file, srcFilePath) => {
diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index 2e32a57b8a..ab242fdad0 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -21,7 +21,9 @@ module.exports = Self => {
 
         try {
             const imageQueue = await Self.find({where: {error: null}});
-            const tempPath = path.join('/tmp/salix-image');
+            /* const tempPath = path.join('/tmp/salix-image'); */
+            const rootPath = models.Image.getPath();
+            const tempPath = path.join(rootPath, 'temp');
 
             // Create temporary path
             await fs.mkdir(tempPath, {recursive: true});
@@ -57,8 +59,6 @@ module.exports = Self => {
                     await errorHandler(image.itemFk, error, filePath);
                 });
             }
-
-            return imageQueue;
         } catch (error) {
             await errorHandler(image.itemFk, error);
         }

From 49af185976685a0a8007d51746e374dee459e602 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 13 Aug 2020 13:47:11 +0200
Subject: [PATCH 015/109] updated path

---
 back/models/image.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/back/models/image.js b/back/models/image.js
index 8d79d1d5f5..079acd2935 100644
--- a/back/models/image.js
+++ b/back/models/image.js
@@ -4,7 +4,7 @@ const path = require('path');
 
 module.exports = Self => {
     Self.getPath = function() {
-        return 'C:\\Users\\jsanc\\Desktop\\image';
+        return '/var/lib/salix/image';
     };
 
     Self.registerImage = async(collectionName, file, srcFilePath) => {

From 7a3de746cca84b782e19dfe063d0518b190f7520 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 13 Aug 2020 14:00:40 +0200
Subject: [PATCH 016/109] Added limit

---
 modules/item/back/methods/item-image-queue/downloadImages.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index ab242fdad0..45c1b0bd6f 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -20,7 +20,7 @@ module.exports = Self => {
         const models = Self.app.models;
 
         try {
-            const imageQueue = await Self.find({where: {error: null}});
+            const imageQueue = await Self.find({where: {error: null}, limit: 100});
             /* const tempPath = path.join('/tmp/salix-image'); */
             const rootPath = models.Image.getPath();
             const tempPath = path.join(rootPath, 'temp');

From a10e091b628f5a7eb87c1b0a442542754b6a762a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 13 Aug 2020 16:26:35 +0200
Subject: [PATCH 017/109] Added limit

---
 modules/item/back/methods/item-image-queue/downloadImages.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index 45c1b0bd6f..e27b4516ae 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -20,7 +20,7 @@ module.exports = Self => {
         const models = Self.app.models;
 
         try {
-            const imageQueue = await Self.find({where: {error: null}, limit: 100});
+            const imageQueue = await Self.find({where: {error: null}, limit: 25});
             /* const tempPath = path.join('/tmp/salix-image'); */
             const rootPath = models.Image.getPath();
             const tempPath = path.join(rootPath, 'temp');

From f7089f3806698919a489479f4c75b08e2a0ce39a Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 14 Aug 2020 09:23:23 +0200
Subject: [PATCH 018/109] #2390-calendar_date_filter e2e

---
 e2e/helpers/selectors.js                |  16 +++
 e2e/paths/03-worker/05_calendar.spec.js | 134 ++++++++++++++++++++++++
 2 files changed, 150 insertions(+)
 create mode 100644 e2e/paths/03-worker/05_calendar.spec.js

diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index e1b6b1c65b..9b7e4e2f3e 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -803,6 +803,22 @@ export default {
         navigateBackToIndex: 'vn-worker-descriptor [name="goToModuleIndex"]',
         acceptDeleteDialog: '.vn-confirm.shown button[response="accept"]'
     },
+    workerCalendar: {
+        year: 'vn-worker-calendar vn-autocomplete[ng-model="$ctrl.year"]',
+        totalHolidaysUsed: 'vn-worker-calendar div.totalBox > div',
+        januaryThirtyFirst: 'vn-worker-calendar vn-calendar:nth-child(2) section:nth-child(33) > div',
+        marchTwentyThird: 'vn-worker-calendar vn-calendar:nth-child(4) section:nth-child(29) > div',
+        mayFourth: 'vn-worker-calendar vn-calendar:nth-child(6) section:nth-child(8) > div',
+        mayEighth: 'vn-worker-calendar vn-calendar:nth-child(6) section:nth-child(12) > div',
+        mayTwelfth: 'vn-worker-calendar vn-calendar:nth-child(6) section:nth-child(16) > div',
+        mayThirteenth: 'vn-worker-calendar vn-calendar:nth-child(6) section:nth-child(17) > div',
+        mayFourteenth: 'vn-worker-calendar vn-calendar:nth-child(6) section:nth-child(18) > div',
+        holidays: 'vn-worker-calendar > vn-side-menu div:nth-child(3) > vn-chip:nth-child(1)',
+        absence: 'vn-worker-calendar > vn-side-menu div:nth-child(3) > vn-chip:nth-child(2)',
+        halfHoliday: 'vn-worker-calendar > vn-side-menu div:nth-child(3) > vn-chip:nth-child(3)',
+        furlough: 'vn-worker-calendar > vn-side-menu div:nth-child(3) > vn-chip:nth-child(4)',
+        halfFurlough: 'vn-worker-calendar > vn-side-menu div:nth-child(3) > vn-chip:nth-child(5)',
+    },
     invoiceOutIndex: {
         topbarSearch: 'vn-searchbar',
         searchButton: 'vn-searchbar vn-icon[icon="search"]',
diff --git a/e2e/paths/03-worker/05_calendar.spec.js b/e2e/paths/03-worker/05_calendar.spec.js
new file mode 100644
index 0000000000..a4d22c9fc4
--- /dev/null
+++ b/e2e/paths/03-worker/05_calendar.spec.js
@@ -0,0 +1,134 @@
+import selectors from '../../helpers/selectors.js';
+import getBrowser from '../../helpers/puppeteer';
+
+// #2390-calendar_date_filter e2e
+xdescribe('Worker calendar path', () => {
+    let browser;
+    let page;
+    beforeAll(async() => {
+        browser = await getBrowser();
+        page = browser.page;
+        await page.loginAndModule('hr', 'worker');
+        await page.accessToSearchResult('coolerNick');
+        await page.accessToSection('worker.card.calendar');
+    });
+
+    afterAll(async() => {
+        await browser.close();
+    });
+
+    describe('as hr', () => {
+        it('should check 0 total holidays have been used so far', async() => {
+            const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
+
+            expect(result).toContain(' 0 ');
+        });
+
+        it('should set two days as holidays on the calendar', async() => {
+            await page.waitToClick(selectors.workerCalendar.holidays);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
+
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.absence);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.marchTwentyThird);
+
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.halfHoliday);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.mayFourth);
+
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.furlough);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.mayTwelfth);
+            await page.waitToClick(selectors.workerCalendar.mayThirteenth);
+            await page.waitToClick(selectors.workerCalendar.mayFourteenth);
+
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.halfFurlough);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.mayEighth);
+        });
+
+        it('should check the total holidays used now has 1.5 more days', async() => {
+            const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
+
+            expect(result).toContain(' 1.5 ');
+        });
+    });
+
+    describe(`as cool boss`, () => {
+        it(`should log in and get to cool's calendar`, async() => {
+            await page.loginAndModule('coolerBoss', 'worker');
+            await page.accessToSearchResult('coolerNick');
+            await page.accessToSection('worker.card.calendar');
+        });
+
+        it('should undo what was done here', async() => {
+            await page.waitFor(4000);
+            await page.waitToClick(selectors.workerCalendar.holidays);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
+
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.absence);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.marchTwentyThird);
+
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.halfHoliday);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.mayFourth);
+
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.furlough);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.mayTwelfth);
+            await page.waitToClick(selectors.workerCalendar.mayThirteenth);
+            await page.waitToClick(selectors.workerCalendar.mayFourteenth);
+
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.halfFurlough);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.mayEighth);
+        });
+
+        it('should check the total holidays used are back to what it was', async() => {
+            const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
+
+            expect(result).toContain(' 0 ');
+        });
+    });
+
+    describe(`as cooler`, () => {
+        it(`should log in and get to his calendar`, async() => {
+            await page.loginAndModule('cooler', 'worker');
+            await page.accessToSearchResult('coolerNick');
+            await page.accessToSection('worker.card.calendar');
+        });
+
+        it('should make a futile attempt to add holidays', async() => {
+            await page.waitFor(4000);
+            await page.waitToClick(selectors.workerCalendar.holidays);
+            await page.waitFor(400);
+            await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
+        });
+
+        it('should check the total holidays used remain the same', async() => {
+            const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
+
+            expect(result).toContain(' 0 ');
+        });
+
+        it('should use the year selector yo go to the previous year', async() => {
+            const date = new Date();
+            const lastYear = (date.getFullYear() - 1).toString();
+
+            await page.autocompleteSearch(selectors.workerCalendar.year, lastYear);
+
+            expect(result).toContain(' 0 ');
+        });
+    });
+});

From 69ddf3a615434289ed22720187eee168a1b06946 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 14 Aug 2020 11:57:16 +0200
Subject: [PATCH 019/109] e2e path nearly as completed

---
 e2e/paths/03-worker/05_calendar.spec.js | 53 +++++++++++++------------
 1 file changed, 28 insertions(+), 25 deletions(-)

diff --git a/e2e/paths/03-worker/05_calendar.spec.js b/e2e/paths/03-worker/05_calendar.spec.js
index a4d22c9fc4..9a1998c07d 100644
--- a/e2e/paths/03-worker/05_calendar.spec.js
+++ b/e2e/paths/03-worker/05_calendar.spec.js
@@ -1,15 +1,14 @@
 import selectors from '../../helpers/selectors.js';
 import getBrowser from '../../helpers/puppeteer';
 
-// #2390-calendar_date_filter e2e
-xdescribe('Worker calendar path', () => {
+fdescribe('Worker calendar path', () => {
     let browser;
     let page;
     beforeAll(async() => {
         browser = await getBrowser();
         page = browser.page;
         await page.loginAndModule('hr', 'worker');
-        await page.accessToSearchResult('coolerNick');
+        await page.accessToSearchResult('Hank Pym');
         await page.accessToSection('worker.card.calendar');
     });
 
@@ -18,10 +17,10 @@ xdescribe('Worker calendar path', () => {
     });
 
     describe('as hr', () => {
-        it('should check 0 total holidays have been used so far', async() => {
+        it('should check 5 total holidays have been used so far before testing anything', async() => {
             const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
 
-            expect(result).toContain(' 0 ');
+            expect(result).toContain(' 5 ');
         });
 
         it('should set two days as holidays on the calendar', async() => {
@@ -52,22 +51,22 @@ xdescribe('Worker calendar path', () => {
             await page.waitToClick(selectors.workerCalendar.mayEighth);
         });
 
-        it('should check the total holidays used now has 1.5 more days', async() => {
+        it('should check the total holidays increased by 1.5', async() => {
             const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
 
-            expect(result).toContain(' 1.5 ');
+            expect(result).toContain(' 6.5 ');
         });
     });
 
-    describe(`as cool boss`, () => {
-        it(`should log in and get to cool's calendar`, async() => {
-            await page.loginAndModule('coolerBoss', 'worker');
-            await page.accessToSearchResult('coolerNick');
+    describe(`as salesBoss`, () => {
+        it(`should log in and get to Hank's calendar`, async() => {
+            await page.loginAndModule('salesBoss', 'worker');
+            await page.accessToSearchResult('Hank Pym');
             await page.accessToSection('worker.card.calendar');
         });
 
         it('should undo what was done here', async() => {
-            await page.waitFor(4000);
+            await page.waitFor(400);
             await page.waitToClick(selectors.workerCalendar.holidays);
             await page.waitFor(400);
             await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
@@ -98,37 +97,41 @@ xdescribe('Worker calendar path', () => {
         it('should check the total holidays used are back to what it was', async() => {
             const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
 
-            expect(result).toContain(' 0 ');
+            expect(result).toContain(' 5 ');
         });
     });
 
-    describe(`as cooler`, () => {
+    describe(`as Hank`, () => {
         it(`should log in and get to his calendar`, async() => {
-            await page.loginAndModule('cooler', 'worker');
-            await page.accessToSearchResult('coolerNick');
+            await page.loginAndModule('HankPym', 'worker');
+            await page.accessToSearchResult('Hank Pym');
             await page.accessToSection('worker.card.calendar');
         });
 
         it('should make a futile attempt to add holidays', async() => {
-            await page.waitFor(4000);
+            await page.waitFor(400);
             await page.waitToClick(selectors.workerCalendar.holidays);
             await page.waitFor(400);
             await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
         });
 
-        it('should check the total holidays used remain the same', async() => {
+        it('should check the total holidays used are now the initial ones', async() => {
             const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
 
-            expect(result).toContain(' 0 ');
+            expect(result).toContain(' 5 ');
         });
 
-        it('should use the year selector yo go to the previous year', async() => {
-            const date = new Date();
-            const lastYear = (date.getFullYear() - 1).toString();
+        // #1361 worker.calendar "hopefully this test works straight away after refreshing holidays per year on each filtering."
+        // it('should use the year selector to go to the previous year', async() => {
+        //     const date = new Date();
+        //     const lastYear = (date.getFullYear() - 1).toString();
 
-            await page.autocompleteSearch(selectors.workerCalendar.year, lastYear);
+        //     await page.autocompleteSearch(selectors.workerCalendar.year, lastYear);
 
-            expect(result).toContain(' 0 ');
-        });
+        //     await page.waitFor(400);
+        //     const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
+
+        //     expect(result).toContain(' 0 ');
+        // });
     });
 });

From caf5ad7a6331f9825fc3ee8607ecb592cf246b12 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 14 Aug 2020 11:57:53 +0200
Subject: [PATCH 020/109] the fdescribe wasn't needed at all XD

---
 e2e/paths/03-worker/05_calendar.spec.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/e2e/paths/03-worker/05_calendar.spec.js b/e2e/paths/03-worker/05_calendar.spec.js
index 9a1998c07d..f3cb87ff53 100644
--- a/e2e/paths/03-worker/05_calendar.spec.js
+++ b/e2e/paths/03-worker/05_calendar.spec.js
@@ -1,7 +1,7 @@
 import selectors from '../../helpers/selectors.js';
 import getBrowser from '../../helpers/puppeteer';
 
-fdescribe('Worker calendar path', () => {
+describe('Worker calendar path', () => {
     let browser;
     let page;
     beforeAll(async() => {

From 3cfca5690f10fc459e20b2ec7c964413ba662c60 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 14 Aug 2020 12:02:27 +0200
Subject: [PATCH 021/109] minor refactor

---
 e2e/paths/03-worker/05_calendar.spec.js | 45 +++++++++++++------------
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/e2e/paths/03-worker/05_calendar.spec.js b/e2e/paths/03-worker/05_calendar.spec.js
index f3cb87ff53..8f3ab4ba36 100644
--- a/e2e/paths/03-worker/05_calendar.spec.js
+++ b/e2e/paths/03-worker/05_calendar.spec.js
@@ -2,6 +2,7 @@ import selectors from '../../helpers/selectors.js';
 import getBrowser from '../../helpers/puppeteer';
 
 describe('Worker calendar path', () => {
+    let reasonableTimeBetweenClicks = 400;
     let browser;
     let page;
     beforeAll(async() => {
@@ -25,29 +26,29 @@ describe('Worker calendar path', () => {
 
         it('should set two days as holidays on the calendar', async() => {
             await page.waitToClick(selectors.workerCalendar.holidays);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
 
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.absence);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.marchTwentyThird);
 
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.halfHoliday);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.mayFourth);
 
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.furlough);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.mayTwelfth);
             await page.waitToClick(selectors.workerCalendar.mayThirteenth);
             await page.waitToClick(selectors.workerCalendar.mayFourteenth);
 
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.halfFurlough);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.mayEighth);
         });
 
@@ -66,31 +67,31 @@ describe('Worker calendar path', () => {
         });
 
         it('should undo what was done here', async() => {
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.holidays);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
 
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.absence);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.marchTwentyThird);
 
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.halfHoliday);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.mayFourth);
 
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.furlough);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.mayTwelfth);
             await page.waitToClick(selectors.workerCalendar.mayThirteenth);
             await page.waitToClick(selectors.workerCalendar.mayFourteenth);
 
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.halfFurlough);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.mayEighth);
         });
 
@@ -109,9 +110,9 @@ describe('Worker calendar path', () => {
         });
 
         it('should make a futile attempt to add holidays', async() => {
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.holidays);
-            await page.waitFor(400);
+            await page.waitFor(reasonableTimeBetweenClicks);
             await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
         });
 
@@ -128,7 +129,7 @@ describe('Worker calendar path', () => {
 
         //     await page.autocompleteSearch(selectors.workerCalendar.year, lastYear);
 
-        //     await page.waitFor(400);
+        //     await page.waitFor(reasonableTimeBetweenClicks);
         //     const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
 
         //     expect(result).toContain(' 0 ');

From 3a723a2e3d6d5248734d285f67060cacb383f0be Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 14 Aug 2020 15:35:50 +0200
Subject: [PATCH 022/109] zone descriptor e2e

---
 db/dump/fixtures.sql                    |  2 +-
 e2e/helpers/selectors.js                |  8 +++++++
 e2e/paths/11-zone/02_descriptor.spec.js | 31 ++++++++++++++++---------
 3 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 2e4384b40f..ccc1b7d1d6 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -560,7 +560,7 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF
         (16, 1,     7,  1, 6,       CURDATE(),                              DATE_ADD(CURDATE(), INTERVAL + 1 DAY),                            106, 'Many Places',           126, NULL,       0, 3,  CURDATE()),
         (17, 1,     7,  2, 6,       CURDATE(),                              DATE_ADD(CURDATE(), INTERVAL + 1 DAY),                            106, 'Many Places',           126, NULL,       0, 3,  CURDATE()),
         (18, 1,     4,  4, 4,       CURDATE(),                              DATE_ADD(CURDATE(), INTERVAL + 1 DAY),                            108, 'Cerebro',               128, NULL,       0, 12, CURDATE()),
-        (19, 1,     5,  5, 3,       CURDATE(),                              DATE_ADD(CURDATE(), INTERVAL + 1 DAY),                            109, 'Somewhere in Thailand', 129, NULL,       1, 13, CURDATE()),
+        (19, 1,     5,  5, NULL,       CURDATE(),                              DATE_ADD(CURDATE(), INTERVAL + 1 DAY),                            109, 'Somewhere in Thailand', 129, NULL,       1, 13, CURDATE()),
         (20, 1,     5,  5, 3,       DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Thailand', 129, NULL,       0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
         (21, NULL,  5,  5, 5,       DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Holland',  102, NULL,       0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
         (22, NULL,  5,  5, 5,       DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Japan',    103, NULL,       0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index e1b6b1c65b..93755d724b 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -544,6 +544,7 @@ export default {
         logButton: 'vn-left-menu a[ui-sref="ticket.card.log"]',
         changedBy: 'vn-ticket-log > vn-log vn-tr:nth-child(1) > vn-td:nth-child(2) > span',
         actionTaken: 'vn-ticket-log > vn-log vn-td:nth-child(1) > div > div:nth-child(3) > span.value',
+        changes: 'vn-ticket-log vn-data-viewer vn-tbody > vn-tr > vn-td:nth-child(7)',
         id: 'vn-ticket-log > vn-log vn-td.before > vn-one:nth-child(1) > div > span.value'
     },
     ticketService: {
@@ -852,6 +853,13 @@ export default {
         createdThermograph: 'vn-travel-thermograph-index vn-tbody > vn-tr',
         upload: 'vn-travel-thermograph-create button[type=submit]'
     },
+    zoneIndex: {
+        searchResult: 'vn-zone-index a.vn-tr',
+    },
+    zoneDescriptor: {
+        menu: 'vn-zone-descriptor vn-icon-button[vn-popover="menu"]',
+        deleteZone: 'slot-menu vn-item[ng-click="$ctrl.onDelete()"]'
+    },
     zoneBasicData: {
         name: 'vn-zone-basic-data vn-textfield[ng-model="$ctrl.zone.name"]',
         agency: 'vn-zone-basic-data vn-autocomplete[ng-model="$ctrl.zone.agencyModeFk"]',
diff --git a/e2e/paths/11-zone/02_descriptor.spec.js b/e2e/paths/11-zone/02_descriptor.spec.js
index fab9b308b0..1de84d601a 100644
--- a/e2e/paths/11-zone/02_descriptor.spec.js
+++ b/e2e/paths/11-zone/02_descriptor.spec.js
@@ -9,25 +9,34 @@ describe('Zone descriptor path', () => {
         browser = await getBrowser();
         page = browser.page;
         await page.loginAndModule('deliveryBoss', 'zone');
-        await page.accessToSearchResult('10');
-        await page.accessToSection('zone.card.basicData');
+        await page.accessToSearchResult('13');
     });
 
     afterAll(async() => {
         await browser.close();
     });
 
-    it('should reach the basic data section', async() => {
-        await page.waitForState('zone.card.basicData');
+    it('should eliminate the zone using the descriptor option', async() => {
+        await page.waitToClick(selectors.zoneDescriptor.menu);
+        await page.waitToClick(selectors.zoneDescriptor.deleteZone);
+        await page.respondToDialog('accept');
+        await page.waitForState('zone.index');
     });
 
-    it('should edit de form and then save', async() => {
-        await page.clearInput(selectors.zoneBasicData.name);
-        await page.write(selectors.zoneBasicData.name, 'Brimstone teleportation');
-        await page.autocompleteSearch(selectors.zoneBasicData.agency, 'Quantum break device');
-        await page.write(selectors.zoneBasicData.maxVolume, '10');
-        const message = await page.waitForSnackbar();
+    it('should search for the deleted zone to find no results', async() => {
+        await page.doSearch('13');
+        const count = await page.countElement(selectors.zoneIndex.searchResult);
 
-        expect(message.type).toBe('success');
+        expect(count).toEqual(0);
+    });
+
+    it('should check the ticket whom lost the zone and see evidence on the logs', async() => {
+        await page.waitToClick(selectors.globalItems.homeButton);
+        await page.selectModule('ticket');
+        await page.accessToSearchResult('20');
+        await page.accessToSection('ticket.card.log');
+        const lastChanges = await page.waitToGetProperty(selectors.ticketLog.changes, 'innerText');
+
+        expect(lastChanges).toContain('Arreglar');
     });
 });

From 3df9ae2946a30af9a67926baa5b197c3c0258924 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 14 Aug 2020 17:10:59 +0200
Subject: [PATCH 023/109] section no longer nukes salesPerson-user relation

---
 modules/claim/back/methods/claim/updateClaim.js | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js
index 61b8085d3f..91cc2fe1b8 100644
--- a/modules/claim/back/methods/claim/updateClaim.js
+++ b/modules/claim/back/methods/claim/updateClaim.js
@@ -36,7 +36,16 @@ module.exports = Self => {
                 relation: 'client',
                 scope: {
                     include: {
-                        relation: 'salesPerson'
+                        relation: 'salesPerson',
+                        scope: {
+                            fields: ['userFk'],
+                            include: {
+                                relation: 'user',
+                                scope: {
+                                    fields: ['nickname']
+                                }
+                            }
+                        }
                     }
                 }
             }

From b711728999cbb9c749143c9c5f4ccd57f8fd4cc1 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 14 Aug 2020 17:47:13 +0200
Subject: [PATCH 024/109] ultimate edition deluxe

---
 modules/claim/back/methods/claim/updateClaim.js | 11 +----------
 modules/claim/front/card/index.js               | 12 +-----------
 modules/claim/front/descriptor/index.html       |  4 ++--
 3 files changed, 4 insertions(+), 23 deletions(-)

diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js
index 91cc2fe1b8..d4931341f0 100644
--- a/modules/claim/back/methods/claim/updateClaim.js
+++ b/modules/claim/back/methods/claim/updateClaim.js
@@ -36,16 +36,7 @@ module.exports = Self => {
                 relation: 'client',
                 scope: {
                     include: {
-                        relation: 'salesPerson',
-                        scope: {
-                            fields: ['userFk'],
-                            include: {
-                                relation: 'user',
-                                scope: {
-                                    fields: ['nickname']
-                                }
-                            }
-                        }
+                        relation: 'salesPersonUser'
                     }
                 }
             }
diff --git a/modules/claim/front/card/index.js b/modules/claim/front/card/index.js
index ccd78a271d..361b0e74f2 100644
--- a/modules/claim/front/card/index.js
+++ b/modules/claim/front/card/index.js
@@ -34,17 +34,7 @@ class Controller extends ModuleCard {
                     scope: {
                         fields: ['salesPersonFk', 'name', 'email'],
                         include: {
-                            relation: 'salesPerson',
-                            scope: {
-                                fields: ['userFk'],
-                                include: {
-                                    relation: 'user',
-                                    scope: {
-                                        fields: ['nickname']
-                                    }
-                                }
-                            }
-
+                            relation: 'salesPersonUser'
                         }
                     }
                 }
diff --git a/modules/claim/front/descriptor/index.html b/modules/claim/front/descriptor/index.html
index dcd1032470..627537348a 100644
--- a/modules/claim/front/descriptor/index.html
+++ b/modules/claim/front/descriptor/index.html
@@ -33,7 +33,7 @@
             </vn-label-value>
             <vn-label-value
                 label="Salesperson" 
-                value="{{$ctrl.claim.client.salesPerson.user.nickname}}">
+                value="{{$ctrl.claim.client.salesPersonUser.nickname}}">
             </vn-label-value>
             <vn-label-value
                 label="Attended by" 
@@ -78,4 +78,4 @@
     on-accept="$ctrl.deleteClaim()"
     question="Delete claim"
     message="Are you sure you want to delete this claim?">
-</vn-confirm>
+</vn-confirm>
\ No newline at end of file

From 8141815fe1a4a04ecb979f3d0aad116107f1e98e Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 14 Aug 2020 18:20:54 +0200
Subject: [PATCH 025/109] upgraded babel preset env due to a deprecation

---
 package-lock.json | 2588 ++++++++++++++++++++++++++++++---------------
 package.json      |    2 +-
 2 files changed, 1729 insertions(+), 861 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 92030199ae..74e75f4580 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,17 @@
                 "@babel/highlight": "^7.0.0"
             }
         },
+        "@babel/compat-data": {
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz",
+            "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==",
+            "dev": true,
+            "requires": {
+                "browserslist": "^4.12.0",
+                "invariant": "^2.2.4",
+                "semver": "^5.5.0"
+            }
+        },
         "@babel/core": {
             "version": "7.7.7",
             "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.7.tgz",
@@ -178,346 +189,390 @@
             }
         },
         "@babel/helper-annotate-as-pure": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz",
-            "integrity": "sha512-2BQmQgECKzYKFPpiycoF9tlb5HA4lrVyAmLLVK177EcQAqjVLciUb2/R+n1boQ9y5ENV3uz2ZqiNw7QMBBw1Og==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz",
+            "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==",
             "dev": true,
             "requires": {
-                "@babel/types": "^7.7.4"
+                "@babel/types": "^7.10.4"
             },
             "dependencies": {
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
         "@babel/helper-builder-binary-assignment-operator-visitor": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz",
-            "integrity": "sha512-Biq/d/WtvfftWZ9Uf39hbPBYDUo986m5Bb4zhkeYDGUllF43D+nUe5M6Vuo6/8JDK/0YX/uBdeoQpyaNhNugZQ==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz",
+            "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==",
             "dev": true,
             "requires": {
-                "@babel/helper-explode-assignable-expression": "^7.7.4",
-                "@babel/types": "^7.7.4"
+                "@babel/helper-explode-assignable-expression": "^7.10.4",
+                "@babel/types": "^7.10.4"
             },
             "dependencies": {
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
-        "@babel/helper-call-delegate": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.4.tgz",
-            "integrity": "sha512-8JH9/B7J7tCYJ2PpWVpw9JhPuEVHztagNVuQAFBVFYluRMlpG7F1CgKEgGeL6KFqcsIa92ZYVj6DSc0XwmN1ZA==",
+        "@babel/helper-compilation-targets": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz",
+            "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==",
             "dev": true,
             "requires": {
-                "@babel/helper-hoist-variables": "^7.7.4",
-                "@babel/traverse": "^7.7.4",
-                "@babel/types": "^7.7.4"
+                "@babel/compat-data": "^7.10.4",
+                "browserslist": "^4.12.0",
+                "invariant": "^2.2.4",
+                "levenary": "^1.1.1",
+                "semver": "^5.5.0"
+            }
+        },
+        "@babel/helper-create-class-features-plugin": {
+            "version": "7.10.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz",
+            "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-function-name": "^7.10.4",
+                "@babel/helper-member-expression-to-functions": "^7.10.5",
+                "@babel/helper-optimise-call-expression": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/helper-replace-supers": "^7.10.4",
+                "@babel/helper-split-export-declaration": "^7.10.4"
             },
             "dependencies": {
                 "@babel/code-frame": {
-                    "version": "7.5.5",
-                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
-                    "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+                    "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
                     "dev": true,
                     "requires": {
-                        "@babel/highlight": "^7.0.0"
-                    }
-                },
-                "@babel/generator": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz",
-                    "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==",
-                    "dev": true,
-                    "requires": {
-                        "@babel/types": "^7.7.4",
-                        "jsesc": "^2.5.1",
-                        "lodash": "^4.17.13",
-                        "source-map": "^0.5.0"
+                        "@babel/highlight": "^7.10.4"
                     }
                 },
                 "@babel/helper-function-name": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
-                    "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+                    "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
                     "dev": true,
                     "requires": {
-                        "@babel/helper-get-function-arity": "^7.7.4",
-                        "@babel/template": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/helper-get-function-arity": "^7.10.4",
+                        "@babel/template": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-get-function-arity": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
-                    "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+                    "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.10.4"
                     }
                 },
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                },
                 "@babel/helper-split-export-declaration": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz",
-                    "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+                    "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.11.0"
+                    }
+                },
+                "@babel/highlight": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+                    "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "chalk": "^2.0.0",
+                        "js-tokens": "^4.0.0"
                     }
                 },
                 "@babel/parser": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz",
-                    "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==",
+                    "version": "7.11.3",
+                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
+                    "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
                     "dev": true
                 },
                 "@babel/template": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
-                    "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+                    "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.0.0",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4"
-                    }
-                },
-                "@babel/traverse": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz",
-                    "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==",
-                    "dev": true,
-                    "requires": {
-                        "@babel/code-frame": "^7.5.5",
-                        "@babel/generator": "^7.7.4",
-                        "@babel/helper-function-name": "^7.7.4",
-                        "@babel/helper-split-export-declaration": "^7.7.4",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4",
-                        "debug": "^4.1.0",
-                        "globals": "^11.1.0",
-                        "lodash": "^4.17.13"
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/parser": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
                 },
-                "debug": {
-                    "version": "4.1.1",
-                    "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
-                    "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
-                    "dev": true,
-                    "requires": {
-                        "ms": "^2.1.1"
-                    }
-                },
-                "ms": {
-                    "version": "2.1.2",
-                    "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-                    "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
                     "dev": true
                 }
             }
         },
         "@babel/helper-create-regexp-features-plugin": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz",
-            "integrity": "sha512-Mt+jBKaxL0zfOIWrfQpnfYCN7/rS6GKx6CCCfuoqVVd+17R8zNDlzVYmIi9qyb2wOk002NsmSTDymkIygDUH7A==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz",
+            "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==",
             "dev": true,
             "requires": {
-                "@babel/helper-regex": "^7.4.4",
-                "regexpu-core": "^4.6.0"
+                "@babel/helper-annotate-as-pure": "^7.10.4",
+                "@babel/helper-regex": "^7.10.4",
+                "regexpu-core": "^4.7.0"
             }
         },
         "@babel/helper-define-map": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.4.tgz",
-            "integrity": "sha512-v5LorqOa0nVQUvAUTUF3KPastvUt/HzByXNamKQ6RdJRTV7j8rLL+WB5C/MzzWAwOomxDhYFb1wLLxHqox86lg==",
+            "version": "7.10.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz",
+            "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==",
             "dev": true,
             "requires": {
-                "@babel/helper-function-name": "^7.7.4",
-                "@babel/types": "^7.7.4",
-                "lodash": "^4.17.13"
+                "@babel/helper-function-name": "^7.10.4",
+                "@babel/types": "^7.10.5",
+                "lodash": "^4.17.19"
             },
             "dependencies": {
-                "@babel/helper-function-name": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
-                    "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
+                "@babel/code-frame": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+                    "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
                     "dev": true,
                     "requires": {
-                        "@babel/helper-get-function-arity": "^7.7.4",
-                        "@babel/template": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/highlight": "^7.10.4"
+                    }
+                },
+                "@babel/helper-function-name": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+                    "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-get-function-arity": "^7.10.4",
+                        "@babel/template": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-get-function-arity": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
-                    "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+                    "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.10.4"
+                    }
+                },
+                "@babel/highlight": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+                    "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "chalk": "^2.0.0",
+                        "js-tokens": "^4.0.0"
                     }
                 },
                 "@babel/parser": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz",
-                    "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==",
+                    "version": "7.11.3",
+                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
+                    "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
                     "dev": true
                 },
                 "@babel/template": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
-                    "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+                    "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.0.0",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/parser": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
         "@babel/helper-explode-assignable-expression": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz",
-            "integrity": "sha512-2/SicuFrNSXsZNBxe5UGdLr+HZg+raWBLE9vC98bdYOKX/U6PY0mdGlYUJdtTDPSU0Lw0PNbKKDpwYHJLn2jLg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz",
+            "integrity": "sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A==",
             "dev": true,
             "requires": {
-                "@babel/traverse": "^7.7.4",
-                "@babel/types": "^7.7.4"
+                "@babel/traverse": "^7.10.4",
+                "@babel/types": "^7.10.4"
             },
             "dependencies": {
                 "@babel/code-frame": {
-                    "version": "7.5.5",
-                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
-                    "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+                    "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
                     "dev": true,
                     "requires": {
-                        "@babel/highlight": "^7.0.0"
+                        "@babel/highlight": "^7.10.4"
                     }
                 },
                 "@babel/generator": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz",
-                    "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz",
+                    "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4",
+                        "@babel/types": "^7.11.0",
                         "jsesc": "^2.5.1",
-                        "lodash": "^4.17.13",
                         "source-map": "^0.5.0"
                     }
                 },
                 "@babel/helper-function-name": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
-                    "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+                    "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
                     "dev": true,
                     "requires": {
-                        "@babel/helper-get-function-arity": "^7.7.4",
-                        "@babel/template": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/helper-get-function-arity": "^7.10.4",
+                        "@babel/template": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-get-function-arity": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
-                    "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+                    "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-split-export-declaration": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz",
-                    "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+                    "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.11.0"
+                    }
+                },
+                "@babel/highlight": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+                    "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "chalk": "^2.0.0",
+                        "js-tokens": "^4.0.0"
                     }
                 },
                 "@babel/parser": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz",
-                    "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==",
+                    "version": "7.11.3",
+                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
+                    "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
                     "dev": true
                 },
                 "@babel/template": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
-                    "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+                    "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.0.0",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/parser": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/traverse": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz",
-                    "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz",
+                    "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.5.5",
-                        "@babel/generator": "^7.7.4",
-                        "@babel/helper-function-name": "^7.7.4",
-                        "@babel/helper-split-export-declaration": "^7.7.4",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4",
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/generator": "^7.11.0",
+                        "@babel/helper-function-name": "^7.10.4",
+                        "@babel/helper-split-export-declaration": "^7.11.0",
+                        "@babel/parser": "^7.11.0",
+                        "@babel/types": "^7.11.0",
                         "debug": "^4.1.0",
                         "globals": "^11.1.0",
-                        "lodash": "^4.17.13"
+                        "lodash": "^4.17.19"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
                 },
@@ -530,6 +585,12 @@
                         "ms": "^2.1.1"
                     }
                 },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
+                },
                 "ms": {
                     "version": "2.1.2",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -559,143 +620,194 @@
             }
         },
         "@babel/helper-hoist-variables": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz",
-            "integrity": "sha512-wQC4xyvc1Jo/FnLirL6CEgPgPCa8M74tOdjWpRhQYapz5JC7u3NYU1zCVoVAGCE3EaIP9T1A3iW0WLJ+reZlpQ==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz",
+            "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==",
             "dev": true,
             "requires": {
-                "@babel/types": "^7.7.4"
+                "@babel/types": "^7.10.4"
             },
             "dependencies": {
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
         "@babel/helper-member-expression-to-functions": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz",
-            "integrity": "sha512-9KcA1X2E3OjXl/ykfMMInBK+uVdfIVakVe7W7Lg3wfXUNyS3Q1HWLFRwZIjhqiCGbslummPDnmb7vIekS0C1vw==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz",
+            "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==",
             "dev": true,
             "requires": {
-                "@babel/types": "^7.7.4"
+                "@babel/types": "^7.11.0"
             },
             "dependencies": {
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
         "@babel/helper-module-imports": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz",
-            "integrity": "sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz",
+            "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==",
             "dev": true,
             "requires": {
-                "@babel/types": "^7.7.4"
+                "@babel/types": "^7.10.4"
             },
             "dependencies": {
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
         "@babel/helper-module-transforms": {
-            "version": "7.7.5",
-            "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz",
-            "integrity": "sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz",
+            "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==",
             "dev": true,
             "requires": {
-                "@babel/helper-module-imports": "^7.7.4",
-                "@babel/helper-simple-access": "^7.7.4",
-                "@babel/helper-split-export-declaration": "^7.7.4",
-                "@babel/template": "^7.7.4",
-                "@babel/types": "^7.7.4",
-                "lodash": "^4.17.13"
+                "@babel/helper-module-imports": "^7.10.4",
+                "@babel/helper-replace-supers": "^7.10.4",
+                "@babel/helper-simple-access": "^7.10.4",
+                "@babel/helper-split-export-declaration": "^7.11.0",
+                "@babel/template": "^7.10.4",
+                "@babel/types": "^7.11.0",
+                "lodash": "^4.17.19"
             },
             "dependencies": {
-                "@babel/helper-split-export-declaration": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz",
-                    "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==",
+                "@babel/code-frame": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+                    "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/highlight": "^7.10.4"
+                    }
+                },
+                "@babel/helper-split-export-declaration": {
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+                    "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/types": "^7.11.0"
+                    }
+                },
+                "@babel/highlight": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+                    "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "chalk": "^2.0.0",
+                        "js-tokens": "^4.0.0"
                     }
                 },
                 "@babel/parser": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz",
-                    "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==",
+                    "version": "7.11.3",
+                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
+                    "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
                     "dev": true
                 },
                 "@babel/template": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
-                    "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+                    "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.0.0",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/parser": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
         "@babel/helper-optimise-call-expression": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz",
-            "integrity": "sha512-VB7gWZ2fDkSuqW6b1AKXkJWO5NyNI3bFL/kK79/30moK57blr6NbH8xcl2XcKCwOmJosftWunZqfO84IGq3ZZg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz",
+            "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==",
             "dev": true,
             "requires": {
-                "@babel/types": "^7.7.4"
+                "@babel/types": "^7.10.4"
             },
             "dependencies": {
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
@@ -706,121 +818,137 @@
             "dev": true
         },
         "@babel/helper-regex": {
-            "version": "7.5.5",
-            "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz",
-            "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==",
+            "version": "7.10.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.5.tgz",
+            "integrity": "sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==",
             "dev": true,
             "requires": {
-                "lodash": "^4.17.13"
+                "lodash": "^4.17.19"
+            },
+            "dependencies": {
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
+                }
             }
         },
         "@babel/helper-remap-async-to-generator": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz",
-            "integrity": "sha512-Sk4xmtVdM9sA/jCI80f+KS+Md+ZHIpjuqmYPk1M7F/upHou5e4ReYmExAiu6PVe65BhJPZA2CY9x9k4BqE5klw==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz",
+            "integrity": "sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg==",
             "dev": true,
             "requires": {
-                "@babel/helper-annotate-as-pure": "^7.7.4",
-                "@babel/helper-wrap-function": "^7.7.4",
-                "@babel/template": "^7.7.4",
-                "@babel/traverse": "^7.7.4",
-                "@babel/types": "^7.7.4"
+                "@babel/helper-annotate-as-pure": "^7.10.4",
+                "@babel/helper-wrap-function": "^7.10.4",
+                "@babel/template": "^7.10.4",
+                "@babel/traverse": "^7.10.4",
+                "@babel/types": "^7.10.4"
             },
             "dependencies": {
-                "@babel/generator": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz",
-                    "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==",
+                "@babel/code-frame": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+                    "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4",
+                        "@babel/highlight": "^7.10.4"
+                    }
+                },
+                "@babel/generator": {
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz",
+                    "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/types": "^7.11.0",
                         "jsesc": "^2.5.1",
-                        "lodash": "^4.17.13",
                         "source-map": "^0.5.0"
                     }
                 },
                 "@babel/helper-function-name": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
-                    "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+                    "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
                     "dev": true,
                     "requires": {
-                        "@babel/helper-get-function-arity": "^7.7.4",
-                        "@babel/template": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/helper-get-function-arity": "^7.10.4",
+                        "@babel/template": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-get-function-arity": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
-                    "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+                    "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-split-export-declaration": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz",
-                    "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+                    "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.11.0"
+                    }
+                },
+                "@babel/highlight": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+                    "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "chalk": "^2.0.0",
+                        "js-tokens": "^4.0.0"
                     }
                 },
                 "@babel/parser": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz",
-                    "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==",
+                    "version": "7.11.3",
+                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
+                    "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
                     "dev": true
                 },
                 "@babel/template": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
-                    "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+                    "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.0.0",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/parser": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/traverse": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz",
-                    "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz",
+                    "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.5.5",
-                        "@babel/generator": "^7.7.4",
-                        "@babel/helper-function-name": "^7.7.4",
-                        "@babel/helper-split-export-declaration": "^7.7.4",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4",
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/generator": "^7.11.0",
+                        "@babel/helper-function-name": "^7.10.4",
+                        "@babel/helper-split-export-declaration": "^7.11.0",
+                        "@babel/parser": "^7.11.0",
+                        "@babel/types": "^7.11.0",
                         "debug": "^4.1.0",
                         "globals": "^11.1.0",
-                        "lodash": "^4.17.13"
-                    },
-                    "dependencies": {
-                        "@babel/code-frame": {
-                            "version": "7.5.5",
-                            "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
-                            "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
-                            "dev": true,
-                            "requires": {
-                                "@babel/highlight": "^7.0.0"
-                            }
-                        }
+                        "lodash": "^4.17.19"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
                 },
@@ -833,6 +961,12 @@
                         "ms": "^2.1.1"
                     }
                 },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
+                },
                 "ms": {
                     "version": "2.1.2",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -842,109 +976,119 @@
             }
         },
         "@babel/helper-replace-supers": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz",
-            "integrity": "sha512-pP0tfgg9hsZWo5ZboYGuBn/bbYT/hdLPVSS4NMmiRJdwWhP0IznPwN9AE1JwyGsjSPLC364I0Qh5p+EPkGPNpg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz",
+            "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==",
             "dev": true,
             "requires": {
-                "@babel/helper-member-expression-to-functions": "^7.7.4",
-                "@babel/helper-optimise-call-expression": "^7.7.4",
-                "@babel/traverse": "^7.7.4",
-                "@babel/types": "^7.7.4"
+                "@babel/helper-member-expression-to-functions": "^7.10.4",
+                "@babel/helper-optimise-call-expression": "^7.10.4",
+                "@babel/traverse": "^7.10.4",
+                "@babel/types": "^7.10.4"
             },
             "dependencies": {
                 "@babel/code-frame": {
-                    "version": "7.5.5",
-                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
-                    "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+                    "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
                     "dev": true,
                     "requires": {
-                        "@babel/highlight": "^7.0.0"
+                        "@babel/highlight": "^7.10.4"
                     }
                 },
                 "@babel/generator": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz",
-                    "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz",
+                    "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4",
+                        "@babel/types": "^7.11.0",
                         "jsesc": "^2.5.1",
-                        "lodash": "^4.17.13",
                         "source-map": "^0.5.0"
                     }
                 },
                 "@babel/helper-function-name": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
-                    "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+                    "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
                     "dev": true,
                     "requires": {
-                        "@babel/helper-get-function-arity": "^7.7.4",
-                        "@babel/template": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/helper-get-function-arity": "^7.10.4",
+                        "@babel/template": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-get-function-arity": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
-                    "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+                    "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-split-export-declaration": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz",
-                    "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+                    "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.11.0"
+                    }
+                },
+                "@babel/highlight": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+                    "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "chalk": "^2.0.0",
+                        "js-tokens": "^4.0.0"
                     }
                 },
                 "@babel/parser": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz",
-                    "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==",
+                    "version": "7.11.3",
+                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
+                    "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
                     "dev": true
                 },
                 "@babel/template": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
-                    "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+                    "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.0.0",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/parser": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/traverse": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz",
-                    "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz",
+                    "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.5.5",
-                        "@babel/generator": "^7.7.4",
-                        "@babel/helper-function-name": "^7.7.4",
-                        "@babel/helper-split-export-declaration": "^7.7.4",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4",
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/generator": "^7.11.0",
+                        "@babel/helper-function-name": "^7.10.4",
+                        "@babel/helper-split-export-declaration": "^7.11.0",
+                        "@babel/parser": "^7.11.0",
+                        "@babel/types": "^7.11.0",
                         "debug": "^4.1.0",
                         "globals": "^11.1.0",
-                        "lodash": "^4.17.13"
+                        "lodash": "^4.17.19"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
                 },
@@ -957,6 +1101,12 @@
                         "ms": "^2.1.1"
                     }
                 },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
+                },
                 "ms": {
                     "version": "2.1.2",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -966,42 +1116,96 @@
             }
         },
         "@babel/helper-simple-access": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz",
-            "integrity": "sha512-zK7THeEXfan7UlWsG2A6CI/L9jVnI5+xxKZOdej39Y0YtDYKx9raHk5F2EtK9K8DHRTihYwg20ADt9S36GR78A==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz",
+            "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==",
             "dev": true,
             "requires": {
-                "@babel/template": "^7.7.4",
-                "@babel/types": "^7.7.4"
+                "@babel/template": "^7.10.4",
+                "@babel/types": "^7.10.4"
             },
             "dependencies": {
+                "@babel/code-frame": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+                    "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/highlight": "^7.10.4"
+                    }
+                },
+                "@babel/highlight": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+                    "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "chalk": "^2.0.0",
+                        "js-tokens": "^4.0.0"
+                    }
+                },
                 "@babel/parser": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz",
-                    "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==",
+                    "version": "7.11.3",
+                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
+                    "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
                     "dev": true
                 },
                 "@babel/template": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
-                    "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+                    "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.0.0",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/parser": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
+                }
+            }
+        },
+        "@babel/helper-skip-transparent-expression-wrappers": {
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz",
+            "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==",
+            "dev": true,
+            "requires": {
+                "@babel/types": "^7.11.0"
+            },
+            "dependencies": {
+                "@babel/types": {
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
+                        "to-fast-properties": "^2.0.0"
+                    }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
@@ -1014,112 +1218,126 @@
                 "@babel/types": "^7.4.4"
             }
         },
+        "@babel/helper-validator-identifier": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+            "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+            "dev": true
+        },
         "@babel/helper-wrap-function": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz",
-            "integrity": "sha512-VsfzZt6wmsocOaVU0OokwrIytHND55yvyT4BPB9AIIgwr8+x7617hetdJTsuGwygN5RC6mxA9EJztTjuwm2ofg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz",
+            "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==",
             "dev": true,
             "requires": {
-                "@babel/helper-function-name": "^7.7.4",
-                "@babel/template": "^7.7.4",
-                "@babel/traverse": "^7.7.4",
-                "@babel/types": "^7.7.4"
+                "@babel/helper-function-name": "^7.10.4",
+                "@babel/template": "^7.10.4",
+                "@babel/traverse": "^7.10.4",
+                "@babel/types": "^7.10.4"
             },
             "dependencies": {
-                "@babel/generator": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz",
-                    "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==",
+                "@babel/code-frame": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+                    "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4",
+                        "@babel/highlight": "^7.10.4"
+                    }
+                },
+                "@babel/generator": {
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz",
+                    "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/types": "^7.11.0",
                         "jsesc": "^2.5.1",
-                        "lodash": "^4.17.13",
                         "source-map": "^0.5.0"
                     }
                 },
                 "@babel/helper-function-name": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
-                    "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+                    "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
                     "dev": true,
                     "requires": {
-                        "@babel/helper-get-function-arity": "^7.7.4",
-                        "@babel/template": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/helper-get-function-arity": "^7.10.4",
+                        "@babel/template": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-get-function-arity": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
-                    "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+                    "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-split-export-declaration": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz",
-                    "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+                    "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.11.0"
+                    }
+                },
+                "@babel/highlight": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+                    "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "chalk": "^2.0.0",
+                        "js-tokens": "^4.0.0"
                     }
                 },
                 "@babel/parser": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz",
-                    "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==",
+                    "version": "7.11.3",
+                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
+                    "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
                     "dev": true
                 },
                 "@babel/template": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
-                    "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+                    "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.0.0",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/parser": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/traverse": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz",
-                    "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz",
+                    "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.5.5",
-                        "@babel/generator": "^7.7.4",
-                        "@babel/helper-function-name": "^7.7.4",
-                        "@babel/helper-split-export-declaration": "^7.7.4",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4",
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/generator": "^7.11.0",
+                        "@babel/helper-function-name": "^7.10.4",
+                        "@babel/helper-split-export-declaration": "^7.11.0",
+                        "@babel/parser": "^7.11.0",
+                        "@babel/types": "^7.11.0",
                         "debug": "^4.1.0",
                         "globals": "^11.1.0",
-                        "lodash": "^4.17.13"
-                    },
-                    "dependencies": {
-                        "@babel/code-frame": {
-                            "version": "7.5.5",
-                            "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
-                            "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
-                            "dev": true,
-                            "requires": {
-                                "@babel/highlight": "^7.0.0"
-                            }
-                        }
+                        "lodash": "^4.17.19"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
                 },
@@ -1132,6 +1350,12 @@
                         "ms": "^2.1.1"
                     }
                 },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
+                },
                 "ms": {
                     "version": "2.1.2",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -1283,84 +1507,284 @@
             "dev": true
         },
         "@babel/plugin-proposal-async-generator-functions": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz",
-            "integrity": "sha512-1ypyZvGRXriY/QP668+s8sFr2mqinhkRDMPSQLNghCQE+GAkFtp+wkHVvg2+Hdki8gwP+NFzJBJ/N1BfzCCDEw==",
+            "version": "7.10.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz",
+            "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/helper-remap-async-to-generator": "^7.7.4",
-                "@babel/plugin-syntax-async-generators": "^7.7.4"
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/helper-remap-async-to-generator": "^7.10.4",
+                "@babel/plugin-syntax-async-generators": "^7.8.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
+            }
+        },
+        "@babel/plugin-proposal-class-properties": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz",
+            "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-create-class-features-plugin": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-proposal-dynamic-import": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.4.tgz",
-            "integrity": "sha512-StH+nGAdO6qDB1l8sZ5UBV8AC3F2VW2I8Vfld73TMKyptMU9DY5YsJAS8U81+vEtxcH3Y/La0wG0btDrhpnhjQ==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz",
+            "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/plugin-syntax-dynamic-import": "^7.7.4"
-            }
-        },
-        "@babel/plugin-proposal-json-strings": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.7.4.tgz",
-            "integrity": "sha512-wQvt3akcBTfLU/wYoqm/ws7YOAQKu8EVJEvHip/mzkNtjaclQoCCIqKXFP5/eyfnfbQCDV3OLRIK3mIVyXuZlw==",
-            "dev": true,
-            "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/plugin-syntax-json-strings": "^7.7.4"
-            }
-        },
-        "@babel/plugin-proposal-object-rest-spread": {
-            "version": "7.7.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.7.tgz",
-            "integrity": "sha512-3qp9I8lelgzNedI3hrhkvhaEYree6+WHnyA/q4Dza9z7iEIs1eyhWyJnetk3jJ69RT0AT4G0UhEGwyGFJ7GUuQ==",
-            "dev": true,
-            "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/plugin-syntax-object-rest-spread": "^7.7.4"
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/plugin-syntax-dynamic-import": "^7.8.0"
             },
             "dependencies": {
-                "@babel/plugin-syntax-object-rest-spread": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz",
-                    "integrity": "sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg==",
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                },
+                "@babel/plugin-syntax-dynamic-import": {
+                    "version": "7.8.3",
+                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+                    "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
                     "dev": true,
                     "requires": {
-                        "@babel/helper-plugin-utils": "^7.0.0"
+                        "@babel/helper-plugin-utils": "^7.8.0"
                     }
                 }
             }
         },
-        "@babel/plugin-proposal-optional-catch-binding": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz",
-            "integrity": "sha512-DyM7U2bnsQerCQ+sejcTNZh8KQEUuC3ufzdnVnSiUv/qoGJp2Z3hanKL18KDhsBT5Wj6a7CMT5mdyCNJsEaA9w==",
+        "@babel/plugin-proposal-export-namespace-from": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz",
+            "integrity": "sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/plugin-syntax-optional-catch-binding": "^7.7.4"
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
+            }
+        },
+        "@babel/plugin-proposal-json-strings": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz",
+            "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/plugin-syntax-json-strings": "^7.8.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
+            }
+        },
+        "@babel/plugin-proposal-logical-assignment-operators": {
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz",
+            "integrity": "sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                },
+                "@babel/plugin-syntax-logical-assignment-operators": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+                    "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-plugin-utils": "^7.10.4"
+                    }
+                }
+            }
+        },
+        "@babel/plugin-proposal-nullish-coalescing-operator": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz",
+            "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
+            }
+        },
+        "@babel/plugin-proposal-numeric-separator": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz",
+            "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                },
+                "@babel/plugin-syntax-numeric-separator": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+                    "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-plugin-utils": "^7.10.4"
+                    }
+                }
+            }
+        },
+        "@babel/plugin-proposal-object-rest-spread": {
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz",
+            "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+                "@babel/plugin-transform-parameters": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
+            }
+        },
+        "@babel/plugin-proposal-optional-catch-binding": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz",
+            "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
+            }
+        },
+        "@babel/plugin-proposal-optional-chaining": {
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz",
+            "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0",
+                "@babel/plugin-syntax-optional-chaining": "^7.8.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
+            }
+        },
+        "@babel/plugin-proposal-private-methods": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz",
+            "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-create-class-features-plugin": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-proposal-unicode-property-regex": {
-            "version": "7.7.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.7.tgz",
-            "integrity": "sha512-80PbkKyORBUVm1fbTLrHpYdJxMThzM1UqFGh0ALEhO9TYbG86Ah9zQYAB/84axz2vcxefDLdZwWwZNlYARlu9w==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz",
+            "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==",
             "dev": true,
             "requires": {
-                "@babel/helper-create-regexp-features-plugin": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-create-regexp-features-plugin": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-syntax-async-generators": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.7.4.tgz",
-            "integrity": "sha512-Li4+EjSpBgxcsmeEF8IFcfV/+yJGxHXDirDkEoyFjumuwbmfCVHUt0HuowD/iGM7OhIRyXJH9YXxqiH6N815+g==",
+            "version": "7.8.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+            "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.8.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-syntax-bigint": {
@@ -1406,6 +1830,23 @@
                 "@babel/helper-plugin-utils": "^7.0.0"
             }
         },
+        "@babel/plugin-syntax-export-namespace-from": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+            "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.8.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
+            }
+        },
         "@babel/plugin-syntax-import-meta": {
             "version": "7.10.1",
             "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.1.tgz",
@@ -1424,12 +1865,20 @@
             }
         },
         "@babel/plugin-syntax-json-strings": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz",
-            "integrity": "sha512-QpGupahTQW1mHRXddMG5srgpHWqRLwJnJZKXTigB9RPFCCGbDGCgBeM/iC82ICXp414WeYx/tD54w7M2qRqTMg==",
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+            "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.8.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-syntax-logical-assignment-operators": {
@@ -1483,13 +1932,38 @@
                 }
             }
         },
-        "@babel/plugin-syntax-optional-catch-binding": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz",
-            "integrity": "sha512-4ZSuzWgFxqHRE31Glu+fEr/MirNZOMYmD/0BhBWyLyOOQz/gTAl7QmWm2hX1QxEIXsr2vkdlwxIzTyiYRC4xcQ==",
+        "@babel/plugin-syntax-object-rest-spread": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+            "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.8.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
+            }
+        },
+        "@babel/plugin-syntax-optional-catch-binding": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+            "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.8.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-syntax-optional-chaining": {
@@ -1510,449 +1984,758 @@
             }
         },
         "@babel/plugin-syntax-top-level-await": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.4.tgz",
-            "integrity": "sha512-wdsOw0MvkL1UIgiQ/IFr3ETcfv1xb8RMM0H9wbiDyLaJFyiDg5oZvDLCXosIXmFeIlweML5iOBXAkqddkYNizg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz",
+            "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-arrow-functions": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz",
-            "integrity": "sha512-zUXy3e8jBNPiffmqkHRNDdZM2r8DWhCB7HhcoyZjiK1TxYEluLHAvQuYnTT+ARqRpabWqy/NHkO6e3MsYB5YfA==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz",
+            "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-async-to-generator": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz",
-            "integrity": "sha512-zpUTZphp5nHokuy8yLlyafxCJ0rSlFoSHypTUWgpdwoDXWQcseaect7cJ8Ppk6nunOM6+5rPMkod4OYKPR5MUg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz",
+            "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==",
             "dev": true,
             "requires": {
-                "@babel/helper-module-imports": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/helper-remap-async-to-generator": "^7.7.4"
+                "@babel/helper-module-imports": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/helper-remap-async-to-generator": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-block-scoped-functions": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz",
-            "integrity": "sha512-kqtQzwtKcpPclHYjLK//3lH8OFsCDuDJBaFhVwf8kqdnF6MN4l618UDlcA7TfRs3FayrHj+svYnSX8MC9zmUyQ==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz",
+            "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-block-scoping": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz",
-            "integrity": "sha512-2VBe9u0G+fDt9B5OV5DQH4KBf5DoiNkwFKOz0TCvBWvdAN2rOykCTkrL+jTLxfCAm76l9Qo5OqL7HBOx2dWggg==",
+            "version": "7.11.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz",
+            "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "lodash": "^4.17.13"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-classes": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz",
-            "integrity": "sha512-sK1mjWat7K+buWRuImEzjNf68qrKcrddtpQo3swi9j7dUcG6y6R6+Di039QN2bD1dykeswlagupEmpOatFHHUg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz",
+            "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==",
             "dev": true,
             "requires": {
-                "@babel/helper-annotate-as-pure": "^7.7.4",
-                "@babel/helper-define-map": "^7.7.4",
-                "@babel/helper-function-name": "^7.7.4",
-                "@babel/helper-optimise-call-expression": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/helper-replace-supers": "^7.7.4",
-                "@babel/helper-split-export-declaration": "^7.7.4",
+                "@babel/helper-annotate-as-pure": "^7.10.4",
+                "@babel/helper-define-map": "^7.10.4",
+                "@babel/helper-function-name": "^7.10.4",
+                "@babel/helper-optimise-call-expression": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/helper-replace-supers": "^7.10.4",
+                "@babel/helper-split-export-declaration": "^7.10.4",
                 "globals": "^11.1.0"
             },
             "dependencies": {
-                "@babel/helper-function-name": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
-                    "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
+                "@babel/code-frame": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+                    "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
                     "dev": true,
                     "requires": {
-                        "@babel/helper-get-function-arity": "^7.7.4",
-                        "@babel/template": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/highlight": "^7.10.4"
+                    }
+                },
+                "@babel/helper-function-name": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+                    "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-get-function-arity": "^7.10.4",
+                        "@babel/template": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-get-function-arity": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
-                    "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+                    "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.10.4"
                     }
                 },
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                },
                 "@babel/helper-split-export-declaration": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz",
-                    "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+                    "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.11.0"
+                    }
+                },
+                "@babel/highlight": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+                    "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "chalk": "^2.0.0",
+                        "js-tokens": "^4.0.0"
                     }
                 },
                 "@babel/parser": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz",
-                    "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==",
+                    "version": "7.11.3",
+                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
+                    "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
                     "dev": true
                 },
                 "@babel/template": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
-                    "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+                    "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.0.0",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/parser": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
         "@babel/plugin-transform-computed-properties": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz",
-            "integrity": "sha512-bSNsOsZnlpLLyQew35rl4Fma3yKWqK3ImWMSC/Nc+6nGjC9s5NFWAer1YQ899/6s9HxO2zQC1WoFNfkOqRkqRQ==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz",
+            "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-destructuring": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz",
-            "integrity": "sha512-4jFMXI1Cu2aXbcXXl8Lr6YubCn6Oc7k9lLsu8v61TZh+1jny2BWmdtvY9zSUlLdGUvcy9DMAWyZEOqjsbeg/wA==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz",
+            "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-dotall-regex": {
-            "version": "7.7.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.7.tgz",
-            "integrity": "sha512-b4in+YlTeE/QmTgrllnb3bHA0HntYvjz8O3Mcbx75UBPJA2xhb5A8nle498VhxSXJHQefjtQxpnLPehDJ4TRlg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz",
+            "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==",
             "dev": true,
             "requires": {
-                "@babel/helper-create-regexp-features-plugin": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-create-regexp-features-plugin": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-duplicate-keys": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.7.4.tgz",
-            "integrity": "sha512-g1y4/G6xGWMD85Tlft5XedGaZBCIVN+/P0bs6eabmcPP9egFleMAo65OOjlhcz1njpwagyY3t0nsQC9oTFegJA==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz",
+            "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-exponentiation-operator": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz",
-            "integrity": "sha512-MCqiLfCKm6KEA1dglf6Uqq1ElDIZwFuzz1WH5mTf8k2uQSxEJMbOIEh7IZv7uichr7PMfi5YVSrr1vz+ipp7AQ==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz",
+            "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==",
             "dev": true,
             "requires": {
-                "@babel/helper-builder-binary-assignment-operator-visitor": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-for-of": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz",
-            "integrity": "sha512-zZ1fD1B8keYtEcKF+M1TROfeHTKnijcVQm0yO/Yu1f7qoDoxEIc/+GX6Go430Bg84eM/xwPFp0+h4EbZg7epAA==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz",
+            "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-function-name": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz",
-            "integrity": "sha512-E/x09TvjHNhsULs2IusN+aJNRV5zKwxu1cpirZyRPw+FyyIKEHPXTsadj48bVpc1R5Qq1B5ZkzumuFLytnbT6g==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz",
+            "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==",
             "dev": true,
             "requires": {
-                "@babel/helper-function-name": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-function-name": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4"
             },
             "dependencies": {
-                "@babel/helper-function-name": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
-                    "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
+                "@babel/code-frame": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+                    "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
                     "dev": true,
                     "requires": {
-                        "@babel/helper-get-function-arity": "^7.7.4",
-                        "@babel/template": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/highlight": "^7.10.4"
+                    }
+                },
+                "@babel/helper-function-name": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+                    "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-get-function-arity": "^7.10.4",
+                        "@babel/template": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/helper-get-function-arity": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
-                    "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+                    "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.10.4"
+                    }
+                },
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                },
+                "@babel/highlight": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+                    "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "chalk": "^2.0.0",
+                        "js-tokens": "^4.0.0"
                     }
                 },
                 "@babel/parser": {
-                    "version": "7.7.7",
-                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz",
-                    "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==",
+                    "version": "7.11.3",
+                    "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz",
+                    "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==",
                     "dev": true
                 },
                 "@babel/template": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
-                    "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+                    "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
                     "dev": true,
                     "requires": {
-                        "@babel/code-frame": "^7.0.0",
-                        "@babel/parser": "^7.7.4",
-                        "@babel/types": "^7.7.4"
+                        "@babel/code-frame": "^7.10.4",
+                        "@babel/parser": "^7.10.4",
+                        "@babel/types": "^7.10.4"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
         "@babel/plugin-transform-literals": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz",
-            "integrity": "sha512-X2MSV7LfJFm4aZfxd0yLVFrEXAgPqYoDG53Br/tCKiKYfX0MjVjQeWPIhPHHsCqzwQANq+FLN786fF5rgLS+gw==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz",
+            "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-member-expression-literals": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.7.4.tgz",
-            "integrity": "sha512-9VMwMO7i69LHTesL0RdGy93JU6a+qOPuvB4F4d0kR0zyVjJRVJRaoaGjhtki6SzQUu8yen/vxPKN6CWnCUw6bA==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz",
+            "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-modules-amd": {
-            "version": "7.7.5",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.5.tgz",
-            "integrity": "sha512-CT57FG4A2ZUNU1v+HdvDSDrjNWBrtCmSH6YbbgN3Lrf0Di/q/lWRxZrE72p3+HCCz9UjfZOEBdphgC0nzOS6DQ==",
+            "version": "7.10.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz",
+            "integrity": "sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==",
             "dev": true,
             "requires": {
-                "@babel/helper-module-transforms": "^7.7.5",
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "babel-plugin-dynamic-import-node": "^2.3.0"
+                "@babel/helper-module-transforms": "^7.10.5",
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "babel-plugin-dynamic-import-node": "^2.3.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-modules-commonjs": {
-            "version": "7.7.5",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz",
-            "integrity": "sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz",
+            "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==",
             "dev": true,
             "requires": {
-                "@babel/helper-module-transforms": "^7.7.5",
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/helper-simple-access": "^7.7.4",
-                "babel-plugin-dynamic-import-node": "^2.3.0"
+                "@babel/helper-module-transforms": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/helper-simple-access": "^7.10.4",
+                "babel-plugin-dynamic-import-node": "^2.3.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-modules-systemjs": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.4.tgz",
-            "integrity": "sha512-y2c96hmcsUi6LrMqvmNDPBBiGCiQu0aYqpHatVVu6kD4mFEXKjyNxd/drc18XXAf9dv7UXjrZwBVmTTGaGP8iw==",
+            "version": "7.10.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz",
+            "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==",
             "dev": true,
             "requires": {
-                "@babel/helper-hoist-variables": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "babel-plugin-dynamic-import-node": "^2.3.0"
+                "@babel/helper-hoist-variables": "^7.10.4",
+                "@babel/helper-module-transforms": "^7.10.5",
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "babel-plugin-dynamic-import-node": "^2.3.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-modules-umd": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.4.tgz",
-            "integrity": "sha512-u2B8TIi0qZI4j8q4C51ktfO7E3cQ0qnaXFI1/OXITordD40tt17g/sXqgNNCcMTcBFKrUPcGDx+TBJuZxLx7tw==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz",
+            "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==",
             "dev": true,
             "requires": {
-                "@babel/helper-module-transforms": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-module-transforms": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-named-capturing-groups-regex": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.4.tgz",
-            "integrity": "sha512-jBUkiqLKvUWpv9GLSuHUFYdmHg0ujC1JEYoZUfeOOfNydZXp1sXObgyPatpcwjWgsdBGsagWW0cdJpX/DO2jMw==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz",
+            "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==",
             "dev": true,
             "requires": {
-                "@babel/helper-create-regexp-features-plugin": "^7.7.4"
+                "@babel/helper-create-regexp-features-plugin": "^7.10.4"
             }
         },
         "@babel/plugin-transform-new-target": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.7.4.tgz",
-            "integrity": "sha512-CnPRiNtOG1vRodnsyGX37bHQleHE14B9dnnlgSeEs3ek3fHN1A1SScglTCg1sfbe7sRQ2BUcpgpTpWSfMKz3gg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz",
+            "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-object-super": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz",
-            "integrity": "sha512-ho+dAEhC2aRnff2JCA0SAK7V2R62zJd/7dmtoe7MHcso4C2mS+vZjn1Pb1pCVZvJs1mgsvv5+7sT+m3Bysb6eg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz",
+            "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/helper-replace-supers": "^7.7.4"
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/helper-replace-supers": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-parameters": {
-            "version": "7.7.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.7.tgz",
-            "integrity": "sha512-OhGSrf9ZBrr1fw84oFXj5hgi8Nmg+E2w5L7NhnG0lPvpDtqd7dbyilM2/vR8CKbJ907RyxPh2kj6sBCSSfI9Ew==",
+            "version": "7.10.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz",
+            "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==",
             "dev": true,
             "requires": {
-                "@babel/helper-call-delegate": "^7.7.4",
-                "@babel/helper-get-function-arity": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-get-function-arity": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4"
             },
             "dependencies": {
                 "@babel/helper-get-function-arity": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
-                    "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+                    "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
                     "dev": true,
                     "requires": {
-                        "@babel/types": "^7.7.4"
+                        "@babel/types": "^7.10.4"
                     }
                 },
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
         "@babel/plugin-transform-property-literals": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.7.4.tgz",
-            "integrity": "sha512-MatJhlC4iHsIskWYyawl53KuHrt+kALSADLQQ/HkhTjX954fkxIEh4q5slL4oRAnsm/eDoZ4q0CIZpcqBuxhJQ==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz",
+            "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-regenerator": {
-            "version": "7.7.5",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.5.tgz",
-            "integrity": "sha512-/8I8tPvX2FkuEyWbjRCt4qTAgZK0DVy8QRguhA524UH48RfGJy94On2ri+dCuwOpcerPRl9O4ebQkRcVzIaGBw==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz",
+            "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==",
             "dev": true,
             "requires": {
-                "regenerator-transform": "^0.14.0"
+                "regenerator-transform": "^0.14.2"
             }
         },
         "@babel/plugin-transform-reserved-words": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.7.4.tgz",
-            "integrity": "sha512-OrPiUB5s5XvkCO1lS7D8ZtHcswIC57j62acAnJZKqGGnHP+TIc/ljQSrgdX/QyOTdEK5COAhuc820Hi1q2UgLQ==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz",
+            "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-shorthand-properties": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz",
-            "integrity": "sha512-q+suddWRfIcnyG5YiDP58sT65AJDZSUhXQDZE3r04AuqD6d/XLaQPPXSBzP2zGerkgBivqtQm9XKGLuHqBID6Q==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz",
+            "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-spread": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz",
-            "integrity": "sha512-8OSs0FLe5/80cndziPlg4R0K6HcWSM0zyNhHhLsmw/Nc5MaA49cAsnoJ/t/YZf8qkG7fD+UjTRaApVDB526d7Q==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz",
+            "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-sticky-regex": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz",
-            "integrity": "sha512-Ls2NASyL6qtVe1H1hXts9yuEeONV2TJZmplLONkMPUG158CtmnrzW5Q5teibM5UVOFjG0D3IC5mzXR6pPpUY7A==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz",
+            "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/helper-regex": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/helper-regex": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-template-literals": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz",
-            "integrity": "sha512-sA+KxLwF3QwGj5abMHkHgshp9+rRz+oY9uoRil4CyLtgEuE/88dpkeWgNk5qKVsJE9iSfly3nvHapdRiIS2wnQ==",
+            "version": "7.10.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz",
+            "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==",
             "dev": true,
             "requires": {
-                "@babel/helper-annotate-as-pure": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-annotate-as-pure": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-typeof-symbol": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.7.4.tgz",
-            "integrity": "sha512-KQPUQ/7mqe2m0B8VecdyaW5XcQYaePyl9R7IsKd+irzj6jvbhoGnRE+M0aNkyAzI07VfUQ9266L5xMARitV3wg==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz",
+            "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==",
             "dev": true,
             "requires": {
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
+            }
+        },
+        "@babel/plugin-transform-unicode-escapes": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz",
+            "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/plugin-transform-unicode-regex": {
-            "version": "7.7.4",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz",
-            "integrity": "sha512-N77UUIV+WCvE+5yHw+oks3m18/umd7y392Zv7mYTpFqHtkpcc+QUz+gLJNTWVlWROIWeLqY0f3OjZxV5TcXnRw==",
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz",
+            "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==",
             "dev": true,
             "requires": {
-                "@babel/helper-create-regexp-features-plugin": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0"
+                "@babel/helper-create-regexp-features-plugin": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                }
             }
         },
         "@babel/polyfill": {
@@ -1974,86 +2757,155 @@
             }
         },
         "@babel/preset-env": {
-            "version": "7.7.7",
-            "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.7.7.tgz",
-            "integrity": "sha512-pCu0hrSSDVI7kCVUOdcMNQEbOPJ52E+LrQ14sN8uL2ALfSqePZQlKrOy+tM4uhEdYlCHi4imr8Zz2cZe9oSdIg==",
+            "version": "7.11.0",
+            "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.0.tgz",
+            "integrity": "sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg==",
             "dev": true,
             "requires": {
-                "@babel/helper-module-imports": "^7.7.4",
-                "@babel/helper-plugin-utils": "^7.0.0",
-                "@babel/plugin-proposal-async-generator-functions": "^7.7.4",
-                "@babel/plugin-proposal-dynamic-import": "^7.7.4",
-                "@babel/plugin-proposal-json-strings": "^7.7.4",
-                "@babel/plugin-proposal-object-rest-spread": "^7.7.7",
-                "@babel/plugin-proposal-optional-catch-binding": "^7.7.4",
-                "@babel/plugin-proposal-unicode-property-regex": "^7.7.7",
-                "@babel/plugin-syntax-async-generators": "^7.7.4",
-                "@babel/plugin-syntax-dynamic-import": "^7.7.4",
-                "@babel/plugin-syntax-json-strings": "^7.7.4",
-                "@babel/plugin-syntax-object-rest-spread": "^7.7.4",
-                "@babel/plugin-syntax-optional-catch-binding": "^7.7.4",
-                "@babel/plugin-syntax-top-level-await": "^7.7.4",
-                "@babel/plugin-transform-arrow-functions": "^7.7.4",
-                "@babel/plugin-transform-async-to-generator": "^7.7.4",
-                "@babel/plugin-transform-block-scoped-functions": "^7.7.4",
-                "@babel/plugin-transform-block-scoping": "^7.7.4",
-                "@babel/plugin-transform-classes": "^7.7.4",
-                "@babel/plugin-transform-computed-properties": "^7.7.4",
-                "@babel/plugin-transform-destructuring": "^7.7.4",
-                "@babel/plugin-transform-dotall-regex": "^7.7.7",
-                "@babel/plugin-transform-duplicate-keys": "^7.7.4",
-                "@babel/plugin-transform-exponentiation-operator": "^7.7.4",
-                "@babel/plugin-transform-for-of": "^7.7.4",
-                "@babel/plugin-transform-function-name": "^7.7.4",
-                "@babel/plugin-transform-literals": "^7.7.4",
-                "@babel/plugin-transform-member-expression-literals": "^7.7.4",
-                "@babel/plugin-transform-modules-amd": "^7.7.5",
-                "@babel/plugin-transform-modules-commonjs": "^7.7.5",
-                "@babel/plugin-transform-modules-systemjs": "^7.7.4",
-                "@babel/plugin-transform-modules-umd": "^7.7.4",
-                "@babel/plugin-transform-named-capturing-groups-regex": "^7.7.4",
-                "@babel/plugin-transform-new-target": "^7.7.4",
-                "@babel/plugin-transform-object-super": "^7.7.4",
-                "@babel/plugin-transform-parameters": "^7.7.7",
-                "@babel/plugin-transform-property-literals": "^7.7.4",
-                "@babel/plugin-transform-regenerator": "^7.7.5",
-                "@babel/plugin-transform-reserved-words": "^7.7.4",
-                "@babel/plugin-transform-shorthand-properties": "^7.7.4",
-                "@babel/plugin-transform-spread": "^7.7.4",
-                "@babel/plugin-transform-sticky-regex": "^7.7.4",
-                "@babel/plugin-transform-template-literals": "^7.7.4",
-                "@babel/plugin-transform-typeof-symbol": "^7.7.4",
-                "@babel/plugin-transform-unicode-regex": "^7.7.4",
-                "@babel/types": "^7.7.4",
-                "browserslist": "^4.6.0",
-                "core-js-compat": "^3.6.0",
+                "@babel/compat-data": "^7.11.0",
+                "@babel/helper-compilation-targets": "^7.10.4",
+                "@babel/helper-module-imports": "^7.10.4",
+                "@babel/helper-plugin-utils": "^7.10.4",
+                "@babel/plugin-proposal-async-generator-functions": "^7.10.4",
+                "@babel/plugin-proposal-class-properties": "^7.10.4",
+                "@babel/plugin-proposal-dynamic-import": "^7.10.4",
+                "@babel/plugin-proposal-export-namespace-from": "^7.10.4",
+                "@babel/plugin-proposal-json-strings": "^7.10.4",
+                "@babel/plugin-proposal-logical-assignment-operators": "^7.11.0",
+                "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
+                "@babel/plugin-proposal-numeric-separator": "^7.10.4",
+                "@babel/plugin-proposal-object-rest-spread": "^7.11.0",
+                "@babel/plugin-proposal-optional-catch-binding": "^7.10.4",
+                "@babel/plugin-proposal-optional-chaining": "^7.11.0",
+                "@babel/plugin-proposal-private-methods": "^7.10.4",
+                "@babel/plugin-proposal-unicode-property-regex": "^7.10.4",
+                "@babel/plugin-syntax-async-generators": "^7.8.0",
+                "@babel/plugin-syntax-class-properties": "^7.10.4",
+                "@babel/plugin-syntax-dynamic-import": "^7.8.0",
+                "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+                "@babel/plugin-syntax-json-strings": "^7.8.0",
+                "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+                "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
+                "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+                "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+                "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
+                "@babel/plugin-syntax-optional-chaining": "^7.8.0",
+                "@babel/plugin-syntax-top-level-await": "^7.10.4",
+                "@babel/plugin-transform-arrow-functions": "^7.10.4",
+                "@babel/plugin-transform-async-to-generator": "^7.10.4",
+                "@babel/plugin-transform-block-scoped-functions": "^7.10.4",
+                "@babel/plugin-transform-block-scoping": "^7.10.4",
+                "@babel/plugin-transform-classes": "^7.10.4",
+                "@babel/plugin-transform-computed-properties": "^7.10.4",
+                "@babel/plugin-transform-destructuring": "^7.10.4",
+                "@babel/plugin-transform-dotall-regex": "^7.10.4",
+                "@babel/plugin-transform-duplicate-keys": "^7.10.4",
+                "@babel/plugin-transform-exponentiation-operator": "^7.10.4",
+                "@babel/plugin-transform-for-of": "^7.10.4",
+                "@babel/plugin-transform-function-name": "^7.10.4",
+                "@babel/plugin-transform-literals": "^7.10.4",
+                "@babel/plugin-transform-member-expression-literals": "^7.10.4",
+                "@babel/plugin-transform-modules-amd": "^7.10.4",
+                "@babel/plugin-transform-modules-commonjs": "^7.10.4",
+                "@babel/plugin-transform-modules-systemjs": "^7.10.4",
+                "@babel/plugin-transform-modules-umd": "^7.10.4",
+                "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4",
+                "@babel/plugin-transform-new-target": "^7.10.4",
+                "@babel/plugin-transform-object-super": "^7.10.4",
+                "@babel/plugin-transform-parameters": "^7.10.4",
+                "@babel/plugin-transform-property-literals": "^7.10.4",
+                "@babel/plugin-transform-regenerator": "^7.10.4",
+                "@babel/plugin-transform-reserved-words": "^7.10.4",
+                "@babel/plugin-transform-shorthand-properties": "^7.10.4",
+                "@babel/plugin-transform-spread": "^7.11.0",
+                "@babel/plugin-transform-sticky-regex": "^7.10.4",
+                "@babel/plugin-transform-template-literals": "^7.10.4",
+                "@babel/plugin-transform-typeof-symbol": "^7.10.4",
+                "@babel/plugin-transform-unicode-escapes": "^7.10.4",
+                "@babel/plugin-transform-unicode-regex": "^7.10.4",
+                "@babel/preset-modules": "^0.1.3",
+                "@babel/types": "^7.11.0",
+                "browserslist": "^4.12.0",
+                "core-js-compat": "^3.6.2",
                 "invariant": "^2.2.2",
-                "js-levenshtein": "^1.1.3",
+                "levenary": "^1.1.1",
                 "semver": "^5.5.0"
             },
             "dependencies": {
-                "@babel/plugin-syntax-object-rest-spread": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz",
-                    "integrity": "sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg==",
+                "@babel/helper-plugin-utils": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+                    "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+                    "dev": true
+                },
+                "@babel/plugin-syntax-class-properties": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz",
+                    "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==",
                     "dev": true,
                     "requires": {
-                        "@babel/helper-plugin-utils": "^7.0.0"
+                        "@babel/helper-plugin-utils": "^7.10.4"
+                    }
+                },
+                "@babel/plugin-syntax-dynamic-import": {
+                    "version": "7.8.3",
+                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+                    "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-plugin-utils": "^7.8.0"
+                    }
+                },
+                "@babel/plugin-syntax-logical-assignment-operators": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+                    "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-plugin-utils": "^7.10.4"
+                    }
+                },
+                "@babel/plugin-syntax-numeric-separator": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+                    "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+                    "dev": true,
+                    "requires": {
+                        "@babel/helper-plugin-utils": "^7.10.4"
                     }
                 },
                 "@babel/types": {
-                    "version": "7.7.4",
-                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
-                    "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+                    "version": "7.11.0",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+                    "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
                     "dev": true,
                     "requires": {
-                        "esutils": "^2.0.2",
-                        "lodash": "^4.17.13",
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
                         "to-fast-properties": "^2.0.0"
                     }
+                },
+                "lodash": {
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+                    "dev": true
                 }
             }
         },
+        "@babel/preset-modules": {
+            "version": "0.1.3",
+            "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz",
+            "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.0.0",
+                "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+                "@babel/plugin-transform-dotall-regex": "^7.4.4",
+                "@babel/types": "^7.4.4",
+                "esutils": "^2.0.2"
+            }
+        },
         "@babel/register": {
             "version": "7.7.7",
             "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.7.7.tgz",
@@ -2085,6 +2937,23 @@
                 }
             }
         },
+        "@babel/runtime": {
+            "version": "7.11.2",
+            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz",
+            "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==",
+            "dev": true,
+            "requires": {
+                "regenerator-runtime": "^0.13.4"
+            },
+            "dependencies": {
+                "regenerator-runtime": {
+                    "version": "0.13.7",
+                    "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+                    "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
+                    "dev": true
+                }
+            }
+        },
         "@babel/template": {
             "version": "7.6.0",
             "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz",
@@ -5382,9 +6251,9 @@
             }
         },
         "babel-plugin-dynamic-import-node": {
-            "version": "2.3.0",
-            "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz",
-            "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==",
+            "version": "2.3.3",
+            "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+            "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
             "dev": true,
             "requires": {
                 "object.assign": "^4.1.0"
@@ -6266,14 +7135,15 @@
             }
         },
         "browserslist": {
-            "version": "4.8.3",
-            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.3.tgz",
-            "integrity": "sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg==",
+            "version": "4.14.0",
+            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz",
+            "integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==",
             "dev": true,
             "requires": {
-                "caniuse-lite": "^1.0.30001017",
-                "electron-to-chromium": "^1.3.322",
-                "node-releases": "^1.1.44"
+                "caniuse-lite": "^1.0.30001111",
+                "electron-to-chromium": "^1.3.523",
+                "escalade": "^3.0.2",
+                "node-releases": "^1.1.60"
             }
         },
         "bser": {
@@ -6515,9 +7385,9 @@
             "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
         },
         "caniuse-lite": {
-            "version": "1.0.30001019",
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001019.tgz",
-            "integrity": "sha512-6ljkLtF1KM5fQ+5ZN0wuyVvvebJxgJPTmScOMaFuQN2QuOzvRJnWSKfzQskQU5IOU4Gap3zasYPIinzwUjoj/g==",
+            "version": "1.0.30001114",
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001114.tgz",
+            "integrity": "sha512-ml/zTsfNBM+T1+mjglWRPgVsu2L76GAaADKX5f4t0pbhttEp0WMawJsHDYlFkVZkoA+89uvBRrVrEE4oqenzXQ==",
             "dev": true
         },
         "canonical-json": {
@@ -7123,12 +7993,12 @@
             "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A=="
         },
         "core-js-compat": {
-            "version": "3.6.2",
-            "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.2.tgz",
-            "integrity": "sha512-+G28dzfYGtAM+XGvB1C5AS1ZPKfQ47HLhcdeIQdZgQnJVdp7/D0m+W/TErwhgsX6CujRUk/LebB6dCrKrtJrvQ==",
+            "version": "3.6.5",
+            "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz",
+            "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==",
             "dev": true,
             "requires": {
-                "browserslist": "^4.8.3",
+                "browserslist": "^4.8.5",
                 "semver": "7.0.0"
             },
             "dependencies": {
@@ -7867,9 +8737,9 @@
             "integrity": "sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q=="
         },
         "electron-to-chromium": {
-            "version": "1.3.328",
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.328.tgz",
-            "integrity": "sha512-x4XefnFxDxFwaQ01d/pppJP9meWhOIJ/gtI6/4jqkpsadq79uL7NYSaX64naLmJqvzUBjSrO3IM2+1b/W9KdPg==",
+            "version": "1.3.533",
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.533.tgz",
+            "integrity": "sha512-YqAL+NXOzjBnpY+dcOKDlZybJDCOzgsq4koW3fvyty/ldTmsb4QazZpOWmVvZ2m0t5jbBf7L0lIGU3BUipwG+A==",
             "dev": true
         },
         "elliptic": {
@@ -8081,6 +8951,12 @@
                 "es6-symbol": "^3.1.1"
             }
         },
+        "escalade": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz",
+            "integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==",
+            "dev": true
+        },
         "escape-goat": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
@@ -17251,12 +18127,6 @@
             "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==",
             "dev": true
         },
-        "js-levenshtein": {
-            "version": "1.1.6",
-            "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
-            "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==",
-            "dev": true
-        },
         "js-tokens": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -17592,6 +18462,15 @@
             "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
             "dev": true
         },
+        "levenary": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz",
+            "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==",
+            "dev": true,
+            "requires": {
+                "leven": "^3.1.0"
+            }
+        },
         "levn": {
             "version": "0.3.0",
             "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
@@ -19369,21 +20248,10 @@
             }
         },
         "node-releases": {
-            "version": "1.1.44",
-            "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.44.tgz",
-            "integrity": "sha512-NwbdvJyR7nrcGrXvKAvzc5raj/NkoJudkarh2yIpJ4t0NH4aqjUDz/486P+ynIW5eokKOfzGNRdYoLfBlomruw==",
-            "dev": true,
-            "requires": {
-                "semver": "^6.3.0"
-            },
-            "dependencies": {
-                "semver": {
-                    "version": "6.3.0",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-                    "dev": true
-                }
-            }
+            "version": "1.1.60",
+            "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz",
+            "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==",
+            "dev": true
         },
         "node-sass": {
             "version": "4.14.1",
@@ -20999,9 +21867,9 @@
             "dev": true
         },
         "regenerate-unicode-properties": {
-            "version": "8.1.0",
-            "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz",
-            "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==",
+            "version": "8.2.0",
+            "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
+            "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
             "dev": true,
             "requires": {
                 "regenerate": "^1.4.0"
@@ -21013,12 +21881,12 @@
             "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
         },
         "regenerator-transform": {
-            "version": "0.14.1",
-            "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz",
-            "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==",
+            "version": "0.14.5",
+            "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
+            "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==",
             "dev": true,
             "requires": {
-                "private": "^0.1.6"
+                "@babel/runtime": "^7.8.4"
             }
         },
         "regex-not": {
@@ -21038,17 +21906,17 @@
             "dev": true
         },
         "regexpu-core": {
-            "version": "4.6.0",
-            "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz",
-            "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==",
+            "version": "4.7.0",
+            "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz",
+            "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==",
             "dev": true,
             "requires": {
                 "regenerate": "^1.4.0",
-                "regenerate-unicode-properties": "^8.1.0",
-                "regjsgen": "^0.5.0",
-                "regjsparser": "^0.6.0",
+                "regenerate-unicode-properties": "^8.2.0",
+                "regjsgen": "^0.5.1",
+                "regjsparser": "^0.6.4",
                 "unicode-match-property-ecmascript": "^1.0.4",
-                "unicode-match-property-value-ecmascript": "^1.1.0"
+                "unicode-match-property-value-ecmascript": "^1.2.0"
             }
         },
         "registry-auth-token": {
@@ -21071,15 +21939,15 @@
             }
         },
         "regjsgen": {
-            "version": "0.5.1",
-            "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz",
-            "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==",
+            "version": "0.5.2",
+            "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
+            "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==",
             "dev": true
         },
         "regjsparser": {
-            "version": "0.6.2",
-            "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.2.tgz",
-            "integrity": "sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q==",
+            "version": "0.6.4",
+            "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz",
+            "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==",
             "dev": true,
             "requires": {
                 "jsesc": "~0.5.0"
@@ -21087,7 +21955,7 @@
             "dependencies": {
                 "jsesc": {
                     "version": "0.5.0",
-                    "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+                    "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
                     "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
                     "dev": true
                 }
@@ -23978,15 +24846,15 @@
             }
         },
         "unicode-match-property-value-ecmascript": {
-            "version": "1.1.0",
-            "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz",
-            "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==",
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
+            "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==",
             "dev": true
         },
         "unicode-property-aliases-ecmascript": {
-            "version": "1.0.5",
-            "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz",
-            "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==",
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
+            "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==",
             "dev": true
         },
         "union-value": {
diff --git a/package.json b/package.json
index b7cca03642..f9d291467b 100644
--- a/package.json
+++ b/package.json
@@ -40,7 +40,7 @@
         "@babel/core": "^7.7.7",
         "@babel/plugin-syntax-dynamic-import": "^7.7.4",
         "@babel/polyfill": "^7.7.0",
-        "@babel/preset-env": "^7.7.7",
+        "@babel/preset-env": "^7.11.0",
         "@babel/register": "^7.7.7",
         "angular-mocks": "^1.7.9",
         "babel-jest": "^26.0.1",

From a679ebfce85da3444b8850f57cad0a2867f2dc19 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 14 Aug 2020 18:42:45 +0200
Subject: [PATCH 026/109] quick fix for updateClaim from other branch

---
 modules/claim/back/methods/claim/updateClaim.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js
index 61b8085d3f..f9a1986869 100644
--- a/modules/claim/back/methods/claim/updateClaim.js
+++ b/modules/claim/back/methods/claim/updateClaim.js
@@ -53,7 +53,8 @@ module.exports = Self => {
         const updatedClaim = await claim.updateAttributes(data);
 
         // Get sales person from claim client
-        const salesPerson = claim.client().salesPerson();
+        const salesPerson = claim.client().salesPersonUser();
+        console.log('claim.client()', claim.client());
         if (salesPerson && changedHasToPickUp && updatedClaim.hasToPickUp) {
             const origin = ctx.req.headers.origin;
             const message = $t('Claim will be picked', {

From 0e4fc7e2bdda333422bdc1143ab4e26e13944cca Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 14 Aug 2020 18:43:57 +0200
Subject: [PATCH 027/109] removed unused code.

---
 modules/claim/back/methods/claim/updateClaim.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/modules/claim/back/methods/claim/updateClaim.js b/modules/claim/back/methods/claim/updateClaim.js
index bef0e5bd1c..b7156feef0 100644
--- a/modules/claim/back/methods/claim/updateClaim.js
+++ b/modules/claim/back/methods/claim/updateClaim.js
@@ -54,7 +54,6 @@ module.exports = Self => {
 
         // Get sales person from claim client
         const salesPerson = claim.client().salesPersonUser();
-        console.log('claim.client()', claim.client());
         if (salesPerson && changedHasToPickUp && updatedClaim.hasToPickUp) {
             const origin = ctx.req.headers.origin;
             const message = $t('Claim will be picked', {

From f13c47ce6d63cd2efd6b75c4ca6dab83a7dd346b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 17 Aug 2020 14:31:26 +0200
Subject: [PATCH 028/109] Ticket problems filter fix

---
 loopback/locale/es.json                      | 2 +-
 modules/ticket/back/methods/ticket/filter.js | 9 +++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/loopback/locale/es.json b/loopback/locale/es.json
index 9951df4a53..d28cceb410 100644
--- a/loopback/locale/es.json
+++ b/loopback/locale/es.json
@@ -134,5 +134,5 @@
 	"This ticket is deleted": "Este ticket está eliminado",
 	"A travel with this data already exists": "Ya existe un travel con estos datos",
 	"This thermograph id already exists": "La id del termógrafo ya existe",
-	"ORDER_ALREADY_CONFIRMED": "ORDER_ALREADY_CONFIRMED"
+	"Choose a date range or days forward": "Selecciona un rango de fechas o días en adelante"
 }
\ No newline at end of file
diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js
index 61f2bd2674..ddb55301bd 100644
--- a/modules/ticket/back/methods/ticket/filter.js
+++ b/modules/ticket/back/methods/ticket/filter.js
@@ -2,6 +2,7 @@
 const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
 const buildFilter = require('vn-loopback/util/filter').buildFilter;
 const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
+const UserError = require('vn-loopback/util/user-error');
 
 module.exports = Self => {
     Self.remoteMethod('filter', {
@@ -233,7 +234,7 @@ module.exports = Self => {
             });
         }
 
-        stmt.merge(conn.makeSuffix(filter));
+        stmt.merge(conn.makeWhere(filter.where));
         stmts.push(stmt);
 
         stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems');
@@ -244,7 +245,7 @@ module.exports = Self => {
                 SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped 
                     FROM tmp.filter f
                         LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel
-                    WHERE (f.code = 'FREE' OR f.alertLevel IS NULL)
+                    WHERE (f.alertLevelCode = 'FREE' OR f.alertLevel IS NULL)
                         AND f.shipped >= CURDATE()`);
         stmts.push('CALL ticketGetProblems()');
 
@@ -264,6 +265,9 @@ module.exports = Self => {
                     LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id
                     LEFT JOIN tmp.ticketTotal tt ON tt.ticketFk = f.id`);
 
+        if (args.problems != undefined && (!args.from || !args.to))
+            throw new UserError('Choose a date range or days forward');
+
         let condition;
         let hasProblem;
         let range;
@@ -295,6 +299,7 @@ module.exports = Self => {
             stmt.merge(conn.makeWhere(problems));
 
         stmt.merge(conn.makeOrderBy(filter.order));
+        stmt.merge(conn.makeLimit(filter));
         let ticketsIndex = stmts.push(stmt);
 
         stmts.push(

From 8968f41b753414e793e0e5fc1af4de5b28ac200d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 18 Aug 2020 08:10:40 +0200
Subject: [PATCH 029/109] Queue changes

---
 .../item/back/methods/item-image-queue/downloadImages.js    | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index e27b4516ae..d6e38d97d3 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -20,7 +20,6 @@ module.exports = Self => {
         const models = Self.app.models;
 
         try {
-            const imageQueue = await Self.find({where: {error: null}, limit: 25});
             /* const tempPath = path.join('/tmp/salix-image'); */
             const rootPath = models.Image.getPath();
             const tempPath = path.join(rootPath, 'temp');
@@ -28,7 +27,8 @@ module.exports = Self => {
             // Create temporary path
             await fs.mkdir(tempPath, {recursive: true});
 
-            for (let image of imageQueue) {
+            setInterval(async() => {
+                const image = await Self.findOne({where: {error: null}});
                 const fileName = `${image.itemFk}.png`;
                 const filePath = path.join(tempPath, fileName);
                 const file = fs.createWriteStream(filePath);
@@ -58,7 +58,7 @@ module.exports = Self => {
                 }).on('error', async error => {
                     await errorHandler(image.itemFk, error, filePath);
                 });
-            }
+            }, 500);
         } catch (error) {
             await errorHandler(image.itemFk, error);
         }

From 1ef6637ad3496213a7512f428b73bc9944a4e0a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 18 Aug 2020 08:37:39 +0200
Subject: [PATCH 030/109] Added clearInterval()

---
 .../item/back/methods/item-image-queue/downloadImages.js   | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index d6e38d97d3..dc63188136 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -27,12 +27,15 @@ module.exports = Self => {
             // Create temporary path
             await fs.mkdir(tempPath, {recursive: true});
 
-            setInterval(async() => {
+            const timer = setInterval(async() => {
                 const image = await Self.findOne({where: {error: null}});
                 const fileName = `${image.itemFk}.png`;
                 const filePath = path.join(tempPath, fileName);
-                const file = fs.createWriteStream(filePath);
 
+                // Exit loop
+                if (!image) clearInterval(timer);
+
+                const file = fs.createWriteStream(filePath);
                 https.get(image.url, async response => {
                     if (response.statusCode != 200) {
                         const error = new Error(`Could not download the image. Status code ${response.statusCode}`);

From 2a7495bac902116934009e98639f91071fd016de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 18 Aug 2020 09:45:26 +0200
Subject: [PATCH 031/109] Image queue fixes

---
 back/models/image.js                          |  9 ++--
 .../item-image-queue/downloadImages.js        | 52 ++++++++++---------
 2 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/back/models/image.js b/back/models/image.js
index 079acd2935..f1eb09c9e5 100644
--- a/back/models/image.js
+++ b/back/models/image.js
@@ -4,7 +4,8 @@ const path = require('path');
 
 module.exports = Self => {
     Self.getPath = function() {
-        return '/var/lib/salix/image';
+        // return '/var/lib/salix/image';
+        return 'C:\\Users\\jsanc\\Desktop\\image';
     };
 
     Self.registerImage = async(collectionName, file, srcFilePath) => {
@@ -55,8 +56,9 @@ module.exports = Self => {
             };
 
             await fs.mkdir(dstDir, {recursive: true});
-            await sharp(srcFilePath)
+            await sharp(srcFilePath, {failOnError: false})
                 .resize(collection.maxWidth, collection.maxHeight, resizeOpts)
+                .png()
                 .toFile(dstFile);
 
             const sizes = collection.sizes();
@@ -69,8 +71,9 @@ module.exports = Self => {
                 };
 
                 await fs.mkdir(dstDir, {recursive: true});
-                await sharp(srcFilePath)
+                await sharp(srcFilePath, {failOnError: false})
                     .resize(size.width, size.height, resizeOpts)
+                    .png()
                     .toFile(dstFile);
             }
 
diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index dc63188136..f295f420ee 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -29,39 +29,41 @@ module.exports = Self => {
 
             const timer = setInterval(async() => {
                 const image = await Self.findOne({where: {error: null}});
+
+                // Exit loop
+                if (!image) return clearInterval(timer);
+
                 const fileName = `${image.itemFk}.png`;
                 const filePath = path.join(tempPath, fileName);
 
-                // Exit loop
-                if (!image) clearInterval(timer);
+                const writeStream = fs.createWriteStream(filePath);
+                writeStream.on('open', () => {
+                    https.get(image.url, async response => {
+                        if (response.statusCode != 200) {
+                            const error = new Error(`Could not download the image. Status code ${response.statusCode}`);
 
-                const file = fs.createWriteStream(filePath);
-                https.get(image.url, async response => {
-                    if (response.statusCode != 200) {
-                        const error = new Error(`Could not download the image. Status code ${response.statusCode}`);
-
-                        file.close();
-                        await errorHandler(image.itemFk, error, filePath);
-                    }
-
-                    response.pipe(file);
-
-                    file.on('error', async error => {
-                        await errorHandler(image.itemFk, error, filePath);
-                    });
-
-                    file.on('finish', async function() {
-                        try {
-                            await models.Image.registerImage('catalog', fileName, filePath);
-                            await image.destroy();
-                        } catch (error) {
-                            await errorHandler(image.itemFk, error, filePath);
+                            return await errorHandler(image.itemFk, error, filePath);
                         }
+
+                        response.pipe(writeStream);
+                    }).on('error', async error => {
+                        await errorHandler(image.itemFk, error, filePath);
                     });
-                }).on('error', async error => {
+                });
+
+                writeStream.on('error', async error => {
                     await errorHandler(image.itemFk, error, filePath);
                 });
-            }, 500);
+
+                writeStream.on('finish', async function() {
+                    try {
+                        await models.Image.registerImage('catalog', fileName, filePath);
+                        await image.destroy();
+                    } catch (error) {
+                        await errorHandler(image.itemFk, error, filePath);
+                    }
+                });
+            }, 1000);
         } catch (error) {
             await errorHandler(image.itemFk, error);
         }

From 4ef540c8f3e8b94dfedca96574a8e67122a69feb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 18 Aug 2020 09:48:02 +0200
Subject: [PATCH 032/109] Changed download path

---
 back/models/image.js                                         | 3 +--
 modules/item/back/methods/item-image-queue/downloadImages.js | 4 +---
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/back/models/image.js b/back/models/image.js
index f1eb09c9e5..340b2e5a60 100644
--- a/back/models/image.js
+++ b/back/models/image.js
@@ -4,8 +4,7 @@ const path = require('path');
 
 module.exports = Self => {
     Self.getPath = function() {
-        // return '/var/lib/salix/image';
-        return 'C:\\Users\\jsanc\\Desktop\\image';
+        return '/var/lib/salix/image';
     };
 
     Self.registerImage = async(collectionName, file, srcFilePath) => {
diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index f295f420ee..bd22bc2810 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -20,9 +20,7 @@ module.exports = Self => {
         const models = Self.app.models;
 
         try {
-            /* const tempPath = path.join('/tmp/salix-image'); */
-            const rootPath = models.Image.getPath();
-            const tempPath = path.join(rootPath, 'temp');
+            const tempPath = path.join('/tmp/salix-image');
 
             // Create temporary path
             await fs.mkdir(tempPath, {recursive: true});

From 540d5e9e718df0af9eaa2ead1ad198baf354c51a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 18 Aug 2020 13:50:08 +0200
Subject: [PATCH 033/109] Fixed errors

---
 modules/worker/front/calendar/index.js      |  5 +++++
 modules/worker/front/calendar/index.spec.js | 25 +++++++++++++++++++++
 modules/worker/front/calendar/locale/es.yml |  3 ++-
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/modules/worker/front/calendar/index.js b/modules/worker/front/calendar/index.js
index 7bbdb894ee..0067251727 100644
--- a/modules/worker/front/calendar/index.js
+++ b/modules/worker/front/calendar/index.js
@@ -19,6 +19,8 @@ class Controller extends Section {
         newYear.setFullYear(value);
 
         this.date = newYear;
+
+        this.refresh().then(() => this.repaint());
     }
 
     get date() {
@@ -140,6 +142,9 @@ class Controller extends Section {
         if (!this.absenceType)
             return this.vnApp.showMessage(this.$t('Choose an absence type from the right menu'));
 
+        if (this.year != new Date().getFullYear())
+            return this.vnApp.showMessage(this.$t('You can just add absences within the current year'));
+
         const day = $days[0];
         const stamp = day.getTime();
         const event = this.events[stamp];
diff --git a/modules/worker/front/calendar/index.spec.js b/modules/worker/front/calendar/index.spec.js
index 6b5025dae4..7637f3a16b 100644
--- a/modules/worker/front/calendar/index.spec.js
+++ b/modules/worker/front/calendar/index.spec.js
@@ -30,11 +30,14 @@ describe('Worker', () => {
 
         describe('year() setter', () => {
             it(`should set the year of the calendar date`, () => {
+                jest.spyOn(controller, 'refresh').mockReturnValue(new Promise());
+
                 const previousYear = year - 1;
                 controller.year = previousYear;
 
                 expect(controller.year).toEqual(previousYear);
                 expect(controller.date.getFullYear()).toEqual(previousYear);
+                expect(controller.refresh).toHaveBeenCalledWith();
             });
         });
 
@@ -157,6 +160,28 @@ describe('Worker', () => {
                 expect(controller.vnApp.showMessage).toHaveBeenCalledWith('Choose an absence type from the right menu');
             });
 
+            it(`should show an snackbar message if the selected day is not within the current year`, () => {
+                jest.spyOn(controller.vnApp, 'showMessage').mockReturnThis();
+
+                const selectedDay = new Date();
+                const $event = {
+                    target: {
+                        closest: () => {
+                            return {$ctrl: {}};
+                        }
+                    }
+                };
+                const $days = [selectedDay];
+                const pastYear = new Date();
+                pastYear.setFullYear(pastYear.getFullYear() - 1);
+
+                controller.date = pastYear;
+                controller.absenceType = {id: 1};
+                controller.onSelection($event, $days);
+
+                expect(controller.vnApp.showMessage).toHaveBeenCalledWith('You can just add absences within the current year');
+            });
+
             it(`should call to the create() method`, () => {
                 jest.spyOn(controller, 'create').mockReturnThis();
 
diff --git a/modules/worker/front/calendar/locale/es.yml b/modules/worker/front/calendar/locale/es.yml
index f48a67c7bd..68a9cf54d6 100644
--- a/modules/worker/front/calendar/locale/es.yml
+++ b/modules/worker/front/calendar/locale/es.yml
@@ -5,4 +5,5 @@ Year: Año
 of: de
 days: días
 Choose an absence type from the right menu: Elige un tipo de ausencia desde el menú de la derecha
-To start adding absences, click an absence type from the right menu and then on the day you want to add an absence: Para empezar a añadir ausencias, haz clic en un tipo de ausencia desde el menu de la derecha y después en el día que quieres añadir la ausencia
\ No newline at end of file
+To start adding absences, click an absence type from the right menu and then on the day you want to add an absence: Para empezar a añadir ausencias, haz clic en un tipo de ausencia desde el menu de la derecha y después en el día que quieres añadir la ausencia
+You can just add absences within the current year: Solo puedes añadir ausencias dentro del año actual
\ No newline at end of file

From 1bcf4ff8a6a63c413e1d229470355ed3b99d9bd3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 18 Aug 2020 13:55:38 +0200
Subject: [PATCH 034/109] Descomentado test

---
 e2e/paths/03-worker/05_calendar.spec.js | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/e2e/paths/03-worker/05_calendar.spec.js b/e2e/paths/03-worker/05_calendar.spec.js
index 8f3ab4ba36..9be92e242b 100644
--- a/e2e/paths/03-worker/05_calendar.spec.js
+++ b/e2e/paths/03-worker/05_calendar.spec.js
@@ -1,7 +1,7 @@
 import selectors from '../../helpers/selectors.js';
 import getBrowser from '../../helpers/puppeteer';
 
-describe('Worker calendar path', () => {
+fdescribe('Worker calendar path', () => {
     let reasonableTimeBetweenClicks = 400;
     let browser;
     let page;
@@ -122,17 +122,16 @@ describe('Worker calendar path', () => {
             expect(result).toContain(' 5 ');
         });
 
-        // #1361 worker.calendar "hopefully this test works straight away after refreshing holidays per year on each filtering."
-        // it('should use the year selector to go to the previous year', async() => {
-        //     const date = new Date();
-        //     const lastYear = (date.getFullYear() - 1).toString();
+        it('should use the year selector to go to the previous year', async() => {
+            const date = new Date();
+            const lastYear = (date.getFullYear() - 1).toString();
 
-        //     await page.autocompleteSearch(selectors.workerCalendar.year, lastYear);
+            await page.autocompleteSearch(selectors.workerCalendar.year, lastYear);
 
-        //     await page.waitFor(reasonableTimeBetweenClicks);
-        //     const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
+            await page.waitFor(reasonableTimeBetweenClicks);
+            const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
 
-        //     expect(result).toContain(' 0 ');
-        // });
+            expect(result).toContain(' 0 ');
+        });
     });
 });

From 1990f5172c8d1cae9a47f4dda5ff5f59816de08f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 18 Aug 2020 13:57:34 +0200
Subject: [PATCH 035/109] Removed focus

---
 e2e/paths/03-worker/05_calendar.spec.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/e2e/paths/03-worker/05_calendar.spec.js b/e2e/paths/03-worker/05_calendar.spec.js
index 9be92e242b..801ff4151c 100644
--- a/e2e/paths/03-worker/05_calendar.spec.js
+++ b/e2e/paths/03-worker/05_calendar.spec.js
@@ -1,7 +1,7 @@
 import selectors from '../../helpers/selectors.js';
 import getBrowser from '../../helpers/puppeteer';
 
-fdescribe('Worker calendar path', () => {
+describe('Worker calendar path', () => {
     let reasonableTimeBetweenClicks = 400;
     let browser;
     let page;

From cacf562954bc09142d71146cde8ec48f10f798c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 18 Aug 2020 14:01:43 +0200
Subject: [PATCH 036/109] Audit fix

---
 package-lock.json       |  38 +++---
 print/package-lock.json | 278 ++++++----------------------------------
 2 files changed, 60 insertions(+), 256 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 92030199ae..c405cbc0e7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -170,9 +170,9 @@
             },
             "dependencies": {
                 "lodash": {
-                    "version": "4.17.15",
-                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-                    "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
                     "dev": true
                 }
             }
@@ -2132,9 +2132,9 @@
                     }
                 },
                 "lodash": {
-                    "version": "4.17.15",
-                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-                    "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
                     "dev": true
                 },
                 "ms": {
@@ -2157,9 +2157,9 @@
             },
             "dependencies": {
                 "lodash": {
-                    "version": "4.17.15",
-                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-                    "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+                    "version": "4.17.20",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+                    "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
                     "dev": true
                 }
             }
@@ -7760,9 +7760,9 @@
             "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug=="
         },
         "dot-prop": {
-            "version": "4.2.0",
-            "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
-            "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+            "version": "4.2.1",
+            "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz",
+            "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==",
             "requires": {
                 "is-obj": "^1.0.0"
             }
@@ -7873,9 +7873,9 @@
             "dev": true
         },
         "elliptic": {
-            "version": "6.5.2",
-            "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
-            "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
+            "version": "6.5.3",
+            "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+            "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
             "dev": true,
             "requires": {
                 "bn.js": "^4.4.0",
@@ -12228,7 +12228,7 @@
         },
         "is-obj": {
             "version": "1.0.1",
-            "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+            "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
             "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
         },
         "is-path-cwd": {
@@ -17702,9 +17702,9 @@
             }
         },
         "lodash": {
-            "version": "4.17.15",
-            "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-            "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
+            "version": "4.17.20",
+            "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+            "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
         },
         "lodash._basecopy": {
             "version": "3.0.1",
diff --git a/print/package-lock.json b/print/package-lock.json
index 1020b8750a..c060030448 100644
--- a/print/package-lock.json
+++ b/print/package-lock.json
@@ -4,20 +4,10 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
-    "@types/node": {
-      "version": "14.0.27",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz",
-      "integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==",
-      "optional": true
-    },
-    "@types/yauzl": {
-      "version": "2.9.1",
-      "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
-      "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
-      "optional": true,
-      "requires": {
-        "@types/node": "*"
-      }
+    "@types/mime-types": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.0.tgz",
+      "integrity": "sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM="
     },
     "agent-base": {
       "version": "5.1.1",
@@ -74,6 +64,11 @@
       "resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz",
       "integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ=="
     },
+    "async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
+    },
     "asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -94,11 +89,6 @@
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
       "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
     },
-    "base64-js": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
-      "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
-    },
     "bcrypt-pbkdf": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -107,23 +97,6 @@
         "tweetnacl": "^0.14.3"
       }
     },
-    "bl": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz",
-      "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==",
-      "requires": {
-        "buffer": "^5.5.0",
-        "inherits": "^2.0.4",
-        "readable-stream": "^3.4.0"
-      },
-      "dependencies": {
-        "inherits": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-          "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
-        }
-      }
-    },
     "boolbase": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@@ -138,25 +111,10 @@
         "concat-map": "0.0.1"
       }
     },
-    "buffer": {
-      "version": "5.6.0",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
-      "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
-      "requires": {
-        "base64-js": "^1.0.2",
-        "ieee754": "^1.1.4"
-      }
-    },
-    "buffer-crc32": {
-      "version": "0.2.13",
-      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
-    },
     "buffer-from": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
-      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
-      "optional": true
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
     },
     "camelcase": {
       "version": "5.3.1",
@@ -201,11 +159,6 @@
         "lodash.some": "^4.4.0"
       }
     },
-    "chownr": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
-      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
-    },
     "cliui": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
@@ -266,7 +219,6 @@
       "version": "1.6.2",
       "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
       "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
-      "optional": true,
       "requires": {
         "buffer-from": "^1.0.0",
         "inherits": "^2.0.3",
@@ -278,7 +230,6 @@
           "version": "2.3.6",
           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
           "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-          "optional": true,
           "requires": {
             "core-util-is": "~1.0.0",
             "inherits": "~2.0.3",
@@ -293,7 +244,6 @@
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
           "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "optional": true,
           "requires": {
             "safe-buffer": "~5.1.0"
           }
@@ -354,7 +304,6 @@
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
       "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "optional": true,
       "requires": {
         "ms": "2.0.0"
       }
@@ -379,11 +328,6 @@
       "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
       "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
     },
-    "devtools-protocol": {
-      "version": "0.0.781568",
-      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.781568.tgz",
-      "integrity": "sha512-9Uqnzy6m6zEStluH9iyJ3iHyaQziFnMnLeC8vK0eN6smiJmIx7+yB64d67C2lH/LZra+5cGscJAJsNXO+MdPMg=="
-    },
     "dijkstrajs": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
@@ -434,14 +378,6 @@
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
       "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
     },
-    "end-of-stream": {
-      "version": "1.4.4",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
-      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
-      "requires": {
-        "once": "^1.4.0"
-      }
-    },
     "entities": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
@@ -472,7 +408,6 @@
       "version": "1.6.7",
       "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
       "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
-      "optional": true,
       "requires": {
         "concat-stream": "1.6.2",
         "debug": "2.6.9",
@@ -499,7 +434,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
       "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
-      "optional": true,
       "requires": {
         "pend": "~1.2.0"
       }
@@ -527,11 +461,6 @@
         "mime-types": "^2.1.12"
       }
     },
-    "fs-constants": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
-      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
-    },
     "fs-extra": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
@@ -560,14 +489,6 @@
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
       "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
     },
-    "get-stream": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
-      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-      "requires": {
-        "pump": "^3.0.0"
-      }
-    },
     "getpass": {
       "version": "0.1.7",
       "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@@ -704,11 +625,6 @@
         "safer-buffer": ">= 2.1.2 < 3"
       }
     },
-    "ieee754": {
-      "version": "1.1.13",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
-      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
-    },
     "image-size": {
       "version": "0.7.5",
       "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz",
@@ -757,8 +673,7 @@
     "isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "optional": true
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
     },
     "isexe": {
       "version": "2.0.0",
@@ -1000,28 +915,20 @@
     "minimist": {
       "version": "0.0.8",
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-      "optional": true
+      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
     },
     "mkdirp": {
       "version": "0.5.1",
       "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
       "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-      "optional": true,
       "requires": {
         "minimist": "0.0.8"
       }
     },
-    "mkdirp-classic": {
-      "version": "0.5.3",
-      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
-      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
-    },
     "ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "optional": true
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
     },
     "mysql2": {
       "version": "1.7.0",
@@ -1198,46 +1105,6 @@
         "pinkie": "^2.0.0"
       }
     },
-    "pkg-dir": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
-      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
-      "requires": {
-        "find-up": "^4.0.0"
-      },
-      "dependencies": {
-        "find-up": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
-          "requires": {
-            "locate-path": "^5.0.0",
-            "path-exists": "^4.0.0"
-          }
-        },
-        "locate-path": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
-          "requires": {
-            "p-locate": "^4.1.0"
-          }
-        },
-        "p-locate": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
-          "requires": {
-            "p-limit": "^2.2.0"
-          }
-        },
-        "path-exists": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
-        }
-      }
-    },
     "pngjs": {
       "version": "3.4.0",
       "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
@@ -1246,8 +1113,7 @@
     "process-nextick-args": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-      "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
-      "optional": true
+      "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
     },
     "progress": {
       "version": "1.1.8",
@@ -1270,37 +1136,26 @@
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
       "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw=="
     },
-    "pump": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
-      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
-      "requires": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
-      }
-    },
     "punycode": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
       "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
     },
     "puppeteer": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-5.2.1.tgz",
-      "integrity": "sha512-PZoZG7u+T6N1GFWBQmGVG162Ak5MAy8nYSVpeeQrwJK2oYUlDWpHEJPcd/zopyuEMTv7DiztS1blgny1txR2qw==",
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-2.1.1.tgz",
+      "integrity": "sha512-LWzaDVQkk1EPiuYeTOj+CZRIjda4k2s5w4MK4xoH2+kgWV/SDlkYHmxatDdtYrciHUKSXTsGgPgPP8ILVdBsxg==",
       "requires": {
+        "@types/mime-types": "^2.1.0",
         "debug": "^4.1.0",
-        "devtools-protocol": "0.0.781568",
-        "extract-zip": "^2.0.0",
+        "extract-zip": "^1.6.6",
         "https-proxy-agent": "^4.0.0",
         "mime": "^2.0.3",
-        "pkg-dir": "^4.2.0",
+        "mime-types": "^2.1.25",
         "progress": "^2.0.1",
         "proxy-from-env": "^1.0.0",
-        "rimraf": "^3.0.2",
-        "tar-fs": "^2.0.0",
-        "unbzip2-stream": "^1.3.3",
-        "ws": "^7.2.3"
+        "rimraf": "^2.6.1",
+        "ws": "^6.1.0"
       },
       "dependencies": {
         "debug": {
@@ -1311,23 +1166,17 @@
             "ms": "^2.1.1"
           }
         },
-        "extract-zip": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
-          "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
-          "requires": {
-            "@types/yauzl": "^2.9.1",
-            "debug": "^4.1.1",
-            "get-stream": "^5.1.0",
-            "yauzl": "^2.10.0"
-          }
+        "mime-db": {
+          "version": "1.44.0",
+          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+          "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
         },
-        "fd-slicer": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
-          "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+        "mime-types": {
+          "version": "2.1.27",
+          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+          "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
           "requires": {
-            "pend": "~1.2.0"
+            "mime-db": "1.44.0"
           }
         },
         "ms": {
@@ -1339,15 +1188,6 @@
           "version": "2.0.3",
           "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
           "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
-        },
-        "yauzl": {
-          "version": "2.10.0",
-          "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
-          "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
-          "requires": {
-            "buffer-crc32": "~0.2.3",
-            "fd-slicer": "~1.1.0"
-          }
         }
       }
     },
@@ -1439,9 +1279,9 @@
       }
     },
     "rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
       "requires": {
         "glob": "^7.1.3"
       }
@@ -1586,40 +1426,12 @@
         "has-flag": "^3.0.0"
       }
     },
-    "tar-fs": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz",
-      "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==",
-      "requires": {
-        "chownr": "^1.1.1",
-        "mkdirp-classic": "^0.5.2",
-        "pump": "^3.0.0",
-        "tar-stream": "^2.0.0"
-      }
-    },
-    "tar-stream": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz",
-      "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==",
-      "requires": {
-        "bl": "^4.0.1",
-        "end-of-stream": "^1.4.1",
-        "fs-constants": "^1.0.0",
-        "inherits": "^2.0.3",
-        "readable-stream": "^3.1.1"
-      }
-    },
     "throttleit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
       "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
       "optional": true
     },
-    "through": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
-    },
     "tough-cookie": {
       "version": "2.4.3",
       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
@@ -1652,17 +1464,7 @@
     "typedarray": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
-      "optional": true
-    },
-    "unbzip2-stream": {
-      "version": "1.4.3",
-      "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
-      "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
-      "requires": {
-        "buffer": "^5.2.1",
-        "through": "^2.3.8"
-      }
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
     },
     "universalify": {
       "version": "0.1.2",
@@ -1819,9 +1621,12 @@
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
     },
     "ws": {
-      "version": "7.3.1",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
-      "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA=="
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
+      "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+      "requires": {
+        "async-limiter": "~1.0.0"
+      }
     },
     "xtend": {
       "version": "4.0.2",
@@ -1868,7 +1673,6 @@
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
       "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
-      "optional": true,
       "requires": {
         "fd-slicer": "~1.0.1"
       }

From a3d3ed4aba161908f1f82f694df69ce337daad7b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 18 Aug 2020 14:14:34 +0200
Subject: [PATCH 037/109] Fixed unit test

---
 modules/worker/front/calendar/index.spec.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/worker/front/calendar/index.spec.js b/modules/worker/front/calendar/index.spec.js
index 7637f3a16b..ebf52dc663 100644
--- a/modules/worker/front/calendar/index.spec.js
+++ b/modules/worker/front/calendar/index.spec.js
@@ -30,7 +30,7 @@ describe('Worker', () => {
 
         describe('year() setter', () => {
             it(`should set the year of the calendar date`, () => {
-                jest.spyOn(controller, 'refresh').mockReturnValue(new Promise());
+                jest.spyOn(controller, 'refresh').mockReturnValue(Promise.resolve());
 
                 const previousYear = year - 1;
                 controller.year = previousYear;

From f0818acf32fab07d34bae05f9dcde2d7e74862cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Wed, 19 Aug 2020 13:04:12 +0200
Subject: [PATCH 038/109] 2387 - Fixed error when deleting a zone

---
 .../10210-summer/00-ticket_beforeUpdate.sql   | 31 +++++++++++++++++++
 modules/zone/back/methods/zone/deleteZone.js  |  9 +++---
 modules/zone/front/descriptor/locale/es.yml   |  2 +-
 3 files changed, 37 insertions(+), 5 deletions(-)
 create mode 100644 db/changes/10210-summer/00-ticket_beforeUpdate.sql

diff --git a/db/changes/10210-summer/00-ticket_beforeUpdate.sql b/db/changes/10210-summer/00-ticket_beforeUpdate.sql
new file mode 100644
index 0000000000..fa1cb6c5fc
--- /dev/null
+++ b/db/changes/10210-summer/00-ticket_beforeUpdate.sql
@@ -0,0 +1,31 @@
+DROP TRIGGER IF EXISTS `vn`.`ticket_beforeUpdate`;
+
+DELIMITER $$
+USE `vn`$$
+CREATE DEFINER=`root`@`%` TRIGGER `ticket_beforeUpdate`
+	BEFORE UPDATE ON `ticket`
+    FOR EACH ROW
+BEGIN
+	IF !(NEW.shipped <=> OLD.shipped) THEN
+		IF YEAR(NEW.shipped) < 2000 THEN
+			SIGNAL SQLSTATE '46000'
+				SET MESSAGE_TEXT = 'Year cannot be lesser than 2000';
+		END IF;
+
+		IF YEAR(NEW.shipped) = 2000 THEN
+			SET NEW.isDeleted = TRUE;
+		END IF;
+	END IF;
+	
+	IF !(NEW.isDeleted <=> OLD.isDeleted) AND NEW.isDeleted THEN
+		SET NEW.shipped = DATE_FORMAT(NEW.shipped, '2000-%m-%d %T');
+		SET NEW.landed = DATE_FORMAT(NEW.landed, '2000-%m-%d %T');
+		SET NEW.routeFk = NULL;
+        SET NEW.zoneFk = NULL;
+	END IF;
+
+    IF NEW.routeFk  AND NEW.isDeleted   THEN 
+		CALL util.throw ('This ticket is deleted');
+	END IF;
+END$$
+DELIMITER ;
diff --git a/modules/zone/back/methods/zone/deleteZone.js b/modules/zone/back/methods/zone/deleteZone.js
index baa4424911..7bf807f7d3 100644
--- a/modules/zone/back/methods/zone/deleteZone.js
+++ b/modules/zone/back/methods/zone/deleteZone.js
@@ -29,7 +29,8 @@ module.exports = Self => {
             const options = {transaction: tx};
             const filter = {
                 where: {
-                    zoneFk: id
+                    zoneFk: id,
+                    shipped: {gte: today}
                 },
                 include: {
                     relation: 'ticketState',
@@ -46,10 +47,10 @@ module.exports = Self => {
                 where: {userFk: userId}
             }, options);
 
-            ticketList.forEach(ticket => {
-                promises.push(ticket.updateAttributes({zoneFk: null}, options));
+            await models.Ticket.rawSql('UPDATE ticket SET zoneFk = NULL WHERE zoneFk = ?', [id], options);
 
-                if (ticket.ticketState().alertLevel == 0 && ticket.shipped >= today) {
+            ticketList.forEach(ticket => {
+                if (ticket.ticketState().alertLevel == 0) {
                     promises.push(models.TicketTracking.create({
                         ticketFk: ticket.id,
                         stateFk: fixingState.id,
diff --git a/modules/zone/front/descriptor/locale/es.yml b/modules/zone/front/descriptor/locale/es.yml
index 67bcbb5b7c..0581ee93a0 100644
--- a/modules/zone/front/descriptor/locale/es.yml
+++ b/modules/zone/front/descriptor/locale/es.yml
@@ -1,4 +1,4 @@
-This zone contains tickets: Esta zona contiene {{ticketsAmount}} tickets. ¿Seguro que quieres eliminar esta zona?
+This zone contains tickets: Esta zona contiene {{ticketsAmount}} tickets por servir. ¿Seguro que quieres eliminar esta zona?
 Do you want to clone this zone?: ¿Quieres clonar esta zona?
 All it's properties will be copied: Todas sus propiedades serán copiadas
 Zone deleted: Zona eliminada
\ No newline at end of file

From 7fdfd92a1cf673cdfc40568c64cc0199ba1406cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Wed, 19 Aug 2020 13:13:16 +0200
Subject: [PATCH 039/109] Removed sql

---
 .../10210-summer/00-ticket_beforeUpdate.sql   | 31 -------------------
 1 file changed, 31 deletions(-)
 delete mode 100644 db/changes/10210-summer/00-ticket_beforeUpdate.sql

diff --git a/db/changes/10210-summer/00-ticket_beforeUpdate.sql b/db/changes/10210-summer/00-ticket_beforeUpdate.sql
deleted file mode 100644
index fa1cb6c5fc..0000000000
--- a/db/changes/10210-summer/00-ticket_beforeUpdate.sql
+++ /dev/null
@@ -1,31 +0,0 @@
-DROP TRIGGER IF EXISTS `vn`.`ticket_beforeUpdate`;
-
-DELIMITER $$
-USE `vn`$$
-CREATE DEFINER=`root`@`%` TRIGGER `ticket_beforeUpdate`
-	BEFORE UPDATE ON `ticket`
-    FOR EACH ROW
-BEGIN
-	IF !(NEW.shipped <=> OLD.shipped) THEN
-		IF YEAR(NEW.shipped) < 2000 THEN
-			SIGNAL SQLSTATE '46000'
-				SET MESSAGE_TEXT = 'Year cannot be lesser than 2000';
-		END IF;
-
-		IF YEAR(NEW.shipped) = 2000 THEN
-			SET NEW.isDeleted = TRUE;
-		END IF;
-	END IF;
-	
-	IF !(NEW.isDeleted <=> OLD.isDeleted) AND NEW.isDeleted THEN
-		SET NEW.shipped = DATE_FORMAT(NEW.shipped, '2000-%m-%d %T');
-		SET NEW.landed = DATE_FORMAT(NEW.landed, '2000-%m-%d %T');
-		SET NEW.routeFk = NULL;
-        SET NEW.zoneFk = NULL;
-	END IF;
-
-    IF NEW.routeFk  AND NEW.isDeleted   THEN 
-		CALL util.throw ('This ticket is deleted');
-	END IF;
-END$$
-DELIMITER ;

From 4d8a84e774698fe41e57e5162547890dae26be78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 20 Aug 2020 08:45:03 +0200
Subject: [PATCH 040/109] Fixed back unit tests

---
 db/dump/fixtures.sql                          |  8 ++---
 modules/ticket/back/methods/ticket/filter.js  |  2 +-
 .../ticket/specs/deleteStowaway.spec.js       |  4 +--
 .../back/methods/ticket/specs/filter.spec.js  | 33 +++++++++++++++----
 modules/ticket/front/main/index.html          |  3 +-
 modules/ticket/front/main/index.js            | 11 +++++--
 6 files changed, 43 insertions(+), 18 deletions(-)

diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index ccc1b7d1d6..2b70cf2bee 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -601,11 +601,11 @@ INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `workerFk`, `created`)
         (12, 3,  19, NOW()),
         (13, 3,  19, NOW()),
         (14, 3,  19, NOW()),
-        (15, 3,  19, NOW()),
+        (15, 2,  19, NOW()),
         (16, 3,  19, NOW()),
-        (17, 3,  19, NOW()),
-        (18, 3,  19, NOW()),
-        (19, 3,  19, NOW()),
+        (17, 2,  19, NOW()),
+        (18, 2,  19, NOW()),
+        (19, 2,  19, NOW()),
         (20, 1,  19, DATE_ADD(NOW(), INTERVAL +1 MONTH)),
         (21, 1,  19, DATE_ADD(NOW(), INTERVAL +1 MONTH)),
         (22, 1,  19, DATE_ADD(NOW(), INTERVAL +1 MONTH)),
diff --git a/modules/ticket/back/methods/ticket/filter.js b/modules/ticket/back/methods/ticket/filter.js
index ddb55301bd..3a34be4429 100644
--- a/modules/ticket/back/methods/ticket/filter.js
+++ b/modules/ticket/back/methods/ticket/filter.js
@@ -265,7 +265,7 @@ module.exports = Self => {
                     LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id
                     LEFT JOIN tmp.ticketTotal tt ON tt.ticketFk = f.id`);
 
-        if (args.problems != undefined && (!args.from || !args.to))
+        if (args.problems != undefined && (!args.from && !args.to))
             throw new UserError('Choose a date range or days forward');
 
         let condition;
diff --git a/modules/ticket/back/methods/ticket/specs/deleteStowaway.spec.js b/modules/ticket/back/methods/ticket/specs/deleteStowaway.spec.js
index bd6fd327ab..56375940d0 100644
--- a/modules/ticket/back/methods/ticket/specs/deleteStowaway.spec.js
+++ b/modules/ticket/back/methods/ticket/specs/deleteStowaway.spec.js
@@ -17,7 +17,7 @@ describe('ticket deleteStowaway()', () => {
         await app.models.Stowaway.rawSql(
             `CALL ticketStateUpdate(?, ?)`, [shipId, 'OK']);
         await app.models.Stowaway.rawSql(
-            `CALL ticketStateUpdate(?, ?)`, [stowawayId, 'OK']);
+            `CALL ticketStateUpdate(?, ?)`, [stowawayId, 'FREE']);
     });
 
     it('should create an stowaway', async() => {
@@ -97,6 +97,6 @@ describe('ticket deleteStowaway()', () => {
             }
         });
 
-        expect(shipState.name).toEqual('OK');
+        expect(shipState.name).toEqual('Libre');
     });
 });
diff --git a/modules/ticket/back/methods/ticket/specs/filter.spec.js b/modules/ticket/back/methods/ticket/specs/filter.spec.js
index 4aa1b3a774..312b95ad58 100644
--- a/modules/ticket/back/methods/ticket/specs/filter.spec.js
+++ b/modules/ticket/back/methods/ticket/specs/filter.spec.js
@@ -11,7 +11,16 @@ describe('ticket filter()', () => {
     });
 
     it('should return the tickets matching the problems on true', async() => {
-        const ctx = {req: {accessToken: {userId: 9}}, args: {problems: true}};
+        const yesterday = new Date();
+        yesterday.setHours(0, 0, 0, 0);
+        const today = new Date();
+        today.setHours(23, 59, 59, 59);
+
+        const ctx = {req: {accessToken: {userId: 9}}, args: {
+            problems: true,
+            from: yesterday,
+            to: today
+        }};
         const filter = {};
         const result = await app.models.Ticket.filter(ctx, filter);
 
@@ -19,11 +28,21 @@ describe('ticket filter()', () => {
     });
 
     it('should return the tickets matching the problems on false', async() => {
-        const ctx = {req: {accessToken: {userId: 9}}, args: {problems: false}};
+        const yesterday = new Date();
+        yesterday.setDate(yesterday.getDate() - 1);
+        yesterday.setHours(0, 0, 0, 0);
+        const today = new Date();
+        today.setHours(23, 59, 59, 59);
+
+        const ctx = {req: {accessToken: {userId: 9}}, args: {
+            problems: false,
+            from: yesterday,
+            to: today
+        }};
         const filter = {};
         const result = await app.models.Ticket.filter(ctx, filter);
 
-        expect(result.length).toEqual(20);
+        expect(result.length).toEqual(11);
     });
 
     it('should return the tickets matching the problems on null', async() => {
@@ -52,10 +71,10 @@ describe('ticket filter()', () => {
         const secondRow = result[1];
         const thirdRow = result[2];
 
-        expect(result.length).toEqual(3);
-        expect(firstRow.state).toEqual('Arreglar');
-        expect(secondRow.state).toEqual('Arreglar');
-        expect(thirdRow.state).toEqual('Arreglar');
+        expect(result.length).toEqual(7);
+        expect(firstRow.state).toEqual('Libre');
+        expect(secondRow.state).toEqual('Libre');
+        expect(thirdRow.state).toEqual('Libre');
     });
 
     it('should return the tickets that are not pending', async() => {
diff --git a/modules/ticket/front/main/index.html b/modules/ticket/front/main/index.html
index a21b28992a..7a02ce8cae 100644
--- a/modules/ticket/front/main/index.html
+++ b/modules/ticket/front/main/index.html
@@ -9,7 +9,8 @@
         panel="vn-ticket-search-panel"
         info="Search ticket by id or alias"
         model="model"
-        fetch-params="$ctrl.fetchParams($params)">
+        fetch-params="$ctrl.fetchParams($params)"
+        suggested-filter="$ctrl.defaultFilter">
     </vn-searchbar>
 </vn-portal>
 <vn-portal slot="menu">
diff --git a/modules/ticket/front/main/index.js b/modules/ticket/front/main/index.js
index bd47181766..6b919c474a 100644
--- a/modules/ticket/front/main/index.js
+++ b/modules/ticket/front/main/index.js
@@ -2,10 +2,15 @@ import ngModule from '../module';
 import ModuleMain from 'salix/components/module-main';
 
 export default class Ticket extends ModuleMain {
-    fetchParams($params) {
-        if (!Object.entries($params).length)
-            $params.scopeDays = 1;
+    constructor() {
+        super();
 
+        this.defaultFilter = {
+            scopeDays: 1
+        };
+    }
+
+    fetchParams($params) {
         if (typeof $params.scopeDays === 'number') {
             const from = new Date();
             from.setHours(0, 0, 0, 0);

From 80e1577d4ff8e0258129748a0920e560631fbbff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 20 Aug 2020 09:50:22 +0200
Subject: [PATCH 041/109] Updated e2e

---
 e2e/paths/05-ticket/18_index_payout.spec.js | 2 +-
 modules/ticket/front/main/index.js          | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/e2e/paths/05-ticket/18_index_payout.spec.js b/e2e/paths/05-ticket/18_index_payout.spec.js
index b1dc06e51e..37e5261dc5 100644
--- a/e2e/paths/05-ticket/18_index_payout.spec.js
+++ b/e2e/paths/05-ticket/18_index_payout.spec.js
@@ -19,7 +19,7 @@ describe('Ticket index payout path', () => {
         await page.waitForState('ticket.index');
     });
 
-    it('should check three tickets 2 of a clinet and 1 of another', async() => {
+    it('should check the second ticket from a client and 1 of another', async() => {
         await page.keyboard.press('Enter');
         await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox);
         await page.waitToClick(selectors.ticketsIndex.sixthTicketCheckbox);
diff --git a/modules/ticket/front/main/index.js b/modules/ticket/front/main/index.js
index 6b919c474a..9bbedbcc96 100644
--- a/modules/ticket/front/main/index.js
+++ b/modules/ticket/front/main/index.js
@@ -11,6 +11,9 @@ export default class Ticket extends ModuleMain {
     }
 
     fetchParams($params) {
+        if (!Object.entries($params).length)
+            $params.scopeDays = 1;
+
         if (typeof $params.scopeDays === 'number') {
             const from = new Date();
             from.setHours(0, 0, 0, 0);

From 957c1c01b90c13cd16a7be7879ad12ab2329b4d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 24 Aug 2020 07:54:30 +0200
Subject: [PATCH 042/109] Html changes

---
 modules/client/front/address/index/index.html | 6 +++++-
 modules/client/front/address/index/index.js   | 3 ++-
 modules/route/front/summary/index.html        | 2 +-
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/modules/client/front/address/index/index.html b/modules/client/front/address/index/index.html
index bd5d10fd26..51b3101282 100644
--- a/modules/client/front/address/index/index.html
+++ b/modules/client/front/address/index/index.html
@@ -46,7 +46,11 @@
                 style="overflow: hidden; min-width: 14em;">
                 <div class="ellipsize"><b>{{::address.nickname}} - #{{::address.id}}</b></div>
                 <div class="ellipsize" name="street">{{::address.street}}</div>
-                <div class="ellipsize">{{::address.city}}, {{::address.province.name}}</div>
+                <div class="ellipsize">
+                    <span ng-show="::address.postalCode">{{::address.postalCode}} -</span> 
+                    <span ng-show="::address.city">{{::address.city}},</span> 
+                    {{::address.province.name}}
+                </div>
                 <div class="ellipsize">
                     {{::address.phone}}<span ng-if="::address.mobile">, </span>
                     {{::address.mobile}}
diff --git a/modules/client/front/address/index/index.js b/modules/client/front/address/index/index.js
index ea6a9f6b96..3a2b5dfa82 100644
--- a/modules/client/front/address/index/index.js
+++ b/modules/client/front/address/index/index.js
@@ -16,7 +16,8 @@ class Controller extends Section {
                 'provinceFk',
                 'phone',
                 'mobile',
-                'isEqualizated'
+                'isEqualizated',
+                'postalCode'
             ],
             order: [
                 'isDefaultAddress DESC',
diff --git a/modules/route/front/summary/index.html b/modules/route/front/summary/index.html
index d99f5e0125..b2c9255e07 100644
--- a/modules/route/front/summary/index.html
+++ b/modules/route/front/summary/index.html
@@ -71,7 +71,7 @@
                             <span 
                                 ng-click="ticketDescriptor.show($event, ticket.id)"
                                 class="link">
-                                {{ticket.id | zeroFill:6}}
+                                {{ticket.id}}
                             </span>
                         </vn-td>
                         <vn-td>

From cd74e9684a04b56f1d60afd306f1de347f5bd8c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 25 Aug 2020 10:00:21 +0200
Subject: [PATCH 043/109] Download route PDF on route index

---
 modules/route/front/index/index.html          | 40 ++++++++++++++++---
 modules/route/front/index/index.js            | 34 ++++++++++++++++
 modules/route/front/index/locale/es.yml       |  1 +
 .../report-footer/assets/css/style.css        |  5 ++-
 print/core/report.js                          |  1 +
 .../reports/driver-route/assets/css/style.css |  5 +++
 .../reports/driver-route/driver-route.html    |  9 +++--
 .../reports/driver-route/driver-route.js      | 31 +++++++++-----
 8 files changed, 105 insertions(+), 21 deletions(-)

diff --git a/modules/route/front/index/index.html b/modules/route/front/index/index.html
index 16f6ad827b..7258018f10 100644
--- a/modules/route/front/index/index.html
+++ b/modules/route/front/index/index.html
@@ -8,6 +8,11 @@
     <vn-table model="model">
         <vn-thead>
             <vn-tr>
+                <vn-th shrink>
+                    <vn-multi-check 
+                        model="model">
+                    </vn-multi-check>
+                </vn-th>
                 <vn-th field="id" number>Id</vn-th>
                 <vn-th th-id="worker">Worker</vn-th>
                 <vn-th th-id="agency">Agency</vn-th>
@@ -22,6 +27,12 @@
             <a ng-repeat="route in model.data"
                 class="clickable vn-tr search-result"
                 ui-sref="route.card.summary({id: {{::route.id}}})">
+                <vn-td shrink>
+                    <vn-check 
+                        ng-model="route.checked"
+                        vn-click-stop>
+                    </vn-check>
+                </vn-td>
                 <vn-td number>{{::route.id | dashIfEmpty}}</vn-td>
                 <vn-td expand>
                     <span 
@@ -55,9 +66,26 @@
 <vn-worker-descriptor-popover 
     vn-id="workerDescriptor">
 </vn-worker-descriptor-popover>
-<a ui-sref="route.create"
-    vn-tooltip="New route"
-    vn-bind="+"
-    fixed-bottom-right>
-    <vn-float-button icon="add"></vn-float-button>
-</a>
\ No newline at end of file
+
+
+</vn-data-viewer>
+<div fixed-bottom-right>
+    <vn-vertical style="align-items: center;">
+        <vn-button class="round sm vn-mb-sm"
+            icon="cloud_download"
+            ng-show="$ctrl.totalChecked > 0"
+            ng-click="$ctrl.showRouteReport()"
+            vn-tooltip="Download selected routes as PDF"
+            tooltip-position="left">
+        </vn-button>
+
+        <a ui-sref="route.create">
+            <vn-button class="round md vn-mb-sm"
+                icon="add"
+                vn-bind="+"
+                vn-tooltip="New route"
+                tooltip-position="left">
+            </vn-button>
+        </a>
+    </vn-vertical>
+</div>
\ No newline at end of file
diff --git a/modules/route/front/index/index.js b/modules/route/front/index/index.js
index 400684a0d5..9afaa862cc 100644
--- a/modules/route/front/index/index.js
+++ b/modules/route/front/index/index.js
@@ -2,12 +2,46 @@ import ngModule from '../module';
 import Section from 'salix/components/section';
 
 export default class Controller extends Section {
+    constructor($element, $, vnReport) {
+        super($element, $);
+        this.vnReport = vnReport;
+    }
+
     preview(route) {
         this.routeSelected = route;
         this.$.summary.show();
     }
+
+    get checked() {
+        const rows = this.$.model.data || [];
+        const checkedRows = [];
+        for (let row of rows) {
+            if (row.checked)
+                checkedRows.push(row);
+        }
+
+        return checkedRows;
+    }
+
+    get totalChecked() {
+        return this.checked.length;
+    }
+
+    showRouteReport() {
+        const routes = [];
+        for (let route of this.checked)
+            routes.push(route.id);
+        const routesId = routes.join(',');
+
+        this.vnReport.show('driver-route', {
+            authorization: this.vnToken.token,
+            routeId: routesId
+        });
+    }
 }
 
+Controller.$inject = ['$element', '$scope', 'vnReport'];
+
 ngModule.vnComponent('vnRouteIndex', {
     template: require('./index.html'),
     controller: Controller
diff --git a/modules/route/front/index/locale/es.yml b/modules/route/front/index/locale/es.yml
index 5a21565b5b..0c09b21eea 100644
--- a/modules/route/front/index/locale/es.yml
+++ b/modules/route/front/index/locale/es.yml
@@ -1 +1,2 @@
 Vehicle: Vehículo
+Download selected routes as PDF: Descargar rutas seleccionadas como PDF
\ No newline at end of file
diff --git a/print/core/components/report-footer/assets/css/style.css b/print/core/components/report-footer/assets/css/style.css
index e06e8c0ade..9727e6f8f9 100644
--- a/print/core/components/report-footer/assets/css/style.css
+++ b/print/core/components/report-footer/assets/css/style.css
@@ -24,8 +24,9 @@ p.privacy {
     text-align: center
 }
 
-.page .pageCount {
-    text-align: right
+.pageCount {
+    text-align: right;
+    float: right
 }
 
 .footer .page > div {
diff --git a/print/core/report.js b/print/core/report.js
index e773c6c915..c5847fda19 100644
--- a/print/core/report.js
+++ b/print/core/report.js
@@ -33,6 +33,7 @@ class Report extends Component {
             args: ['--no-sandbox', '--disable-setuid-sandbox']
         });
         const page = await browser.newPage();
+        await page.emulateMedia('screen');
         await page.setContent(template);
 
         const element = await page.$('#pageFooter');
diff --git a/print/templates/reports/driver-route/assets/css/style.css b/print/templates/reports/driver-route/assets/css/style.css
index 2e7ec4dab5..6b76748ebe 100644
--- a/print/templates/reports/driver-route/assets/css/style.css
+++ b/print/templates/reports/driver-route/assets/css/style.css
@@ -47,3 +47,8 @@ section.text-area {
     padding-right: 1em;
     background-color: #e5e5e5;
 }
+
+.route-block {
+    margin-bottom: 100px;
+    page-break-after: always;
+}
\ No newline at end of file
diff --git a/print/templates/reports/driver-route/driver-route.html b/print/templates/reports/driver-route/driver-route.html
index 549aac0607..a3bb0f478a 100644
--- a/print/templates/reports/driver-route/driver-route.html
+++ b/print/templates/reports/driver-route/driver-route.html
@@ -8,9 +8,9 @@
                         <!-- Header block -->
                         <report-header v-bind="$props"></report-header>
                         <!-- Block -->
-                        <div class="grid-row">
+                        <div class="grid-row route-block" v-for="route in routes">
                             <div class="grid-block">
-                                <h1 class="title uppercase">{{route.id}}</h1>
+                                <h1 class="title uppercase">{{$t('route')}} {{route.id}}</h1>
                                 <div class="panel">
                                     <div class="header">{{$t('information')}}</div>
                                     <div class="body">
@@ -80,7 +80,8 @@
                                         </div>
                                     </div>
                                 </div>
-                                <div class="no-page-break" v-for="ticket in tickets">
+                                <!-- Route ticket list -->
+                                <div class="no-page-break" v-for="ticket in route.tickets">
                                     <div>
                                         <table class="column-oriented repeatable">
                                             <thead>
@@ -151,7 +152,7 @@
                         </div>
                         <!-- Footer block -->
                         <report-footer id="pageFooter" 
-                            v-bind:left-text="$t('routeId', [route.id])"
+                            v-bind:left-text="$t('routeId', [routeId])"
                             v-bind="$props">
                         </report-footer>
                     </td>
diff --git a/print/templates/reports/driver-route/driver-route.js b/print/templates/reports/driver-route/driver-route.js
index 8785527bc5..fcba7cb67f 100755
--- a/print/templates/reports/driver-route/driver-route.js
+++ b/print/templates/reports/driver-route/driver-route.js
@@ -6,15 +6,27 @@ const reportFooter = new Component('report-footer');
 module.exports = {
     name: 'driver-route',
     async serverPrefetch() {
-        this.route = await this.fetchRoute(this.routeId);
-        this.tickets = await this.fetchTickets(this.routeId);
+        const routesId = this.routeId.split(',');
+        const routes = await this.fetchRoutes(routesId);
+        const tickets = await this.fetchTickets(routesId);
+        console.log(tickets);
 
-        if (!this.route)
+        for (let route of routes) {
+            const routeTickets = tickets.filter(ticket => {
+                return ticket.routeFk == route.id;
+            });
+
+            route.tickets = routeTickets;
+        }
+
+        this.routes = routes;
+
+        if (!this.routes)
             throw new Error('Something went wrong');
     },
     methods: {
-        fetchRoute(id) {
-            return db.findOne(
+        fetchRoutes(routesId) {
+            return db.rawSql(
                 `SELECT 
                     r.id,
                     r.m3,
@@ -30,9 +42,9 @@ module.exports = {
                     LEFT JOIN worker w ON w.id = r.workerFk
                     LEFT JOIN account.user u ON u.id = w.userFk
                     LEFT JOIN agencyMode am ON am.id = r.agencyModeFk
-                WHERE r.id = :routeId`, {routeId: id});
+                WHERE r.id IN(:routesId)`, {routesId});
         },
-        fetchTickets(routeId) {
+        fetchTickets(routesId) {
             return db.rawSql(
                 `SELECT
                     t.nickname addressName,
@@ -41,6 +53,7 @@ module.exports = {
                     t.id,
                     t.clientFk,
                     t.companyFk,
+                    t.routeFk,
                     if(a.phone, a.phone, c.phone) AS phone,
                     if(a.mobile, a.mobile, c.mobile) AS mobile,
                     wh.name warehouseName,
@@ -65,8 +78,8 @@ module.exports = {
                     LEFT JOIN warehouse wh ON wh.id = t.warehouseFk
                     LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
                     LEFT JOIN stowaway s ON s.id = t.id
-                WHERE r.id = ?
-                ORDER BY t.priority, t.id`, [routeId]);
+                WHERE r.id IN(:routesId)
+                ORDER BY t.priority, t.id`, {routesId});
         }
     },
     components: {

From 17497c3f2d75dc5f61bbf0ce629a41fdf2d5ecdd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 25 Aug 2020 10:22:57 +0200
Subject: [PATCH 044/109] Added unit test

---
 modules/route/front/index/index.spec.js | 60 +++++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 modules/route/front/index/index.spec.js

diff --git a/modules/route/front/index/index.spec.js b/modules/route/front/index/index.spec.js
new file mode 100644
index 0000000000..8d71c91d67
--- /dev/null
+++ b/modules/route/front/index/index.spec.js
@@ -0,0 +1,60 @@
+import './index.js';
+import crudModel from 'core/mocks/crud-model';
+
+describe('Component vnRouteIndex', () => {
+    let controller;
+
+    beforeEach(ngModule('route'));
+
+    beforeEach(inject($componentController => {
+        const $element = angular.element('<vn-route-index></vn-route-index>');
+        controller = $componentController('vnRouteIndex', {$element});
+        controller.$.model = crudModel;
+        controller.$.model.data = [{id: 1}, {id: 2}, {id: 3}];
+    }));
+
+    describe('checked() getter', () => {
+        it('should should return the checked lines', () => {
+            const data = controller.$.model.data;
+            data[0].checked = true;
+            data[2].checked = true;
+
+            const checkedRows = controller.checked;
+
+            const firstCheckedRow = checkedRows[0];
+            const secondCheckedRow = checkedRows[1];
+
+            expect(firstCheckedRow.id).toEqual(1);
+            expect(secondCheckedRow.id).toEqual(3);
+        });
+    });
+
+    describe('totalCheked() getter', () => {
+        it('should should return the total checked lines', () => {
+            const data = controller.$.model.data;
+            data[0].checked = true;
+
+            const checkedRows = controller.totalChecked;
+
+            expect(checkedRows).toEqual(1);
+        });
+    });
+
+    describe('showRouteReport()', () => {
+        it('should call to the vnReport show method', () => {
+            controller.vnReport.show = jest.fn();
+
+            const data = controller.$.model.data;
+            data[0].checked = true;
+            data[2].checked = true;
+            const expectedParams = {
+                authorization: null,
+                routeId: '1,3'
+            };
+
+            controller.showRouteReport();
+
+            expect(controller.vnReport.show).toHaveBeenCalledWith('driver-route', expectedParams);
+        });
+    });
+});

From c15934aabcce114036019767e5bf9d8f71d4ceb1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 25 Aug 2020 11:59:51 +0200
Subject: [PATCH 045/109] Updated e2e selector

---
 e2e/helpers/selectors.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index 925347115b..6eca623bd6 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -371,7 +371,7 @@ export default {
     ticketsIndex: {
         openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
         advancedSearchInvoiceOut: 'vn-ticket-search-panel vn-textfield[ng-model="filter.refFk"]',
-        newTicketButton: 'vn-ticket-index a',
+        newTicketButton: 'vn-ticket-index a[ui-sref="ticket.create"]',
         searchResult: 'vn-ticket-index vn-card > vn-table > div > vn-tbody > a.vn-tr',
         secondTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(2) > vn-td:nth-child(1) > vn-check',
         thirdTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(3) > vn-td:nth-child(1) > vn-check',
@@ -689,7 +689,7 @@ export default {
         confirmButton: '.vn-confirm.shown button[response="accept"]',
     },
     routeIndex: {
-        addNewRouteButton: 'vn-route-index > a[ui-sref="route.create"]'
+        addNewRouteButton: 'vn-route-index a[ui-sref="route.create"]'
     },
     createRouteView: {
         worker: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.workerFk"]',

From 9ef58cabd4353a5ef5ddb1021074c26986f02f4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 25 Aug 2020 14:10:38 +0200
Subject: [PATCH 046/109] Removed console log

---
 modules/route/front/index/index.spec.js              | 4 ++--
 print/templates/reports/driver-route/driver-route.js | 1 -
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/modules/route/front/index/index.spec.js b/modules/route/front/index/index.spec.js
index 8d71c91d67..e90fc71648 100644
--- a/modules/route/front/index/index.spec.js
+++ b/modules/route/front/index/index.spec.js
@@ -14,7 +14,7 @@ describe('Component vnRouteIndex', () => {
     }));
 
     describe('checked() getter', () => {
-        it('should should return the checked lines', () => {
+        it('should return the checked lines', () => {
             const data = controller.$.model.data;
             data[0].checked = true;
             data[2].checked = true;
@@ -30,7 +30,7 @@ describe('Component vnRouteIndex', () => {
     });
 
     describe('totalCheked() getter', () => {
-        it('should should return the total checked lines', () => {
+        it('should return the total checked lines', () => {
             const data = controller.$.model.data;
             data[0].checked = true;
 
diff --git a/print/templates/reports/driver-route/driver-route.js b/print/templates/reports/driver-route/driver-route.js
index fcba7cb67f..cab5342e50 100755
--- a/print/templates/reports/driver-route/driver-route.js
+++ b/print/templates/reports/driver-route/driver-route.js
@@ -9,7 +9,6 @@ module.exports = {
         const routesId = this.routeId.split(',');
         const routes = await this.fetchRoutes(routesId);
         const tickets = await this.fetchTickets(routesId);
-        console.log(tickets);
 
         for (let route of routes) {
             const routeTickets = tickets.filter(ticket => {

From ea4f561bcfb2320d22b008d62fb928008d1778c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Wed, 26 Aug 2020 07:33:00 +0200
Subject: [PATCH 047/109] Added try-catch

---
 .../item-image-queue/downloadImages.js        | 21 +++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index bd22bc2810..c49cb07027 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -19,6 +19,7 @@ module.exports = Self => {
     Self.downloadImages = async() => {
         const models = Self.app.models;
 
+        let image;
         try {
             const tempPath = path.join('/tmp/salix-image');
 
@@ -26,7 +27,7 @@ module.exports = Self => {
             await fs.mkdir(tempPath, {recursive: true});
 
             const timer = setInterval(async() => {
-                const image = await Self.findOne({where: {error: null}});
+                image = await Self.findOne({where: {error: null}});
 
                 // Exit loop
                 if (!image) return clearInterval(timer);
@@ -61,17 +62,25 @@ module.exports = Self => {
                         await errorHandler(image.itemFk, error, filePath);
                     }
                 });
-            }, 1000);
+            }, 1500);
         } catch (error) {
             await errorHandler(image.itemFk, error);
         }
 
         async function errorHandler(rowId, error, filePath) {
-            const row = await Self.findById(rowId);
-            await row.updateAttribute('error', error);
+            try {
+                const row = await Self.findById(rowId);
 
-            if (filePath)
-                await fs.unlink(filePath);
+                if (!row)
+                    throw new Error(`Could not update due error ${error}`);
+
+                await row.updateAttribute('error', error);
+
+                if (filePath)
+                    await fs.unlink(filePath);
+            } catch (error) {
+                throw error;
+            }
         }
     };
 };

From a343d5eb9a192780ba6ce27c3d980d75f89cf1a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Wed, 26 Aug 2020 11:27:36 +0200
Subject: [PATCH 048/109] 2394 - Removed call to order_total()

---
 modules/order/back/methods/order/filter.js | 39 ++++------------------
 modules/order/back/models/order.json       |  3 ++
 2 files changed, 9 insertions(+), 33 deletions(-)

diff --git a/modules/order/back/methods/order/filter.js b/modules/order/back/methods/order/filter.js
index bfa64c4dd5..66b4244d0d 100644
--- a/modules/order/back/methods/order/filter.js
+++ b/modules/order/back/methods/order/filter.js
@@ -136,14 +136,10 @@ module.exports = Self => {
         let stmts = [];
         let stmt;
 
-        stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.filter');
-
         stmt = new ParameterizedSQL(
-            `CREATE TEMPORARY TABLE tmp.filter
-                (INDEX (id))
-                ENGINE = MEMORY
-                SELECT
+            `SELECT
                     o.id,
+                    o.total,
                     o.date_send landed,
                     o.date_make created,
                     o.customer_id clientFk,
@@ -178,36 +174,13 @@ module.exports = Self => {
         }
 
         stmt.merge(conn.makeWhere(filter.where));
-        stmt.merge({
-            sql: `GROUP BY o.id`
-        });
+        stmt.merge(`GROUP BY o.id`);
         stmt.merge(conn.makePagination(filter));
         stmts.push(stmt);
 
-        stmts.push(`
-            CREATE TEMPORARY TABLE tmp.order
-                (INDEX (orderFk))
-                ENGINE = MEMORY
-                    SELECT id AS orderFk
-                    FROM tmp.filter`);
+        const sql = ParameterizedSQL.join(stmts, ';');
+        const result = await conn.executeStmt(sql);
 
-        stmts.push('CALL hedera.order_getTotal()');
-
-        stmt = new ParameterizedSQL(
-            `SELECT f.*, ot.*
-                FROM tmp.filter f
-                    LEFT JOIN tmp.orderTotal ot ON ot.orderFk = f.id`);
-        const orderIndex = stmts.push(stmt) - 1;
-
-        stmts.push(`
-            DROP TEMPORARY TABLE 
-                tmp.order, 
-                tmp.orderTotal,
-                tmp.filter`);
-
-        let sql = ParameterizedSQL.join(stmts, ';');
-        let result = await conn.executeStmt(sql);
-
-        return result[orderIndex];
+        return result;
     };
 };
diff --git a/modules/order/back/models/order.json b/modules/order/back/models/order.json
index ab10ad1944..38755c2a54 100644
--- a/modules/order/back/models/order.json
+++ b/modules/order/back/models/order.json
@@ -79,6 +79,9 @@
             "mysql": {
                 "columnName": "confirm_date"
             }
+        },
+        "total": {
+            "type": "Number"
         }
     },
     "relations": {

From 30a4bbfe1acd83e1ba7579d28c9adb9a643d1d0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Wed, 26 Aug 2020 12:41:38 +0200
Subject: [PATCH 049/109] Css changes

---
 modules/ticket/front/sale/index.html | 5 ++---
 modules/ticket/front/sale/style.scss | 3 +++
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html
index 8caa2f89e3..ab3277e31d 100644
--- a/modules/ticket/front/sale/index.html
+++ b/modules/ticket/front/sale/index.html
@@ -58,7 +58,7 @@
                     </vn-th>
                     <vn-th shrink></vn-th>
                     <vn-th shrink></vn-th>
-                    <vn-th number>Id</vn-th>
+                    <vn-th number id="ticketId">Id</vn-th>
                     <vn-th>Quantity</vn-th>
                     <vn-th>Item</vn-th>
                     <vn-th number>Price</vn-th>
@@ -102,9 +102,8 @@
                         ng-click="descriptor.show($event, sale.itemFk, sale.id)">
                         {{sale.itemFk}}
                     </span>
-                    <vn-autocomplete ng-if="!sale.id"
+                    <vn-autocomplete ng-if="!sale.id" class="dense"
                         vn-focus
-                        vn-one
                         url="Items"
                         ng-model="sale.itemFk"
                         show-field="name"
diff --git a/modules/ticket/front/sale/style.scss b/modules/ticket/front/sale/style.scss
index a1c36f271d..d38601d2a7 100644
--- a/modules/ticket/front/sale/style.scss
+++ b/modules/ticket/front/sale/style.scss
@@ -53,6 +53,9 @@ vn-ticket-sale {
             padding: 0!important;
         }
     }
+    #ticketId {
+        min-width: 150px
+    }
 }
 .vn-popover .transfer {
     .vn-textfield {

From 3a82ef0e06739f4af46726fbad84c81a1091141d Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Wed, 26 Aug 2020 16:33:47 +0200
Subject: [PATCH 050/109] 2375 entry lastBuy seccion

---
 db/changes/10210-summer/00-ACL.sql            |   2 +
 front/core/directives/smart-table.js          |  14 +-
 .../back/methods/entry/editLatestBuys.js      |  78 ++++++++
 .../back/methods/entry/latestBuysFilter.js    | 135 +++++++++----
 modules/entry/back/model-config.json          |   3 +
 modules/entry/back/models/buy.js              |   4 +
 modules/entry/back/models/buy.json            |  64 +++++++
 modules/entry/back/models/entry.js            |   1 -
 modules/entry/front/card/index.js             |   9 +-
 .../entry/front/descriptor-popover/index.html |   3 +
 .../entry/front/descriptor-popover/index.js   |   9 +
 modules/entry/front/descriptor/index.js       |  60 +++++-
 modules/entry/front/index.js                  |   1 +
 .../front/latest-buys-search-panel/index.html |  21 ++-
 .../front/latest-buys-search-panel/index.js   |   2 +-
 modules/entry/front/latest-buys/index.html    | 178 +++++++++++-------
 modules/entry/front/latest-buys/index.js      |  53 ++++++
 modules/entry/front/routes.json               |   8 +-
 modules/item/back/methods/item/filter.js      |  12 +-
 modules/item/front/index/index.html           |  28 +--
 modules/route/front/index/index.html          |  12 +-
 21 files changed, 539 insertions(+), 158 deletions(-)
 create mode 100644 db/changes/10210-summer/00-ACL.sql
 create mode 100644 modules/entry/back/methods/entry/editLatestBuys.js
 create mode 100644 modules/entry/back/models/buy.js
 create mode 100644 modules/entry/back/models/buy.json
 create mode 100644 modules/entry/front/descriptor-popover/index.html
 create mode 100644 modules/entry/front/descriptor-popover/index.js

diff --git a/db/changes/10210-summer/00-ACL.sql b/db/changes/10210-summer/00-ACL.sql
new file mode 100644
index 0000000000..755b148d74
--- /dev/null
+++ b/db/changes/10210-summer/00-ACL.sql
@@ -0,0 +1,2 @@
+INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
+    VALUES ('Buy', '*', '*', 'ALLOW', 'ROLE', 'buyer');
diff --git a/front/core/directives/smart-table.js b/front/core/directives/smart-table.js
index 2d5a24ade4..c7072c09e0 100644
--- a/front/core/directives/smart-table.js
+++ b/front/core/directives/smart-table.js
@@ -2,22 +2,26 @@ import ngModule from '../module';
 import template from './smart-table.html';
 import './smart-table.scss';
 
+/**
+ * Directive to hide/show selected columns of a table, don't use with rowspan.
+ */
 directive.$inject = ['$http', '$compile', 'vnApp', '$translate'];
 export function directive($http, $compile, vnApp, $translate) {
     function getHeaderList($element, $scope) {
-        let allHeaders = $element[0].querySelectorAll(`vn-th[field], vn-th[th-id]`);
-        let headerList = Array.from(allHeaders);
+        let filtrableHeaders = $element[0].querySelectorAll('vn-th[field]');
+        let headerList = Array.from(filtrableHeaders);
         let ids = [];
         let titles = {};
 
         headerList.forEach(header => {
-            let id = header.getAttribute('th-id') || header.getAttribute('field');
+            let id = header.getAttribute('field');
             ids.push(id);
             titles[id] = header.innerText || id.charAt(0).toUpperCase() + id.slice(1);
         });
 
         $scope.fields = ids;
         $scope.titles = titles;
+        $scope.allHeaders = Array.from($element[0].querySelectorAll('vn-th'));
 
         return headerList;
     }
@@ -38,8 +42,8 @@ export function directive($http, $compile, vnApp, $translate) {
         Object.keys(userConfig.configuration).forEach(key => {
             let index;
             if (userConfig.configuration[key] === false) {
-                index = headerList.findIndex(el => {
-                    return (el.getAttribute('th-id') == key || el.getAttribute('field') == key);
+                index = $scope.allHeaders.findIndex(el => {
+                    return el.getAttribute('field') == key;
                 });
 
                 let baseSelector = `vn-table[vn-smart-table=${userConfig.tableCode}] > div`;
diff --git a/modules/entry/back/methods/entry/editLatestBuys.js b/modules/entry/back/methods/entry/editLatestBuys.js
new file mode 100644
index 0000000000..acda6ed1cc
--- /dev/null
+++ b/modules/entry/back/methods/entry/editLatestBuys.js
@@ -0,0 +1,78 @@
+module.exports = Self => {
+    Self.remoteMethod('editLatestBuys', {
+        description: 'Updates a column for one of more buys',
+        accessType: 'WRITE',
+        accepts: [{
+            arg: 'column',
+            type: 'Object',
+            required: true,
+            description: `the column to edit and it's new value`
+        },
+        {
+            arg: 'buys',
+            type: ['Object'],
+            required: true,
+            description: `the buys which will be modified`
+        }],
+        returns: {
+            type: 'Object',
+            root: true
+        },
+        http: {
+            path: `/editLatestBuys`,
+            verb: 'POST'
+        }
+    });
+
+    Self.editLatestBuys = async(column, buys) => {
+        let modelName;
+        let identifier;
+        switch (column.field) {
+        case 'size':
+        case 'density':
+            modelName = 'Item';
+            identifier = 'itemFk';
+            break;
+        case 'quantity':
+        case 'buyingValue':
+        case 'freightValue':
+        case 'packing':
+        case 'grouping':
+        case 'groupingMode':
+        case 'comissionValue':
+        case 'packageValue':
+        case 'price2':
+        case 'price3':
+        case 'minPrice':
+        case 'weight':
+            modelName = 'Buy';
+            identifier = 'id';
+        }
+
+        const models = Self.app.models;
+        const model = models[modelName];
+
+        let tx = await model.beginTransaction({});
+
+        try {
+            let promises = [];
+            let options = {transaction: tx};
+
+            let targets = buys.map(buy => {
+                return buy[identifier];
+            });
+
+            let value = {};
+            value[column.field] = column.newValue;
+
+            for (let target of targets)
+                promises.push(model.upsertWithWhere({id: target}, value, options));
+
+            await Promise.all(promises);
+            await tx.commit();
+        } catch (error) {
+            await tx.rollback();
+            throw error;
+        }
+    };
+};
diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js
index edfc46e3b2..50cd8cf3c0 100644
--- a/modules/entry/back/methods/entry/latestBuysFilter.js
+++ b/modules/entry/back/methods/entry/latestBuysFilter.js
@@ -12,43 +12,44 @@ module.exports = Self => {
                 arg: 'filter',
                 type: 'Object',
                 description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
-                http: {source: 'query'}
             },
             {
+                arg: 'search',
+                type: 'String',
+                description: `If it's and integer searchs by id, otherwise it searchs by name`,
+            }, {
+                arg: 'id',
+                type: 'Integer',
+                description: 'Item id',
+            }, {
                 arg: 'tags',
                 type: ['Object'],
                 description: 'List of tags to filter with',
                 http: {source: 'query'}
-            }, {
-                arg: 'search',
-                type: 'String',
-                description: `If it's and integer searchs by id, otherwise it searchs by name`,
-                http: {source: 'query'}
-            }, {
-                arg: 'id',
-                type: 'Integer',
-                description: 'Item id',
-                http: {source: 'query'}
             }, {
                 arg: 'categoryFk',
                 type: 'Integer',
                 description: 'Category id',
-                http: {source: 'query'}
             }, {
                 arg: 'typeFk',
                 type: 'Integer',
                 description: 'Type id',
-                http: {source: 'query'}
             }, {
-                arg: 'isActive',
+                arg: 'active',
                 type: 'Boolean',
                 description: 'Whether the the item is or not active',
-                http: {source: 'query'}
+            }, {
+                arg: 'visible',
+                type: 'Boolean',
+                description: 'Whether the the item is or not visible',
             }, {
                 arg: 'salesPersonFk',
                 type: 'Integer',
                 description: 'The buyer of the item',
-                http: {source: 'query'}
+            }, {
+                arg: 'description',
+                type: 'String',
+                description: 'The item description',
             }
         ],
         returns: {
@@ -64,42 +65,100 @@ module.exports = Self => {
     Self.latestBuysFilter = async(ctx, filter) => {
         let conn = Self.dataSource.connector;
         let where = buildFilter(ctx.args, (param, value) => {
-            // switch (param) {
-            // case 'search':
-            //     return /^\d+$/.test(value)
-            //         ? {or: [{'i.id': value}]}
-            //         : {or: [{'i.name': {like: `%${value}%`}}]};
-            // case 'id':
-            //     return {'i.id': value};
-            // case 'description':
-            //     return {'i.description': {like: `%${value}%`}};
-            // case 'categoryFk':
-            //     return {'ic.id': value};
-            // case 'salesPersonFk':
-            //     return {'t.workerFk': value};
-            // case 'typeFk':
-            //     return {'i.typeFk': value};
-            // case 'isActive':
-            //     return {'i.isActive': value};
-            // }
+            switch (param) {
+            case 'search':
+                return /^\d+$/.test(value)
+                    ? {'i.id': value}
+                    : {'i.name': {like: `%${value}%`}};
+            case 'id':
+                return {'i.id': value};
+            case 'description':
+                return {'i.description': {like: `%${value}%`}};
+            case 'categoryFk':
+                return {'ic.id': value};
+            case 'salesPersonFk':
+                return {'it.workerFk': value};
+            case 'typeFk':
+                return {'i.typeFk': value};
+            case 'active':
+                return {'i.isActive': value};
+            case 'visible':
+                if (value)
+                    return {'v.visible': {gt: 0}};
+                else if (!value)
+                    return {'v.visible': {lte: 0}};
+            }
         });
         filter = mergeFilters(ctx.args.filter, {where});
 
         let stmts = [];
         let stmt;
 
-        stmt = new ParameterizedSQL('CALL cache.last_buy_refresh(FALSE)');
-        stmts.push(stmt);
+        stmts.push('CALL cache.last_buy_refresh(FALSE)');
+        stmts.push('CALL cache.visible_refresh(@calc_id, FALSE, 1)');
 
         stmt = new ParameterizedSQL(`
             SELECT 
-                size
+                i.image,
+                i.id AS itemFk,
+                i.size,
+                i.density,
+                i.typeFk,
+                t.name AS type,
+                i.family,
+                intr.description AS intrastat,
+                ori.code AS origin,
+                i.isActive,
+                b.entryFk,
+                b.id,
+                b.quantity,
+                b.buyingValue,
+                b.freightValue,
+                b.isIgnored,
+                b.packing,
+                b.grouping,
+                b.groupingMode,
+                b.comissionValue,
+                b.packageValue,
+                b.price2,
+                b.price3,
+                b.minPrice,
+                b.ektFk,
+                b.weight
             FROM cache.last_buy lb
+                LEFT JOIN cache.visible v ON v.item_id = lb.item_id
+                    AND v.calc_id = @calc_id
                 JOIN item i ON i.id = lb.item_id
                 JOIN itemType it ON it.id = i.typeFk AND lb.warehouse_id = it.warehouseFk
-                JOIN buy b ON b.id = lb.buy_id`
+                JOIN buy b ON b.id = lb.buy_id
+                LEFT JOIN itemCategory ic ON ic.id = it.categoryFk
+                LEFT JOIN itemType t ON t.id = i.typeFk
+                LEFT JOIN intrastat intr ON intr.id = i.intrastatFk
+                LEFT JOIN origin ori ON ori.id = i.originFk`
         );
 
+        if (ctx.args.tags) {
+            let i = 1;
+            for (const tag of ctx.args.tags) {
+                const tAlias = `it${i++}`;
+
+                if (tag.tagFk) {
+                    stmt.merge({
+                        sql: `JOIN vn.itemTag ${tAlias} ON ${tAlias}.itemFk = i.id
+                            AND ${tAlias}.tagFk = ?
+                            AND ${tAlias}.value LIKE ?`,
+                        params: [tag.tagFk, `%${tag.value}%`],
+                    });
+                } else {
+                    stmt.merge({
+                        sql: `JOIN vn.itemTag ${tAlias} ON ${tAlias}.itemFk = i.id
+                            AND ${tAlias}.value LIKE ?`,
+                        params: [`%${tag.value}%`],
+                    });
+                }
+            }
+        }
+
         stmt.merge(conn.makeSuffix(filter));
         let buysIndex = stmts.push(stmt) - 1;
 
diff --git a/modules/entry/back/model-config.json b/modules/entry/back/model-config.json
index c8c8babadc..0e37b947ff 100644
--- a/modules/entry/back/model-config.json
+++ b/modules/entry/back/model-config.json
@@ -2,6 +2,9 @@
     "Entry": {
         "dataSource": "vn"
     },
+    "Buy": {
+        "dataSource": "vn"
+    },
     "EntryLog": {
         "dataSource": "vn"
     }
diff --git a/modules/entry/back/models/buy.js b/modules/entry/back/models/buy.js
new file mode 100644
index 0000000000..e110164e82
--- /dev/null
+++ b/modules/entry/back/models/buy.js
@@ -0,0 +1,4 @@
+module.exports = Self => {
+    require('../methods/entry/editLatestBuys')(Self);
+    require('../methods/entry/latestBuysFilter')(Self);
+};
diff --git a/modules/entry/back/models/buy.json b/modules/entry/back/models/buy.json
new file mode 100644
index 0000000000..14f2490d8f
--- /dev/null
+++ b/modules/entry/back/models/buy.json
@@ -0,0 +1,64 @@
+{
+    "name": "Buy",
+    "base": "Loggable",
+    "log": {
+        "model": "EntryLog",
+        "relation": "entry"
+      },
+    "options": {
+        "mysql": {
+        "table": "buy"
+        }
+    },
+    "properties": {
+        "id": {
+            "type": "number",
+            "id": true,
+            "description": "Identifier"
+        },
+        "quantity": {
+            "type": "number"
+        },
+        "buyingValue": {
+            "type": "number"
+        },
+        "freightValue": {
+            "type": "number"
+        },
+        "packing": {
+            "type": "number"
+        },
+        "grouping": {
+            "type": "number"
+        },
+        "groupingMode": {
+            "type": "number"
+        },
+        "comissionValue": {
+            "type": "number"
+        },
+        "packageValue": {
+            "type": "number"
+        },
+        "price2": {
+            "type": "number"
+        },
+        "price3": {
+            "type": "number"
+        },
+        "minPrice": {
+            "type": "number"
+        },
+        "weight": {
+            "type": "number"
+        }
+    },
+    "relations": {
+        "entry": {
+            "type": "belongsTo",
+            "model": "Entry",
+            "foreignKey": "entryFk",
+            "required": true
+        }
+    }
+}
\ No newline at end of file
diff --git a/modules/entry/back/models/entry.js b/modules/entry/back/models/entry.js
index 40f89ebf09..713154d1b0 100644
--- a/modules/entry/back/models/entry.js
+++ b/modules/entry/back/models/entry.js
@@ -1,5 +1,4 @@
 module.exports = Self => {
-    require('../methods/entry/latestBuysFilter')(Self);
     require('../methods/entry/filter')(Self);
     require('../methods/entry/getEntry')(Self);
 };
diff --git a/modules/entry/front/card/index.js b/modules/entry/front/card/index.js
index f9ab6187c1..eafed171bb 100644
--- a/modules/entry/front/card/index.js
+++ b/modules/entry/front/card/index.js
@@ -10,7 +10,8 @@ class Controller extends ModuleCard {
                     scope: {
                         fields: ['id', 'code']
                     }
-                }, {
+                },
+                {
                     relation: 'travel',
                     scope: {
                         fields: ['id', 'landed', 'agencyFk', 'warehouseOutFk'],
@@ -35,12 +36,14 @@ class Controller extends ModuleCard {
                             }
                         ]
                     }
-                }, {
+                },
+                {
                     relation: 'supplier',
                     scope: {
                         fields: ['id', 'nickname']
                     }
-                }, {
+                },
+                {
                     relation: 'currency'
                 }
             ]
diff --git a/modules/entry/front/descriptor-popover/index.html b/modules/entry/front/descriptor-popover/index.html
new file mode 100644
index 0000000000..465a9bf51e
--- /dev/null
+++ b/modules/entry/front/descriptor-popover/index.html
@@ -0,0 +1,3 @@
+<slot-descriptor>
+    <vn-entry-descriptor></vn-entry-descriptor>
+</slot-descriptor>
\ No newline at end of file
diff --git a/modules/entry/front/descriptor-popover/index.js b/modules/entry/front/descriptor-popover/index.js
new file mode 100644
index 0000000000..d79aed03e8
--- /dev/null
+++ b/modules/entry/front/descriptor-popover/index.js
@@ -0,0 +1,9 @@
+import ngModule from '../module';
+import DescriptorPopover from 'salix/components/descriptor-popover';
+
+class Controller extends DescriptorPopover {}
+
+ngModule.vnComponent('vnEntryDescriptorPopover', {
+    slotTemplate: require('./index.html'),
+    controller: Controller
+});
diff --git a/modules/entry/front/descriptor/index.js b/modules/entry/front/descriptor/index.js
index dd417a8422..fed3787d49 100644
--- a/modules/entry/front/descriptor/index.js
+++ b/modules/entry/front/descriptor/index.js
@@ -11,15 +11,23 @@ class Controller extends Descriptor {
     }
 
     get travelFilter() {
-        return this.entry && JSON.stringify({
-            agencyFk: this.entry.travel.agencyFk
-        });
+        let travelFilter;
+        const entryTravel = this.entry && this.entry.travel;
+
+        if (entryTravel && entryTravel.agencyFk) {
+            travelFilter = this.entry && JSON.stringify({
+                agencyFk: entryTravel.agencyFk
+            });
+        }
+        return travelFilter;
     }
 
     get entryFilter() {
-        if (!this.entry) return null;
+        let entryTravel = this.entry && this.entry.travel;
 
-        const date = new Date(this.entry.travel.landed);
+        if (!entryTravel || !entryTravel.landed) return null;
+
+        const date = new Date(entryTravel.landed);
         date.setHours(0, 0, 0, 0);
 
         const from = new Date(date.getTime());
@@ -35,6 +43,48 @@ class Controller extends Descriptor {
         });
     }
 
+    loadData() {
+        const filter = {
+            include: [
+                {
+                    relation: 'travel',
+                    scope: {
+                        fields: ['id', 'landed', 'agencyFk', 'warehouseOutFk'],
+                        include: [
+                            {
+                                relation: 'agency',
+                                scope: {
+                                    fields: ['name']
+                                }
+                            },
+                            {
+                                relation: 'warehouseOut',
+                                scope: {
+                                    fields: ['name']
+                                }
+                            },
+                            {
+                                relation: 'warehouseIn',
+                                scope: {
+                                    fields: ['name']
+                                }
+                            }
+                        ]
+                    }
+                },
+                {
+                    relation: 'supplier',
+                    scope: {
+                        fields: ['id', 'nickname']
+                    }
+                }
+            ]
+        };
+
+        return this.getData(`Entries/${this.id}`, {filter})
+            .then(res => this.entity = res.data);
+    }
+
     showEntryReport() {
         this.vnReport.show('entry-order', {
             entryId: this.entry.id
diff --git a/modules/entry/front/index.js b/modules/entry/front/index.js
index eb2c823c40..fc24e3efb7 100644
--- a/modules/entry/front/index.js
+++ b/modules/entry/front/index.js
@@ -6,6 +6,7 @@ import './latest-buys';
 import './search-panel';
 import './latest-buys-search-panel';
 import './descriptor';
+import './descriptor-popover';
 import './card';
 import './summary';
 import './log';
diff --git a/modules/entry/front/latest-buys-search-panel/index.html b/modules/entry/front/latest-buys-search-panel/index.html
index f30442ec61..67fa7f0c22 100644
--- a/modules/entry/front/latest-buys-search-panel/index.html
+++ b/modules/entry/front/latest-buys-search-panel/index.html
@@ -3,7 +3,6 @@
     <form ng-submit="$ctrl.onSearch()">
         <vn-horizontal>
             <vn-textfield
-                vn-one
                 label="General search"
                 ng-model="filter.search"
                 info="Search items by id, name or barcode"
@@ -12,7 +11,6 @@
         </vn-horizontal>
         <vn-horizontal>
             <vn-autocomplete
-                vn-one
                 vn-focus
                 url="ItemCategories"
                 label="Category"
@@ -20,7 +18,7 @@
                 value-field="id"
                 ng-model="filter.categoryFk">
             </vn-autocomplete>
-            <vn-autocomplete vn-one
+            <vn-autocomplete
                 url="ItemTypes"
                 label="Type"
                 where="{categoryFk: filter.categoryFk}"
@@ -39,7 +37,6 @@
         </vn-horizontal>
         <vn-horizontal>
             <vn-autocomplete 
-                vn-one
                 disabled="false"
                 ng-model="filter.salesPersonFk"
                 url="Clients/activeWorkersWithRole"
@@ -50,6 +47,18 @@
                 label="Buyer">
             </vn-autocomplete>
         </vn-horizontal>
+        <vn-horizontal>
+            <vn-check
+                label="Is active"
+                ng-model="filter.active"
+                triple-state="true">
+            </vn-check>
+            <vn-check
+                label="Is visible"
+                ng-model="filter.visible"
+                triple-state="true">
+            </vn-check>
+        </vn-horizontal>
         <vn-horizontal class="vn-pt-sm">
             <vn-one class="text-subtitle1" translate>
                 Tags
@@ -65,7 +74,6 @@
         <vn-horizontal ng-repeat="itemTag in filter.tags">
             <vn-autocomplete
                 vn-id="tag"
-                vn-one
                 ng-model="itemTag.tagFk"
                 data="tags.model"
                 show-field="name"
@@ -73,14 +81,12 @@
                 on-change="itemTag.value = null">
             </vn-autocomplete>
             <vn-textfield
-                vn-one
                 ng-show="tag.selection.isFree !== false"
                 vn-id="text"
                 label="Value"
                 ng-model="itemTag.value">
             </vn-textfield>
             <vn-autocomplete
-                vn-one
                 ng-show="tag.selection.isFree === false"
                 url="{{$ctrl.getSourceTable(tag.selection)}}"
                 label="Value"
@@ -110,7 +116,6 @@
         </vn-horizontal>
         <vn-horizontal ng-repeat="fieldFilter in $ctrl.fieldFilters">
             <vn-autocomplete
-                vn-one
                 label="Field"
                 ng-model="fieldFilter.name"
                 data="$ctrl.moreFields"
diff --git a/modules/entry/front/latest-buys-search-panel/index.js b/modules/entry/front/latest-buys-search-panel/index.js
index bcb1ca23be..187fe91719 100644
--- a/modules/entry/front/latest-buys-search-panel/index.js
+++ b/modules/entry/front/latest-buys-search-panel/index.js
@@ -5,7 +5,7 @@ class Controller extends SearchPanel {
     constructor($element, $) {
         super($element, $);
         let model = 'Item';
-        let moreFields = ['id', 'description', 'name', 'isActive'];
+        let moreFields = ['id', 'description', 'name'];
 
         let properties;
         let validations = window.validations;
diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
index ecf36c63be..9be2160675 100644
--- a/modules/entry/front/latest-buys/index.html
+++ b/modules/entry/front/latest-buys/index.html
@@ -1,28 +1,19 @@
 <vn-crud-model
     vn-id="model"
-    url="Entries/latestBuysFilter"
+    url="Buys/latestBuysFilter"
     limit="20"
-    data="buys"
-    auto-load="true">
+    data="$ctrl.buys">
 </vn-crud-model>
 <vn-portal slot="topbar">
     <vn-searchbar
         panel="vn-latest-buys-search-panel"
-        suggested-filter="$ctrl.filterParams"
-        info="Search buys"
-        filter="$ctrl.filterParams"
+        placeholder="Search by item id or name"
+        info="You can search by item id or name"
+        suggested-filter="{isActive: true}"
         model="model"
         auto-state="false">
     </vn-searchbar>
 </vn-portal>
-<!-- <vn-portal slot="topbar">
-    <vn-searchbar
-        panel="vn-latest-buys-search-panel"
-        info="Search buys"
-        model="model"
-        auto-state="false">
-    </vn-searchbar>
-</vn-portal> -->
 <vn-data-viewer
     model="model"
     class="vn-mb-xl vn-w-xl">
@@ -33,72 +24,98 @@
         vn-smart-table="latestBuys">
         <vn-thead>
             <vn-tr>
-                <vn-th shrink
-                    field='Selection'>
-                    <vn-multi-check 
+                <vn-th shrink>
+                    <vn-multi-check
                         model="model">
                     </vn-multi-check>
                 </vn-th>
-                <vn-th shrink field='status'></vn-th>
-                <vn-th field="id" number>Id</vn-th>
-                <vn-th field="landed" center>Landed</vn-th>
-                <vn-th>Reference</vn-th>
-                <vn-th field="supplierFk">Supplier</vn-th>
-                <vn-th field="currencyFk" center>Currency</vn-th>
-                <vn-th field="companyFk" center>Company</vn-th>
-                <vn-th field="isBooked" center>Booked</vn-th>
-                <vn-th field="isConfirmed" center>Confirmed</vn-th>
-                <vn-th field="isOrdered" center>Ordered</vn-th>
-                <vn-th>Notes</vn-th>
+                <vn-th field="picture">Picture</vn-th>
+                <vn-th field="id">Id</vn-th>
+                <vn-th field="grouping">Grouping</vn-th>
+                <vn-th field="packing">Packing</vn-th>
+                <vn-th field="size">Size</vn-th>
+                <vn-th field="type">Type</vn-th>
+                <vn-th field="intrastat">Intrastat</vn-th>
+                <vn-th field="origin">Origin</vn-th>
+                <vn-th field="density">Density</vn-th>
+                <vn-th field="isActive">Active</vn-th>
+                <vn-th field="family">Family</vn-th>
+                <vn-th field="entryFk">Entry</vn-th>
+                <vn-th field="quantity">Quantity</vn-th>
+                <vn-th field="buyingValue">Buying value</vn-th>
+                <vn-th field="freightValue">Freight value</vn-th>
+                <vn-th field="comissionValue" expand>Comission value</vn-th>
+                <vn-th field="packageValue" expand>Package value</vn-th>
+                <vn-th field="isIgnored">Is ignored</vn-th>
+                <vn-th field="groupingMode" expand>Grouping mode</vn-th>
+                <vn-th field="price2">price2</vn-th>
+                <vn-th field="price3">price3</vn-th>
+                <vn-th field="minPrice">Min price</vn-th>
+                <vn-th field="ektFk">Ekt</vn-th>
+                <vn-th field="weight">Weight</vn-th>
             </vn-tr>
         </vn-thead>
         <vn-tbody>
             <a ng-repeat="buy in $ctrl.buys" 
                 class="clickable vn-tr search-result"
-                ui-sref="buy.card.summary({id: {{::buy.id}}})">
+                ui-sref="entry.card.buy({id: {{::buy.entryFk}}})">
                 <vn-td shrink>
                     <vn-check 
                         ng-model="buy.checked"
                         vn-click-stop>
                     </vn-check>
                 </vn-td>
-                <vn-td shrink>
-                    <vn-icon
-                        ng-show="buy.isInventory"
-                        class="bright"
-                        vn-tooltip="Inventory buy"
-                        icon="icon-inventory">
-                    </vn-icon>
-                    <vn-icon
-                        ng-show="buy.isRaid"
-                        class="bright"
-                        vn-tooltip="Virtual buy"
-                        icon="icon-net">
-                    </vn-icon>
+                <vn-td shrink >
+                    <img 
+                        ng-src="{{::$root.imagePath}}/catalog/50x50/{{::buy.image}}"
+                        zoom-image="{{::$root.imagePath}}/catalog/1600x900/{{::item.image}}"
+                        vn-click-stop
+                        on-error-src/>
                 </vn-td>
-                <vn-td number>{{::buy.size}}</vn-td>
-                <vn-td center>
-                    <span 
-                        class="link" 
-                        vn-click-stop="travelDescriptor.show($event, buy.travelFk)">
-                        {{::buy.landed | date:'dd/MM/yyyy'}}
+                <vn-td shrink>
+                    <span
+                        vn-click-stop="itemDescriptor.show($event, buy.itemFk)"
+                        class="link">
+                        {{::buy.itemFk | zeroFill:6}}
                     </span>
                 </vn-td>
-                <vn-td expand>{{::buy.ref}}</vn-td>
-                <vn-td expand>{{::buy.supplierName}}</vn-td>
-                <vn-td center expand>{{::buy.currencyCode}}</vn-td>
-                <vn-td center expand>{{::buy.companyCode}}</vn-td>
-                <vn-td center><vn-check ng-model="buy.isBooked" disabled="true"></vn-check></vn-td>
-                <vn-td center><vn-check ng-model="buy.isConfirmed" disabled="true"></vn-check></vn-td>
-                <vn-td center><vn-check ng-model="buy.isOrdered" disabled="true"></vn-check></vn-td>
-                <vn-td shrink> 
-                    <vn-icon
-                        ng-if="buy.notes.length"
-                        vn-tooltip="{{::buy.notes}}"
-                        icon="insert_drive_file"
-                        class="bright">
-                    </vn-icon>
+                <vn-td number>{{::buy.grouping}}</vn-td>
+                <vn-td number>{{::buy.packing}}</vn-td>
+                <vn-td number>{{::buy.size}}</vn-td>
+                <vn-td shrink title="{{::buy.type}}">
+                    {{::buy.type}}
                 </vn-td>
+                <vn-td shrink title="{{::item.intrastat}}">
+                    {{::buy.intrastat}}
+                </vn-td>
+                <vn-td shrink>{{::buy.origin}}</vn-td>
+                <vn-td shrink>{{::buy.density}}</vn-td>
+                <vn-td shrink>
+                    <vn-check
+                        disabled="true"
+                        ng-model="::buy.isActive">
+                    </vn-check> 
+                </vn-td>
+                <vn-td shrink>{{::buy.family}}</vn-td>
+                <vn-td shrink>
+                    <span
+                        vn-click-stop="entryDescriptor.show($event, buy.entryFk)"
+                        class="link">
+                        {{::buy.entryFk}}
+                    </span>
+                </vn-td>
+                <vn-td number>{{::buy.quantity}}</vn-td>
+                <vn-td number>{{::buy.buyingValue | currency: 'EUR':2}}</vn-td>
+                <vn-td number>{{::buy.freightValue | currency: 'EUR':2}}</vn-td>
+                <vn-td number>{{::buy.comissionValue | currency: 'EUR':2}}</vn-td>
+                <vn-td number>{{::buy.packageValue | currency: 'EUR':2}}</vn-td>
+                <vn-td shrink>{{::buy.isIgnored}}</vn-td>
+                <vn-td shrink>{{::buy.groupingMode}}</vn-td>
+                <vn-td number>{{::buy.price2 | currency: 'EUR':2}}</vn-td>
+                <vn-td number>{{::buy.price3 | currency: 'EUR':2}}</vn-td>
+                <vn-td number>{{::buy.minPrice | currency: 'EUR':2}}</vn-td>
+                <vn-td number>{{::buy.ektFk | dashIfEmpty}}</vn-td>
+                <vn-td number>{{::buy.weight}}</vn-td>
             </a>
         </vn-tbody>
     </vn-table>
@@ -109,12 +126,41 @@
         <vn-button class="round sm vn-mb-sm"
             icon="edit"
             ng-show="$ctrl.totalChecked > 0"
-            ng-click="$ctrl.edit()"
+            ng-click="edit.show($event)"
             vn-tooltip="Edit buys"
             tooltip-position="left">
         </vn-button>
     </vn-vertical>
 </div>
-<vn-travel-descriptor-popover 
-    vn-id="travelDescriptor">
-</vn-travel-descriptor-popover>
\ No newline at end of file
+<vn-dialog class="edit" 
+    vn-id="edit"
+    on-accept="$ctrl.onEditAccept()"
+    message="Edit buy(s)">
+    <tpl-body>
+        <vn-horizontal>
+            <vn-autocomplete
+                vn-two
+                ng-model="$ctrl.editedColumn.field"
+                data="$ctrl.columns"
+                show-field="displayName"
+                value-field="field"
+                label="Field to edit">
+            </vn-autocomplete>
+            <vn-textfield
+                vn-one
+                label="Value"
+                ng-model="$ctrl.editedColumn.newValue">
+            </vn-textfield>
+        </vn-horizontal>
+    </tpl-body>
+    <tpl-buttons>
+        <input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
+        <button response="accept" translate>Create</button>
+    </tpl-buttons>
+</vn-dialog>
+<vn-item-descriptor-popover
+    vn-id="itemDescriptor">
+</vn-item-descriptor-popover>
+<vn-entry-descriptor-popover
+    vn-id="entryDescriptor">
+</vn-entry-descriptor-popover>
diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js
index 7f2de41853..b3b120af8c 100644
--- a/modules/entry/front/latest-buys/index.js
+++ b/modules/entry/front/latest-buys/index.js
@@ -8,7 +8,33 @@ export default class Controller extends Section {
             id: false,
             actions: false
         };
+        this.editedColumn;
     }
+
+    get columns() {
+        if (this._columns) return this._columns;
+
+        this._columns = [
+            {field: 'quantity', displayName: 'quantity'},
+            {field: 'buyingValue', displayName: 'buyingValue'},
+            {field: 'freightValue', displayName: 'freightValue'},
+            {field: 'packing', displayName: 'packing'},
+            {field: 'grouping', displayName: 'grouping'},
+            {field: 'groupingMode', displayName: 'groupingMode'},
+            {field: 'comissionValue', displayName: 'comissionValue'},
+            {field: 'packageValue', displayName: 'packageValue'},
+            {field: 'price2', displayName: 'price2'},
+            {field: 'price3', displayName: 'price3'},
+            {field: 'minPrice', displayName: 'minPrice'},
+            {field: 'weight', displayName: 'weight'},
+            {field: 'size', displayName: 'size'},
+            {field: 'density', displayName: 'density'},
+            {field: 'description', displayName: 'description'}
+        ];
+
+        return this._columns;
+    }
+
     get checked() {
         const buys = this.$.model.data || [];
         const checkedBuys = [];
@@ -20,9 +46,36 @@ export default class Controller extends Section {
         return checkedBuys;
     }
 
+    uncheck() {
+        console.log('clicked!');
+        const lines = this.checked;
+        for (let line of lines) {
+            if (line.checked)
+                line.checked = false;
+        }
+    }
+
     get totalChecked() {
         return this.checked.length;
     }
+
+    onEditAccept() {
+        let data = {
+            column: this.editedColumn,
+            buys: this.checked
+        };
+
+        this.$http.post('Buys/editLatestBuys', data)
+            .then(() => {
+                this.$.edit.hide();
+                this.uncheck();
+                this.$.model.refresh();
+            });
+
+        this.editedColumn = null;
+
+        return false;
+    }
 }
 
 ngModule.component('vnEntryLatestBuys', {
diff --git a/modules/entry/front/routes.json b/modules/entry/front/routes.json
index 32c046a3d6..cdaaebc7db 100644
--- a/modules/entry/front/routes.json
+++ b/modules/entry/front/routes.json
@@ -2,7 +2,7 @@
     "module": "entry",
     "name": "Entries",
     "icon": "icon-entry",
-    "dependencies": ["travel"],
+    "dependencies": ["travel", "item"],
     "validations": true,
     "menus": {
         "main": [
@@ -25,12 +25,14 @@
             "url": "/index?q",
             "state": "entry.index",
             "component": "vn-entry-index",
-            "description": "Entries"
+            "description": "Entries",
+            "acl": ["buyer"]
         }, {
             "url": "/latest-buys?q",
             "state": "entry.latestBuys",
             "component": "vn-entry-latest-buys",
-            "description": "Latest buys"
+            "description": "Latest buys",
+            "acl": ["buyer"]
         }, {
             "url": "/:id",
             "state": "entry.card",
diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js
index 5d9ae9e0fb..a38a067132 100644
--- a/modules/item/back/methods/item/filter.js
+++ b/modules/item/back/methods/item/filter.js
@@ -12,42 +12,38 @@ module.exports = Self => {
                 arg: 'filter',
                 type: 'Object',
                 description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
-                http: {source: 'query'}
             }, {
                 arg: 'tags',
                 type: ['Object'],
                 description: 'List of tags to filter with',
-                http: {source: 'query'}
             }, {
                 arg: 'search',
                 type: 'String',
                 description: `If it's and integer searchs by id, otherwise it searchs by name`,
-                http: {source: 'query'}
             }, {
                 arg: 'id',
                 type: 'Integer',
                 description: 'Item id',
-                http: {source: 'query'}
             }, {
                 arg: 'categoryFk',
                 type: 'Integer',
                 description: 'Category id',
-                http: {source: 'query'}
             }, {
                 arg: 'typeFk',
                 type: 'Integer',
                 description: 'Type id',
-                http: {source: 'query'}
             }, {
                 arg: 'isActive',
                 type: 'Boolean',
                 description: 'Whether the the item is or not active',
-                http: {source: 'query'}
             }, {
                 arg: 'salesPersonFk',
                 type: 'Integer',
                 description: 'The buyer of the item',
-                http: {source: 'query'}
+            }, {
+                arg: 'description',
+                type: 'String',
+                description: 'The item description',
             }
         ],
         returns: {
diff --git a/modules/item/front/index/index.html b/modules/item/front/index/index.html
index 296ac97473..b34445d367 100644
--- a/modules/item/front/index/index.html
+++ b/modules/item/front/index/index.html
@@ -11,21 +11,21 @@
         vn-smart-table="itemIndex">
         <vn-thead>
             <vn-tr>
-                <vn-th th-id="picture" shrink></vn-th>
+                <vn-th field="picture" shrink></vn-th>
                 <vn-th field="id" shrink>Id</vn-th>
-                <vn-th th-id="grouping" shrink>Grouping</vn-th>
-                <vn-th th-id="packing" shrink>Packing</vn-th>
-                <vn-th th-id="description" style="text-align: center">Description</vn-th>
-                <vn-th th-id="stems" shrink>Stems</vn-th>
-                <vn-th th-id="size" shrink>Size</vn-th>
-                <vn-th th-id="niche" shrink>Niche</vn-th>
-                <vn-th th-id="type" shrink>Type</vn-th>
-                <vn-th th-id="category" shrink>Category</vn-th>
-                <vn-th th-id="intrastat" shrink>Intrastat</vn-th>
-                <vn-th th-id="origin" shrink>Origin</vn-th>
-                <vn-th th-id="salesperson" shrink>Buyer</vn-th>
-                <vn-th th-id="density" shrink>Density</vn-th>
-                <vn-th th-id="active" shrink>Active</vn-th>
+                <vn-th field="grouping" shrink>Grouping</vn-th>
+                <vn-th field="packing" shrink>Packing</vn-th>
+                <vn-th field="description" style="text-align: center">Description</vn-th>
+                <vn-th field="stems" shrink>Stems</vn-th>
+                <vn-th field="size" shrink>Size</vn-th>
+                <vn-th field="niche" shrink>Niche</vn-th>
+                <vn-th field="type" shrink>Type</vn-th>
+                <vn-th field="category" shrink>Category</vn-th>
+                <vn-th field="intrastat" shrink>Intrastat</vn-th>
+                <vn-th field="origin" shrink>Origin</vn-th>
+                <vn-th field="salesperson" shrink>Buyer</vn-th>
+                <vn-th field="density" shrink>Density</vn-th>
+                <vn-th field="active" shrink>Active</vn-th>
                 <vn-th></vn-th>
             </vn-tr>
         </vn-thead>
diff --git a/modules/route/front/index/index.html b/modules/route/front/index/index.html
index 7258018f10..909d782490 100644
--- a/modules/route/front/index/index.html
+++ b/modules/route/front/index/index.html
@@ -14,12 +14,12 @@
                     </vn-multi-check>
                 </vn-th>
                 <vn-th field="id" number>Id</vn-th>
-                <vn-th th-id="worker">Worker</vn-th>
-                <vn-th th-id="agency">Agency</vn-th>
-                <vn-th th-id="vehicle">Vehicle</vn-th>
-                <vn-th th-id="created">Date</vn-th>
-                <vn-th th-id="m3" number>m³</vn-th>
-                <vn-th th-id="description">Description</vn-th>
+                <vn-th field="worker">Worker</vn-th>
+                <vn-th field="agency">Agency</vn-th>
+                <vn-th field="vehicle">Vehicle</vn-th>
+                <vn-th field="created">Date</vn-th>
+                <vn-th field="m3" number>m³</vn-th>
+                <vn-th field="description">Description</vn-th>
                 <vn-th shrink></vn-th>
             </vn-tr>
         </vn-thead>

From 17542472da68d9373bd80025e560de6c1a267878 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 27 Aug 2020 08:24:21 +0200
Subject: [PATCH 051/109] 2391 - Editable description

---
 back/model-config.json                        |  3 +
 back/models/accounting-type.json              | 30 ++++++++
 back/models/bank.json                         | 76 +++++++++++--------
 db/changes/10210-summer/00-accountingType.sql |  2 +
 db/dump/fixtures.sql                          | 16 ++--
 modules/client/back/methods/receipt/filter.js |  4 +-
 .../client/front/balance/create/index.html    | 22 +++++-
 modules/client/front/balance/create/index.js  | 13 ++++
 modules/client/front/balance/index/index.html | 42 +++++-----
 modules/client/front/balance/index/index.js   |  7 ++
 10 files changed, 153 insertions(+), 62 deletions(-)
 create mode 100644 back/models/accounting-type.json
 create mode 100644 db/changes/10210-summer/00-accountingType.sql

diff --git a/back/model-config.json b/back/model-config.json
index 323e5f2330..dc5cde2172 100644
--- a/back/model-config.json
+++ b/back/model-config.json
@@ -2,6 +2,9 @@
     "Account": {
         "dataSource": "vn"
     },
+    "AccountingType": {
+        "dataSource": "vn"
+    },
     "Bank": {
         "dataSource": "vn"
     },
diff --git a/back/models/accounting-type.json b/back/models/accounting-type.json
new file mode 100644
index 0000000000..7967933428
--- /dev/null
+++ b/back/models/accounting-type.json
@@ -0,0 +1,30 @@
+{
+    "name": "AccountingType",
+    "base": "VnModel",
+    "options": {
+        "mysql": {
+            "table": "accountingType"
+        }
+    },
+    "properties": {
+        "id": {
+            "type": "Number",
+            "id": true,
+            "description": "Identifier"
+        },
+        "description": {
+            "type": "String",
+            "required": true
+        },
+        "receiptDescription": {
+            "type": "String",
+            "required": true
+        }
+    },
+    "acls": [{
+        "accessType": "READ",
+        "principalType": "ROLE",
+        "principalId": "$everyone",
+        "permission": "ALLOW"
+    }]
+}
\ No newline at end of file
diff --git a/back/models/bank.json b/back/models/bank.json
index 119ea97437..33a2637d69 100644
--- a/back/models/bank.json
+++ b/back/models/bank.json
@@ -2,39 +2,49 @@
     "name": "Bank",
     "base": "VnModel",
     "options": {
-      "mysql": {
-        "table": "bank"
-      }
+        "mysql": {
+            "table": "bank"
+        }
     },
     "properties": {
-      "id": {
-        "type": "Number",
-        "id": true,
-        "description": "Identifier"
-      },
-      "bank": {
-        "type": "string",
-        "required": true
-      },
-      "account": {
-        "type": "string",
-        "required": true
-      },
-      "cash": {
-        "type": "string",
-        "required": true
-      },
-      "entityFk": {
-        "type": "string",
-        "required": true
-      },
-      "isActive": {
-        "type": "string",
-        "required": true
-      },
-      "currencyFk": {
-        "type": "string",
-        "required": true
-      }
+        "id": {
+            "type": "Number",
+            "id": true,
+            "description": "Identifier"
+        },
+        "bank": {
+            "type": "String",
+            "required": true
+        },
+        "account": {
+            "type": "String",
+            "required": true
+        },
+        "accountingTypeFk": {
+            "type": "Number",
+            "required": true,
+            "mysql": {
+                "columnName": "cash"
+            }
+        },
+        "entityFk": {
+            "type": "Number",
+            "required": true
+        },
+        "isActive": {
+            "type": "Boolean",
+            "required": true
+        },
+        "currencyFk": {
+            "type": "Number",
+            "required": true
+        }
+    },
+    "relations": {
+		"accountingType": {
+			"type": "belongsTo",
+			"model": "AccountingType",
+			"foreignKey": "accountingTypeFk"
+        }
     }
-  }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/db/changes/10210-summer/00-accountingType.sql b/db/changes/10210-summer/00-accountingType.sql
new file mode 100644
index 0000000000..1dbe29952a
--- /dev/null
+++ b/db/changes/10210-summer/00-accountingType.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `vn`.`accountingType` 
+ADD COLUMN `receiptDescription` VARCHAR(50) NULL AFTER `description`;
diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 2b70cf2bee..274d241399 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -116,13 +116,13 @@ INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `isPrinted`, `priority`, `park
         ('GVC', '1', '0', '1', '0', '106'),
         ('HEJ', '2', '0', '1', '0', '106');
 
-INSERT INTO `vn`.`accountingType`(`id`, `description`)
+INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`)
     VALUES 
-        (1, 'Digital money'),
-        (2, 'Cash'),
-        (3, 'Card'),
-        (4, 'Stolen Money'),
-        (5, 'Miscellaneous');
+        (1, 'Digital money',    ''),
+        (2, 'Cash',             'Cash'),
+        (3, 'Card',             'Pay on receipt'),
+        (4, 'Stolen Money',     ''),
+        (5, 'Miscellaneous',    '');
 
 INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
     VALUES
@@ -133,8 +133,8 @@ INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
 
 INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`)
     VALUES 
-        (1, 'Pay on receipt',   '0000000000', 4, 0, 1, 1),
-        (2, 'Cash',             '1111111111', 1, 0, 1, 1);
+        (1, 'Pay on receipt',   '0000000000', 3, 0, 1, 1),
+        (2, 'Cash',             '1111111111', 2, 0, 1, 1);
 
 INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
     VALUES
diff --git a/modules/client/back/methods/receipt/filter.js b/modules/client/back/methods/receipt/filter.js
index 532d728119..b32249d4be 100644
--- a/modules/client/back/methods/receipt/filter.js
+++ b/modules/client/back/methods/receipt/filter.js
@@ -42,11 +42,11 @@ module.exports = Self => {
                             r.workerFk,
                             c.code company,
                             r.created,
-                            r.invoiceFk ref,
+                            r.invoiceFk description,
                             NULL debit,
                             r.amountPaid credit,
                             r.bankFk,
-                            u.nickname userNickname,
+                            u.name userName,
                             r.clientFk,
                             FALSE hasPdf,
                             FALSE isInvoice
diff --git a/modules/client/front/balance/create/index.html b/modules/client/front/balance/create/index.html
index 506e86f4b0..5a75445fe4 100644
--- a/modules/client/front/balance/create/index.html
+++ b/modules/client/front/balance/create/index.html
@@ -2,6 +2,13 @@
     New payment
 </tpl-title>
 <tpl-body>
+    <vn-crud-model
+        url="Banks"
+        include="{relation: 'accountingType'}"
+        data="banks"
+        order="id"
+        auto-load="true">
+    </vn-crud-model>
     <vn-horizontal>
         <vn-date-picker
             label="Date" 
@@ -17,11 +24,15 @@
     </vn-horizontal>
     <vn-horizontal>
         <vn-autocomplete
-            url="Banks"
             label="Bank"
+            data="banks"
             show-field="bank"
             value-field="id"
-            ng-model="$ctrl.receipt.bankFk">
+            order="id"
+            ng-model="$ctrl.receipt.bankFk"
+            search-function="{or: [{id: $search}, {bank: {like: '%'+ $search +'%'}}]}"
+            selection="$ctrl.bankSelection">
+            <tpl-item>{{id}}: {{bank}}</tpl-item>
         </vn-autocomplete>
         <vn-input-number
             vn-focus
@@ -31,6 +42,13 @@
             rule>
         </vn-input-number>
     </vn-horizontal>
+    <vn-horizontal>
+        <vn-textfield
+            label="Reference"
+            ng-model="$ctrl.receipt.description"
+            rule>
+        </vn-textfield>
+    </vn-horizontal>
 </tpl-body>
 <tpl-buttons>
     <input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
diff --git a/modules/client/front/balance/create/index.js b/modules/client/front/balance/create/index.js
index 880774f557..8b01cab4a7 100644
--- a/modules/client/front/balance/create/index.js
+++ b/modules/client/front/balance/create/index.js
@@ -50,6 +50,19 @@ class Controller extends Dialog {
         return this.receipt.description;
     }
 
+    get bankSelection() {
+        return this._bankSelection;
+    }
+
+    set bankSelection(value) {
+        this._bankSelection = value;
+
+        if (value) {
+            const accountingType = value.accountingType;
+            this.receipt.description = accountingType && accountingType.receiptDescription;
+        }
+    }
+
     getAmountPaid() {
         const filter = {
             where: {
diff --git a/modules/client/front/balance/index/index.html b/modules/client/front/balance/index/index.html
index 1ad7efad99..da8c40315e 100644
--- a/modules/client/front/balance/index/index.html
+++ b/modules/client/front/balance/index/index.html
@@ -68,25 +68,33 @@
                         <span
                             vn-click-stop="workerDescriptor.show($event, balance.workerFk)"
                             class="link">
-                            {{::balance.userNickname}}
+                            {{::balance.userName}}
                         </span>
                     </vn-td>
-                    <vn-td expand>
-                        <div ng-show="::balance.ref">
-                            <span
-                                ng-if="balance.isInvoice"
-                                title="{{'BILL' | translate: {ref: balance.ref} }}"
-                                vn-click-stop="$ctrl.showInvoiceOutDescriptor($event, balance)"
-                                class="link">
-                                {{'BILL' | translate: {ref: balance.ref} }}
-                            </span>
-                            <span
-                                ng-if="!balance.isInvoice"
-                                title="{{::balance.ref}}">
-                                {{::balance.ref}}
-                            </span>
-                        </div>
-                    </vn-td>
+                    <vn-td-editable disabled="balance.isInvoice" expand>
+                        <text>
+                            <div ng-show="::balance.description">
+                                <span
+                                    ng-if="balance.isInvoice"
+                                    title="{{'BILL' | translate: {ref: balance.description} }}"
+                                    vn-click-stop="$ctrl.showInvoiceOutDescriptor($event, balance)"
+                                    class="link">
+                                    {{'BILL' | translate: {ref: balance.description} }}
+                                </span>
+                                <span
+                                    ng-if="!balance.isInvoice"
+                                    title="{{::balance.description}}">
+                                    {{balance.description}}
+                                </span>
+                            </div>
+                        </text>
+                        <field>
+                            <vn-textfield class="dense" vn-focus
+                                ng-model="balance.description"
+                                on-change="$ctrl.changeDescription(balance)">
+                            </vn-textfield>
+                        </field>
+                    </vn-td-editable>
                     <vn-td number>{{::balance.bankFk}}</vn-td>
                     <vn-td number expand>{{::balance.debit | currency: 'EUR':2}}</vn-td>
                     <vn-td number expand>{{::balance.credit | currency: 'EUR':2}}</vn-td>
diff --git a/modules/client/front/balance/index/index.js b/modules/client/front/balance/index/index.js
index 8f52611765..40a6e49571 100644
--- a/modules/client/front/balance/index/index.js
+++ b/modules/client/front/balance/index/index.js
@@ -79,6 +79,13 @@ class Controller extends Section {
 
         this.$.invoiceOutDescriptor.show(event.target, balance.id);
     }
+
+    changeDescription(balance) {
+        const params = {description: balance.description};
+        const endpoint = `Receipts/${balance.id}`;
+        this.$http.patch(endpoint, params)
+            .then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
+    }
 }
 
 Controller.$inject = ['$element', '$scope'];

From ac181bb845b10519de74db1e9191be6305c83c81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 27 Aug 2020 11:16:36 +0200
Subject: [PATCH 052/109] Updated unit tests

---
 .../client/front/balance/create/index.spec.js | 76 +++++++++++++++++++
 modules/client/front/balance/index/index.js   |  2 +-
 .../client/front/balance/index/index.spec.js  | 20 ++++-
 3 files changed, 96 insertions(+), 2 deletions(-)
 create mode 100644 modules/client/front/balance/create/index.spec.js

diff --git a/modules/client/front/balance/create/index.spec.js b/modules/client/front/balance/create/index.spec.js
new file mode 100644
index 0000000000..11fdb1040c
--- /dev/null
+++ b/modules/client/front/balance/create/index.spec.js
@@ -0,0 +1,76 @@
+import './index';
+
+describe('Client', () => {
+    describe('Component vnClientBalancCreate', () => {
+        let controller;
+        let $httpBackend;
+        let $httpParamSerializer;
+
+        beforeEach(ngModule('client'));
+
+        beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
+            $httpBackend = _$httpBackend_;
+            $httpParamSerializer = _$httpParamSerializer_;
+            let $scope = $rootScope.$new();
+            const $element = angular.element('<vn-client-balance-create></vn-client-balance-create>');
+            const $transclude = {
+                $$boundTransclude: {
+                    $$slots: []
+                }
+            };
+            controller = $componentController('vnClientBalanceCreate', {$element, $scope, $transclude});
+            controller.receipt = {
+                clientFk: 101,
+                companyFk: 442
+            };
+        }));
+
+        describe('bankSelection() setter', () => {
+            it('should set the receipt description property', () => {
+                controller.bankSelection = {
+                    id: 1,
+                    bank: 'Cash',
+                    accountingType: {
+                        id: 2,
+                        receiptDescription: 'Cash'
+                    }
+                };
+
+                expect(controller.receipt.description).toEqual('Cash');
+            });
+        });
+
+        describe('getAmountPaid()', () => {
+            it('should make an http GET query and then set the receipt amountPaid property', () => {
+                controller.$params = {id: 101};
+                const receipt = controller.receipt;
+                const filter = {
+                    where: {
+                        clientFk: 101,
+                        companyFk: 442
+                    }
+                };
+                const serializedParams = $httpParamSerializer({filter});
+                $httpBackend.expect('GET', `ClientRisks?${serializedParams}`,).respond([{amount: 20}]);
+                controller.getAmountPaid();
+                $httpBackend.flush();
+
+                expect(receipt.amountPaid).toEqual(20);
+            });
+        });
+
+        describe('responseHandler()', () => {
+            it('should make an http POST query and then call to the parent responseHandler() method', () => {
+                jest.spyOn(controller.vnApp, 'showSuccess');
+
+                controller.$params = {id: 101};
+
+                $httpBackend.expect('POST', `Receipts`,).respond({id: 1});
+                controller.responseHandler('accept');
+                $httpBackend.flush();
+
+                expect(controller.vnApp.showSuccess).toHaveBeenCalled();
+            });
+        });
+    });
+});
diff --git a/modules/client/front/balance/index/index.js b/modules/client/front/balance/index/index.js
index 40a6e49571..3c76feabc4 100644
--- a/modules/client/front/balance/index/index.js
+++ b/modules/client/front/balance/index/index.js
@@ -58,7 +58,7 @@ class Controller extends Section {
             return balance.companyFk === selectedCompany;
         });
 
-        return currentBalance.amount;
+        return currentBalance && currentBalance.amount;
     }
 
     getBalances() {
diff --git a/modules/client/front/balance/index/index.spec.js b/modules/client/front/balance/index/index.spec.js
index 496407847d..bdbea38460 100644
--- a/modules/client/front/balance/index/index.spec.js
+++ b/modules/client/front/balance/index/index.spec.js
@@ -3,10 +3,12 @@ import './index';
 describe('Client', () => {
     describe('Component vnClientBalanceIndex', () => {
         let controller;
+        let $httpBackend;
 
         beforeEach(ngModule('client'));
 
-        beforeEach(inject(($componentController, $rootScope) => {
+        beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
+            $httpBackend = _$httpBackend_;
             let $scope = $rootScope.$new();
             const $element = angular.element('<vn-client-balance-index></vn-client-balance-index>');
             controller = $componentController('vnClientBalanceIndex', {$element, $scope});
@@ -133,5 +135,21 @@ describe('Client', () => {
                 expect(controller.getBalances).toHaveBeenCalledWith();
             });
         });
+
+        describe('changeDescription()', () => {
+            it('should make an http PATCH query', () => {
+                const expectedParams = {description: 'Web'};
+
+                $httpBackend.expect('PATCH', `Receipts/1`, expectedParams).respond(200);
+                controller.changeDescription({
+                    id: 1,
+                    description: 'Web',
+                    accountingType: {
+                        description: 'Cash'
+                    }
+                });
+                $httpBackend.flush();
+            });
+        });
     });
 });

From f14b484faf69344322ec7bf642959557e49abdd5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 27 Aug 2020 11:23:39 +0200
Subject: [PATCH 053/109] Added ACL to td-editable

---
 modules/client/front/balance/index/index.html | 4 ++--
 modules/client/front/balance/index/index.js   | 4 ++++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/modules/client/front/balance/index/index.html b/modules/client/front/balance/index/index.html
index da8c40315e..cf0c07cfcd 100644
--- a/modules/client/front/balance/index/index.html
+++ b/modules/client/front/balance/index/index.html
@@ -71,7 +71,7 @@
                             {{::balance.userName}}
                         </span>
                     </vn-td>
-                    <vn-td-editable disabled="balance.isInvoice" expand>
+                    <vn-td-editable disabled="balance.isInvoice || !$ctrl.isAdministrative" expand>
                         <text>
                             <div ng-show="::balance.description">
                                 <span
@@ -89,7 +89,7 @@
                             </div>
                         </text>
                         <field>
-                            <vn-textfield class="dense" vn-focus
+                            <vn-textfield vn-acl="administrative" class="dense" vn-focus
                                 ng-model="balance.description"
                                 on-change="$ctrl.changeDescription(balance)">
                             </vn-textfield>
diff --git a/modules/client/front/balance/index/index.js b/modules/client/front/balance/index/index.js
index 3c76feabc4..7e09e018cd 100644
--- a/modules/client/front/balance/index/index.js
+++ b/modules/client/front/balance/index/index.js
@@ -39,6 +39,10 @@ class Controller extends Section {
             this.getBalances();
     }
 
+    get isAdministrative() {
+        return this.aclService.hasAny(['administrative']);
+    }
+
     getData() {
         return this.$.model.applyFilter(null, {
             clientId: this.$params.id,

From 914407012a0dabe006dd0a8cb92f5498e4b6096c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 27 Aug 2020 11:58:28 +0200
Subject: [PATCH 054/109] Fixed bank search expression

---
 e2e/paths/02-client/14_balance.spec.js         |  2 +-
 modules/client/front/balance/create/index.html | 11 +++--------
 2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/e2e/paths/02-client/14_balance.spec.js b/e2e/paths/02-client/14_balance.spec.js
index 108f767108..6d9ab10c8c 100644
--- a/e2e/paths/02-client/14_balance.spec.js
+++ b/e2e/paths/02-client/14_balance.spec.js
@@ -1,7 +1,7 @@
 import selectors from '../../helpers/selectors';
 import getBrowser from '../../helpers/puppeteer';
 
-describe('Client balance path', () => {
+fdescribe('Client balance path', () => {
     let browser;
     let page;
     beforeAll(async() => {
diff --git a/modules/client/front/balance/create/index.html b/modules/client/front/balance/create/index.html
index 5a75445fe4..6cfdc06669 100644
--- a/modules/client/front/balance/create/index.html
+++ b/modules/client/front/balance/create/index.html
@@ -2,13 +2,6 @@
     New payment
 </tpl-title>
 <tpl-body>
-    <vn-crud-model
-        url="Banks"
-        include="{relation: 'accountingType'}"
-        data="banks"
-        order="id"
-        auto-load="true">
-    </vn-crud-model>
     <vn-horizontal>
         <vn-date-picker
             label="Date" 
@@ -25,9 +18,11 @@
     <vn-horizontal>
         <vn-autocomplete
             label="Bank"
-            data="banks"
+            url="Banks"
             show-field="bank"
             value-field="id"
+            fields="['accountingTypeFk']"
+            include="{relation: 'accountingType'}"
             order="id"
             ng-model="$ctrl.receipt.bankFk"
             search-function="{or: [{id: $search}, {bank: {like: '%'+ $search +'%'}}]}"

From 32de0e1e6f0a85963fa908ee671538d4c1ba55e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 27 Aug 2020 12:43:57 +0200
Subject: [PATCH 055/109] Removed focus

---
 e2e/paths/02-client/14_balance.spec.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/e2e/paths/02-client/14_balance.spec.js b/e2e/paths/02-client/14_balance.spec.js
index 6d9ab10c8c..108f767108 100644
--- a/e2e/paths/02-client/14_balance.spec.js
+++ b/e2e/paths/02-client/14_balance.spec.js
@@ -1,7 +1,7 @@
 import selectors from '../../helpers/selectors';
 import getBrowser from '../../helpers/puppeteer';
 
-fdescribe('Client balance path', () => {
+describe('Client balance path', () => {
     let browser;
     let page;
     beforeAll(async() => {

From 6f3fb83cd75b121f703e979888b0eb05068fabbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 27 Aug 2020 13:53:11 +0200
Subject: [PATCH 056/109] Changes

---
 back/models/image.js                                  |  4 +++-
 .../back/methods/item-image-queue/downloadImages.js   | 11 +++++------
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/back/models/image.js b/back/models/image.js
index 340b2e5a60..313e4492b4 100644
--- a/back/models/image.js
+++ b/back/models/image.js
@@ -90,7 +90,9 @@ module.exports = Self => {
                 );
             }
 
-            await fs.unlink(srcFilePath);
+            if (fs.existsSync(filePath))
+                await fs.unlink(srcFilePath);
+
             await tx.commit();
             return newImage;
         } catch (e) {
diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index c49cb07027..d3fd739ccb 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -19,7 +19,6 @@ module.exports = Self => {
     Self.downloadImages = async() => {
         const models = Self.app.models;
 
-        let image;
         try {
             const tempPath = path.join('/tmp/salix-image');
 
@@ -27,7 +26,7 @@ module.exports = Self => {
             await fs.mkdir(tempPath, {recursive: true});
 
             const timer = setInterval(async() => {
-                image = await Self.findOne({where: {error: null}});
+                const image = await Self.findOne({where: {error: null}});
 
                 // Exit loop
                 if (!image) return clearInterval(timer);
@@ -62,9 +61,9 @@ module.exports = Self => {
                         await errorHandler(image.itemFk, error, filePath);
                     }
                 });
-            }, 1500);
+            }, 2500);
         } catch (error) {
-            await errorHandler(image.itemFk, error);
+            throw new Error('Try-catch error: ', error);
         }
 
         async function errorHandler(rowId, error, filePath) {
@@ -76,10 +75,10 @@ module.exports = Self => {
 
                 await row.updateAttribute('error', error);
 
-                if (filePath)
+                if (filePath && fs.existsSync(filePath))
                     await fs.unlink(filePath);
             } catch (error) {
-                throw error;
+                throw new Error('ErrorHandler error: ', error);
             }
         }
     };

From 0c4939830bd27897ed44217b0628c1900900141f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 27 Aug 2020 14:00:40 +0200
Subject: [PATCH 057/109] Fixed error

---
 back/models/image.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/back/models/image.js b/back/models/image.js
index 313e4492b4..113bc70844 100644
--- a/back/models/image.js
+++ b/back/models/image.js
@@ -90,7 +90,7 @@ module.exports = Self => {
                 );
             }
 
-            if (fs.existsSync(filePath))
+            if (fs.existsSync(srcFilePath))
                 await fs.unlink(srcFilePath);
 
             await tx.commit();

From fd67a85fe8bdcae4c14bb849b61d91cfd9398858 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 27 Aug 2020 14:09:21 +0200
Subject: [PATCH 058/109] Changed to 1 second

---
 modules/item/back/methods/item-image-queue/downloadImages.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index d3fd739ccb..febd0289da 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -61,7 +61,7 @@ module.exports = Self => {
                         await errorHandler(image.itemFk, error, filePath);
                     }
                 });
-            }, 2500);
+            }, 1000);
         } catch (error) {
             throw new Error('Try-catch error: ', error);
         }

From 55d047c0dd40d61b3cdb6f188cc9c1f7940c5cc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 27 Aug 2020 14:11:22 +0200
Subject: [PATCH 059/109] Renamed error var

---
 modules/item/back/methods/item-image-queue/downloadImages.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index febd0289da..71af072653 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -77,8 +77,8 @@ module.exports = Self => {
 
                 if (filePath && fs.existsSync(filePath))
                     await fs.unlink(filePath);
-            } catch (error) {
-                throw new Error('ErrorHandler error: ', error);
+            } catch (err) {
+                throw new Error('ErrorHandler error: ', err);
             }
         }
     };

From a75938b6d07196126cc2f5eefd74862114df5006 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 27 Aug 2020 14:23:40 +0200
Subject: [PATCH 060/109] Updated error handler

---
 modules/item/back/methods/item-image-queue/downloadImages.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/item/back/methods/item-image-queue/downloadImages.js b/modules/item/back/methods/item-image-queue/downloadImages.js
index 71af072653..420b357a5c 100644
--- a/modules/item/back/methods/item-image-queue/downloadImages.js
+++ b/modules/item/back/methods/item-image-queue/downloadImages.js
@@ -78,7 +78,7 @@ module.exports = Self => {
                 if (filePath && fs.existsSync(filePath))
                     await fs.unlink(filePath);
             } catch (err) {
-                throw new Error('ErrorHandler error: ', err);
+                throw new Error(`ErrorHandler error: ${err}`);
             }
         }
     };

From d156ca95ba399942f9be38c259e88824cccf6195 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Thu, 27 Aug 2020 15:14:30 +0200
Subject: [PATCH 061/109] front and back unit tests

---
 db/dump/fixtures.sql                          |  34 ++---
 .../entry/specs/editLatestBuys.spec.js        |  30 ++++
 .../entry/specs/latestBuysFilter.spec.js      | 132 +++++++++++++++++-
 modules/entry/front/descriptor/index.spec.js  |  18 ++-
 .../latest-buys-search-panel/index.spec.js    |   8 +-
 modules/entry/front/latest-buys/index.js      |   3 -
 modules/entry/front/latest-buys/index.spec.js |  91 ++++++++++++
 7 files changed, 287 insertions(+), 29 deletions(-)
 create mode 100644 modules/entry/back/methods/entry/specs/editLatestBuys.spec.js
 create mode 100644 modules/entry/front/latest-buys/index.spec.js

diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 2b70cf2bee..301f0a256b 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -735,23 +735,23 @@ INSERT INTO `vn`.`intrastat`(`id`, `description`, `taxClassFk`, `taxCodeFk`)
 
 INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `isOnOffer`, `expenceFk`, `isBargain`, `comment`, `relevancy`, `image`, `taxClassFk`, `subName`)
     VALUES
-        (1,  2, 70,   'AMA', 1,    1, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL),
-        (2,  2, 70,   'AZL', 1,    2, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL),
-        (3,  1, 60,   'AMR', 1,    3, NULL, 1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL),
-        (4,  1, 60,   'AMR', 1,    1, NULL, 1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL),
-        (5,  3, 30,   'GRE', 1,    2, NULL, 2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (6,  5, 30,   'GRE', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (7,  5, 90,   'AZL', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (8,  2, 70,   'AMA', 1,    1, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL),
-        (9,  2, 70,   'AZL', 1,    2, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL),
-        (10, 1, 60,   'AMR', 1,    3, NULL, 1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL),
-        (11, 1, 60,   'AMR', 1,    1, NULL, 1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL),
-        (12, 3, 30,   'GRE', 1,    2, NULL, 2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (13, 5, 30,   'GRE', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (14, 5, 90,   'AZL', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (15, 4, NULL,  NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350,  2, NULL),
-        (16, 4, NULL,  NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350,  2, NULL),
-        (71, 4, NULL,  NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, 67350,  2, NULL);
+        (1,  2, 70,   'AMA', 1,    1, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL),
+        (2,  2, 70,   'AZL', 1,    2, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL),
+        (3,  1, 60,   'AMR', 1,    3, NULL,              1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL),
+        (4,  1, 60,   'AMR', 1,    1, 'Increases block', 1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL),
+        (5,  3, 30,   'GRE', 1,    2, NULL,              2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL),
+        (6,  5, 30,   'GRE', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
+        (7,  5, 90,   'AZL', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
+        (8,  2, 70,   'AMA', 1,    1, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL),
+        (9,  2, 70,   'AZL', 1,    2, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL),
+        (10, 1, 60,   'AMR', 1,    3, NULL,              1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL),
+        (11, 1, 60,   'AMR', 1,    1, NULL,              1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL),
+        (12, 3, 30,   'GRE', 1,    2, NULL,              2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL),
+        (13, 5, 30,   'GRE', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
+        (14, 5, 90,   'AZL', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
+        (15, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
+        (16, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
+        (71, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL);
 
 INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`)
     VALUES
diff --git a/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js b/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js
new file mode 100644
index 0000000000..c82ca036b4
--- /dev/null
+++ b/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js
@@ -0,0 +1,30 @@
+const app = require('vn-loopback/server/server');
+const model = app.models.Buy;
+
+describe('Buy editLatestsBuys()', () => {
+    it('should change the value of a given column for the selected buys', async() => {
+        let ctx = {
+            args: {
+                search: 'Ranged weapon longbow 2m'
+            }
+        };
+
+        let [original] = await model.latestBuysFilter(ctx);
+
+        const column = {field: 'size', newValue: 99};
+        const buys = [{itemFk: 1, id: 3}];
+
+        await model.editLatestBuys(column, buys);
+
+        let [result] = await model.latestBuysFilter(ctx);
+
+        expect(result.size).toEqual(99);
+
+        column.newValue = original.size;
+        await model.editLatestBuys(column, buys);
+
+        let [restoredFixture] = await model.latestBuysFilter(ctx);
+
+        expect(restoredFixture.size).toEqual(original.size);
+    });
+});
diff --git a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js
index 2e2cab3464..ba18fcf576 100644
--- a/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js
+++ b/modules/entry/back/methods/entry/specs/latestBuysFilter.spec.js
@@ -1,15 +1,139 @@
 const app = require('vn-loopback/server/server');
 
-fdescribe('Entry latests buys filter()', () => {
+describe('Buy latests buys filter()', () => {
     it('should return the entry matching "search"', async() => {
         let ctx = {
             args: {
-                search: 1
+                search: 'Ranged weapon longbow 2m'
             }
         };
 
-        let result = await app.models.Entry.latestBuysFilter(ctx);
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+        let firstBuy = results[0];
 
-        expect(result[0].size).toEqual(300);
+        expect(results.length).toEqual(1);
+        expect(firstBuy.size).toEqual(70);
+    });
+
+    it('should return the entry matching "id"', async() => {
+        let ctx = {
+            args: {
+                id: 1
+            }
+        };
+
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+
+        expect(results.length).toEqual(1);
+    });
+
+    it('should return results matching "tags"', async() => {
+        let ctx = {
+            args: {
+                tags: [
+                    {tagFk: 27, value: '2m'}
+                ]
+            }
+        };
+
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+
+        expect(results.length).toBe(2);
+    });
+
+    it('should return results matching "categoryFk"', async() => {
+        let ctx = {
+            args: {
+                categoryFk: 1
+            }
+        };
+
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+
+        expect(results.length).toBe(4);
+    });
+
+    it('should return results matching "typeFk"', async() => {
+        let ctx = {
+            args: {
+                typeFk: 2
+            }
+        };
+
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+
+        expect(results.length).toBe(4);
+    });
+
+    it('should return results matching "active"', async() => {
+        let ctx = {
+            args: {
+                active: true
+            }
+        };
+
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+
+        expect(results.length).toBe(6);
+    });
+
+    it('should return results matching "not active"', async() => {
+        let ctx = {
+            args: {
+                active: false
+            }
+        };
+
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+
+        expect(results.length).toBe(0);
+    });
+
+    it('should return results matching "visible"', async() => {
+        let ctx = {
+            args: {
+                visible: true
+            }
+        };
+
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+
+        expect(results.length).toBe(5);
+    });
+
+    it('should return results matching "not visible"', async() => {
+        let ctx = {
+            args: {
+                visible: false
+            }
+        };
+
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+
+        expect(results.length).toBe(0);
+    });
+
+    it('should return results matching "salesPersonFk"', async() => {
+        let ctx = {
+            args: {
+                salesPersonFk: 35
+            }
+        };
+
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+
+        expect(results.length).toBe(6);
+    });
+
+    it('should return results matching "description"', async() => {
+        let ctx = {
+            args: {
+                description: 'Increases block'
+            }
+        };
+
+        let results = await app.models.Buy.latestBuysFilter(ctx);
+
+        expect(results.length).toBe(1);
     });
 });
diff --git a/modules/entry/front/descriptor/index.spec.js b/modules/entry/front/descriptor/index.spec.js
index 513425c765..84defea3bb 100644
--- a/modules/entry/front/descriptor/index.spec.js
+++ b/modules/entry/front/descriptor/index.spec.js
@@ -1,12 +1,14 @@
 import './index.js';
 
 describe('Entry Component vnEntryDescriptor', () => {
+    let $httpBackend;
     let controller;
     const entry = {id: 2};
 
     beforeEach(ngModule('entry'));
 
-    beforeEach(inject($componentController => {
+    beforeEach(inject(($componentController, _$httpBackend_) => {
+        $httpBackend = _$httpBackend_;
         controller = $componentController('vnEntryDescriptor', {$element: null}, {entry});
     }));
 
@@ -24,4 +26,18 @@ describe('Entry Component vnEntryDescriptor', () => {
             expect(controller.vnReport.show).toHaveBeenCalledWith('entry-order', params);
         });
     });
+
+    describe('loadData()', () => {
+        it('should perform ask for the entry', () => {
+            let query = `Entries/${entry.id}`;
+            jest.spyOn(controller, 'getData');
+
+            $httpBackend.expectGET(query).respond();
+            controller.loadData();
+            $httpBackend.flush();
+
+            expect(controller.getData).toHaveBeenCalledTimes(1);
+            expect(controller.getData).toHaveBeenCalledWith(query, jasmine.any(Object));
+        });
+    });
 });
diff --git a/modules/entry/front/latest-buys-search-panel/index.spec.js b/modules/entry/front/latest-buys-search-panel/index.spec.js
index 0fb8b2128f..6d403b9fbd 100644
--- a/modules/entry/front/latest-buys-search-panel/index.spec.js
+++ b/modules/entry/front/latest-buys-search-panel/index.spec.js
@@ -1,14 +1,14 @@
 import './index.js';
 
-xdescribe('Item', () => {
-    describe('Component vnItemSearchPanel', () => {
+describe('Entry', () => {
+    describe('Component vnLatestBuysSearchPanel', () => {
         let $element;
         let controller;
 
-        beforeEach(ngModule('item'));
+        beforeEach(ngModule('entry'));
 
         beforeEach(angular.mock.inject($componentController => {
-            $element = angular.element(`<div></div>`);
+            $element = angular.element(`<vn-latest-buys-search-panel></vn-latest-buys-search-panel>`);
             controller = $componentController('vnLatestBuysSearchPanel', {$element});
         }));
 
diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js
index b3b120af8c..6ce1995a12 100644
--- a/modules/entry/front/latest-buys/index.js
+++ b/modules/entry/front/latest-buys/index.js
@@ -47,7 +47,6 @@ export default class Controller extends Section {
     }
 
     uncheck() {
-        console.log('clicked!');
         const lines = this.checked;
         for (let line of lines) {
             if (line.checked)
@@ -73,8 +72,6 @@ export default class Controller extends Section {
             });
 
         this.editedColumn = null;
-
-        return false;
     }
 }
 
diff --git a/modules/entry/front/latest-buys/index.spec.js b/modules/entry/front/latest-buys/index.spec.js
new file mode 100644
index 0000000000..ed6d6ca21d
--- /dev/null
+++ b/modules/entry/front/latest-buys/index.spec.js
@@ -0,0 +1,91 @@
+import './index.js';
+
+describe('Entry', () => {
+    describe('Component vnEntryLatestBuys', () => {
+        let controller;
+        let $httpBackend;
+
+        beforeEach(ngModule('entry'));
+
+        beforeEach(angular.mock.inject(($componentController, $compile, $rootScope, _$httpBackend_) => {
+            $httpBackend = _$httpBackend_;
+            let $element = $compile('<vn-entry-latest-buys></vn-entry-latest-buys')($rootScope);
+            controller = $componentController('vnEntryLatestBuys', {$element});
+            controller.$ = {
+                model: {refresh: () => {}},
+                edit: {hide: () => {}}
+            };
+        }));
+
+        describe('get columns', () => {
+            it(`should return a set of columns`, () => {
+                let result = controller.columns;
+
+                let length = result.length;
+                let anyColumn = Object.keys(result[Math.floor(Math.random() * Math.floor(length))]);
+
+                expect(anyColumn).toContain('field', 'displayName');
+            });
+        });
+
+        describe('get checked', () => {
+            it(`should return a set of checked lines`, () => {
+                controller.$.model.data = [
+                    {checked: true, id: 1},
+                    {checked: true, id: 2},
+                    {checked: true, id: 3},
+                    {checked: false, id: 4},
+                ];
+
+                let result = controller.checked;
+
+                expect(result.length).toEqual(3);
+            });
+        });
+
+        describe('uncheck()', () => {
+            it(`should clear the selection of lines on the controller`, () => {
+                controller.$.model.data = [
+                    {checked: true, id: 1},
+                    {checked: true, id: 2},
+                    {checked: true, id: 3},
+                    {checked: false, id: 4},
+                ];
+
+                let result = controller.checked;
+
+                expect(result.length).toEqual(3);
+
+                controller.uncheck();
+
+                result = controller.checked;
+
+                expect(result.length).toEqual(0);
+            });
+        });
+
+        describe('onEditAccept()', () => {
+            it(`should perform a query to update columns and then `, () => {
+                controller.editedColumn = {someColumnName: 'some Value'};
+                let query = 'Buys/editLatestBuys';
+                controller.$.model.data = [
+                    {checked: true, id: 1},
+                    {checked: true, id: 2},
+                    {checked: true, id: 3},
+                    {checked: false, id: 4},
+                ];
+
+                expect(controller.editedColumn).toBeDefined();
+
+                $httpBackend.expectPOST(query).respond();
+                controller.onEditAccept();
+                $httpBackend.flush();
+
+                const result = controller.checked;
+
+                expect(result.length).toEqual(0);
+                expect(controller.editedColumn).toBeNull();
+            });
+        });
+    });
+});

From 5614a39f919b3642cb31fb665d600aa818358012 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Thu, 27 Aug 2020 15:29:48 +0200
Subject: [PATCH 062/109] traductuctions

---
 modules/entry/front/latest-buys/index.html    |  2 +-
 modules/entry/front/latest-buys/locale/es.yml | 13 ++++++++++++-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
index 9be2160675..dfe272208f 100644
--- a/modules/entry/front/latest-buys/index.html
+++ b/modules/entry/front/latest-buys/index.html
@@ -127,7 +127,7 @@
             icon="edit"
             ng-show="$ctrl.totalChecked > 0"
             ng-click="edit.show($event)"
-            vn-tooltip="Edit buys"
+            vn-tooltip="Edit buy(s)"
             tooltip-position="left">
         </vn-button>
     </vn-vertical>
diff --git a/modules/entry/front/latest-buys/locale/es.yml b/modules/entry/front/latest-buys/locale/es.yml
index 9eeab7bce4..572cb272b2 100644
--- a/modules/entry/front/latest-buys/locale/es.yml
+++ b/modules/entry/front/latest-buys/locale/es.yml
@@ -1 +1,12 @@
-Edit buys: Editar compras
\ No newline at end of file
+Edit buy(s): Editar compra(s)
+Buying value: Valor compra
+Freight value: Valor envío
+Comission value: Valor comisión
+Package value: Valor paquete
+Is ignored: Ignorado
+Grouping mode: Agrupación
+price2: Precio 2
+price3: Precio 3
+Min price: Precio min
+Weight: Peso
+Field to edit: Campo a editar
\ No newline at end of file

From 58fc25d91f9b967bb15e18fc31013efaa25fff2b Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Thu, 27 Aug 2020 16:40:08 +0200
Subject: [PATCH 063/109] grouping & packaging according to grouping mode

---
 modules/entry/front/latest-buys/index.html    | 14 ++++++++++----
 modules/entry/front/latest-buys/index.js      |  1 -
 modules/entry/front/latest-buys/locale/es.yml | 17 ++++++++---------
 3 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
index dfe272208f..fdf0f50abd 100644
--- a/modules/entry/front/latest-buys/index.html
+++ b/modules/entry/front/latest-buys/index.html
@@ -47,7 +47,6 @@
                 <vn-th field="comissionValue" expand>Comission value</vn-th>
                 <vn-th field="packageValue" expand>Package value</vn-th>
                 <vn-th field="isIgnored">Is ignored</vn-th>
-                <vn-th field="groupingMode" expand>Grouping mode</vn-th>
                 <vn-th field="price2">price2</vn-th>
                 <vn-th field="price3">price3</vn-th>
                 <vn-th field="minPrice">Min price</vn-th>
@@ -79,8 +78,16 @@
                         {{::buy.itemFk | zeroFill:6}}
                     </span>
                 </vn-td>
-                <vn-td number>{{::buy.grouping}}</vn-td>
-                <vn-td number>{{::buy.packing}}</vn-td>
+                <vn-td number>
+                    <vn-chip translate-attr="{title: 'Grouping'}" ng-class="{'message': buy.groupingMode == 1}"> 
+                        <span translate>{{::buy.grouping | dashIfEmpty}}</span>
+                    </vn-chip>
+                </vn-td>
+                <vn-td number>
+                    <vn-chip translate-attr="{title: 'Packing'}" ng-class="{'message': buy.groupingMode == 2}"> 
+                        <span translate>{{::buy.packing | dashIfEmpty}}</span>
+                    </vn-chip>
+                </vn-td>
                 <vn-td number>{{::buy.size}}</vn-td>
                 <vn-td shrink title="{{::buy.type}}">
                     {{::buy.type}}
@@ -110,7 +117,6 @@
                 <vn-td number>{{::buy.comissionValue | currency: 'EUR':2}}</vn-td>
                 <vn-td number>{{::buy.packageValue | currency: 'EUR':2}}</vn-td>
                 <vn-td shrink>{{::buy.isIgnored}}</vn-td>
-                <vn-td shrink>{{::buy.groupingMode}}</vn-td>
                 <vn-td number>{{::buy.price2 | currency: 'EUR':2}}</vn-td>
                 <vn-td number>{{::buy.price3 | currency: 'EUR':2}}</vn-td>
                 <vn-td number>{{::buy.minPrice | currency: 'EUR':2}}</vn-td>
diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js
index 6ce1995a12..7fac10ece3 100644
--- a/modules/entry/front/latest-buys/index.js
+++ b/modules/entry/front/latest-buys/index.js
@@ -20,7 +20,6 @@ export default class Controller extends Section {
             {field: 'freightValue', displayName: 'freightValue'},
             {field: 'packing', displayName: 'packing'},
             {field: 'grouping', displayName: 'grouping'},
-            {field: 'groupingMode', displayName: 'groupingMode'},
             {field: 'comissionValue', displayName: 'comissionValue'},
             {field: 'packageValue', displayName: 'packageValue'},
             {field: 'price2', displayName: 'price2'},
diff --git a/modules/entry/front/latest-buys/locale/es.yml b/modules/entry/front/latest-buys/locale/es.yml
index 572cb272b2..148c80e4ef 100644
--- a/modules/entry/front/latest-buys/locale/es.yml
+++ b/modules/entry/front/latest-buys/locale/es.yml
@@ -1,12 +1,11 @@
 Edit buy(s): Editar compra(s)
-Buying value: Valor compra
-Freight value: Valor envío
-Comission value: Valor comisión
-Package value: Valor paquete
+Buying value: Precio
+Freight value: Porte
+Commission value: Comisión
+Package value: Embalaje
 Is ignored: Ignorado
-Grouping mode: Agrupación
-price2: Precio 2
-price3: Precio 3
+price 2: Paquete
+price 3: Caja
 Min price: Precio min
-Weight: Peso
-Field to edit: Campo a editar
\ No newline at end of file
+Ekt: Ekt
+Weight: Peso
\ No newline at end of file

From 2f81e4188197b39b86ed207b9dadcf68d53385f0 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Thu, 27 Aug 2020 16:42:01 +0200
Subject: [PATCH 064/109] grping and pcking shown as per item last entries

---
 modules/entry/front/latest-buys/index.html | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
index fdf0f50abd..f389ec9530 100644
--- a/modules/entry/front/latest-buys/index.html
+++ b/modules/entry/front/latest-buys/index.html
@@ -31,8 +31,8 @@
                 </vn-th>
                 <vn-th field="picture">Picture</vn-th>
                 <vn-th field="id">Id</vn-th>
-                <vn-th field="grouping">Grouping</vn-th>
                 <vn-th field="packing">Packing</vn-th>
+                <vn-th field="grouping">Grouping</vn-th>
                 <vn-th field="size">Size</vn-th>
                 <vn-th field="type">Type</vn-th>
                 <vn-th field="intrastat">Intrastat</vn-th>
@@ -79,13 +79,13 @@
                     </span>
                 </vn-td>
                 <vn-td number>
-                    <vn-chip translate-attr="{title: 'Grouping'}" ng-class="{'message': buy.groupingMode == 1}"> 
-                        <span translate>{{::buy.grouping | dashIfEmpty}}</span>
+                    <vn-chip translate-attr="{title: 'Packing'}" ng-class="{'message': buy.groupingMode == 2}"> 
+                        <span translate>{{::buy.packing | dashIfEmpty}}</span>
                     </vn-chip>
                 </vn-td>
                 <vn-td number>
-                    <vn-chip translate-attr="{title: 'Packing'}" ng-class="{'message': buy.groupingMode == 2}"> 
-                        <span translate>{{::buy.packing | dashIfEmpty}}</span>
+                    <vn-chip translate-attr="{title: 'Grouping'}" ng-class="{'message': buy.groupingMode == 1}"> 
+                        <span translate>{{::buy.grouping | dashIfEmpty}}</span>
                     </vn-chip>
                 </vn-td>
                 <vn-td number>{{::buy.size}}</vn-td>

From c70ad808a0dc691297ead5cff78f362439b9fa58 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Thu, 27 Aug 2020 17:54:43 +0200
Subject: [PATCH 065/109] refactor

---
 db/dump/fixtures.sql                          | 68 +++++++++----------
 .../back/methods/entry/editLatestBuys.js      |  5 +-
 .../back/methods/entry/latestBuysFilter.js    |  6 +-
 modules/entry/back/models/buy.json            |  3 -
 modules/entry/front/latest-buys/index.html    |  4 +-
 modules/entry/front/latest-buys/locale/en.yml |  3 +
 modules/entry/front/latest-buys/locale/es.yml |  7 +-
 modules/item/back/models/item.json            |  3 +
 8 files changed, 52 insertions(+), 47 deletions(-)
 create mode 100644 modules/entry/front/latest-buys/locale/en.yml

diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 301f0a256b..fa738863c5 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -733,25 +733,25 @@ INSERT INTO `vn`.`intrastat`(`id`, `description`, `taxClassFk`, `taxCodeFk`)
         (05080000, 'Coral y materiales similares',        2, 2),
         (06021010, 'Plantas vivas: Esqueje/injerto, Vid', 1, 1);
 
-INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `isOnOffer`, `expenceFk`, `isBargain`, `comment`, `relevancy`, `image`, `taxClassFk`, `subName`)
+INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `isOnOffer`, `expenceFk`, `isBargain`, `comment`, `relevancy`, `image`, `taxClassFk`, `subName`, `minPrice`)
     VALUES
-        (1,  2, 70,   'AMA', 1,    1, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL),
-        (2,  2, 70,   'AZL', 1,    2, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL),
-        (3,  1, 60,   'AMR', 1,    3, NULL,              1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL),
-        (4,  1, 60,   'AMR', 1,    1, 'Increases block', 1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL),
-        (5,  3, 30,   'GRE', 1,    2, NULL,              2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (6,  5, 30,   'GRE', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (7,  5, 90,   'AZL', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (8,  2, 70,   'AMA', 1,    1, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL),
-        (9,  2, 70,   'AZL', 1,    2, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL),
-        (10, 1, 60,   'AMR', 1,    3, NULL,              1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL),
-        (11, 1, 60,   'AMR', 1,    1, NULL,              1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL),
-        (12, 3, 30,   'GRE', 1,    2, NULL,              2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (13, 5, 30,   'GRE', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (14, 5, 90,   'AZL', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (15, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (16, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (71, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL);
+        (1,  2, 70,   'AMA', 1,    1, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL, 0),
+        (2,  2, 70,   'AZL', 1,    2, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL, 0),
+        (3,  1, 60,   'AMR', 1,    3, NULL,              1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL, 0),
+        (4,  1, 60,   'AMR', 1,    1, 'Increases block', 1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL, 0),
+        (5,  3, 30,   'GRE', 1,    2, NULL,              2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
+        (6,  5, 30,   'GRE', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
+        (7,  5, 90,   'AZL', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
+        (8,  2, 70,   'AMA', 1,    1, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL, 0),
+        (9,  2, 70,   'AZL', 1,    2, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL, 0),
+        (10, 1, 60,   'AMR', 1,    3, NULL,              1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL, 0),
+        (11, 1, 60,   'AMR', 1,    1, NULL,              1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL, 0),
+        (12, 3, 30,   'GRE', 1,    2, NULL,              2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
+        (13, 5, 30,   'GRE', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
+        (14, 5, 90,   'AZL', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
+        (15, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
+        (16, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
+        (71, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0);
 
 INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`)
     VALUES
@@ -1233,23 +1233,23 @@ INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `saleTotal`, `saleWa
         ('HankPym',              YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)),   WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1),     'Miscellaneous Accessories',    '186',      '0',    '0.0'),
         ('HankPym',              YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)),   WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1),     'Adhesives',                    '277',      '0',    '0.0');
 
-INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`minPrice`,`producer`,`printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`)
+INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`producer`,`printedStickers`,`isChecked`,`isIgnored`,`weight`, `created`)
     VALUES
-        (1,  1, 1, 50,      5000,   4, 1, 1.500, 1.500, 0.000, 1,  1,  1, NULL, 0.00, 99.6, 99.4,   0.00, NULL, 0, 1, 0, 1,     DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
-        (2,  2, 1, 50,      100,    4, 1, 1.500, 1.500, 0.000, 1,  1,  1, NULL, 0.00, 99.6, 99.4,   0.00, NULL, 0, 1, 0, 1,     DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
-        (3,  3, 1, 50,      100,    4, 1, 1.500, 1.500, 0.000, 1,  1,  0, NULL, 0.00, 99.6, 99.4,   0.00, NULL, 0, 1, 0, 1,     CURDATE()),
-        (4,  2, 2, 5,       450,    3, 1, 1.000, 1.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00,   0.00, NULL, 0, 1, 0, 2.5,   CURDATE()),
-        (5,  3, 3, 55,      500,    5, 1, 1.000, 1.000, 0.000, 1,  1,  0, NULL, 0.00, 78.3, 75.6,   0.00, NULL, 0, 1, 0, 2.5,   CURDATE()),
-        (6,  4, 8, 50,      1000,   4, 1, 1.000, 1.000, 0.000, 1,  1,  1, NULL, 0.00, 99.6, 99.4,   0.00, NULL, 0, 1, 0, 2.5,   CURDATE()),
-        (7,  4, 9, 20,      1000,   3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 30.50, 29.00, 0.00, NULL, 0, 1, 0, 2.5,   CURDATE()),
-        (8,  4, 4, 1.25,    1000,   3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67,   0.00, NULL, 0, 1, 0, 2.5,   CURDATE()),
-        (9,  4, 4, 1.25,    1000,   3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67,   0.00, NULL, 0, 1, 0, 4,     CURDATE()),
-        (10, 5, 1, 50,      10,     4, 1, 2.500, 2.500, 0.000, 1,  1,  1, NULL, 0.00, 99.6, 99.4,   0.00, NULL, 0, 1, 0, 4,     CURDATE()),
-        (11, 5, 4, 1.25,    10,     3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67,   0.00, NULL, 0, 1, 0, 4,     CURDATE()),
-        (12, 6, 4, 1.25,    0,      3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67,   0.00, NULL, 0, 1, 0, 4,     CURDATE()),
-        (13, 7, 1, 50,      0,      3, 1, 2.000, 2.000, 0.000, 1,  1,  1, NULL, 0.00, 99.6, 99.4,   0.00, NULL, 0, 1, 0, 4,     CURDATE()),
-        (14, 7, 2, 5,       0,      3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 7.30, 7.00,   0.00, NULL, 0, 1, 0, 4,     CURDATE()),
-        (15, 7, 4, 1.25,    0,      3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67,   0.00, NULL, 0, 1, 0, 4,     CURDATE());
+        (1,  1, 1, 50,      5000,   4, 1, 1.500, 1.500, 0.000, 1,  1,  1, NULL, 0.00, 99.6, 99.4,   NULL, 0, 1, 0, 1,     DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
+        (2,  2, 1, 50,      100,    4, 1, 1.500, 1.500, 0.000, 1,  1,  1, NULL, 0.00, 99.6, 99.4,   NULL, 0, 1, 0, 1,     DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
+        (3,  3, 1, 50,      100,    4, 1, 1.500, 1.500, 0.000, 1,  1,  0, NULL, 0.00, 99.6, 99.4,   NULL, 0, 1, 0, 1,     CURDATE()),
+        (4,  2, 2, 5,       450,    3, 1, 1.000, 1.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00,   NULL, 0, 1, 0, 2.5,   CURDATE()),
+        (5,  3, 3, 55,      500,    5, 1, 1.000, 1.000, 0.000, 1,  1,  0, NULL, 0.00, 78.3, 75.6,   NULL, 0, 1, 0, 2.5,   CURDATE()),
+        (6,  4, 8, 50,      1000,   4, 1, 1.000, 1.000, 0.000, 1,  1,  1, NULL, 0.00, 99.6, 99.4,   NULL, 0, 1, 0, 2.5,   CURDATE()),
+        (7,  4, 9, 20,      1000,   3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 30.50, 29.00, NULL, 0, 1, 0, 2.5,   CURDATE()),
+        (8,  4, 4, 1.25,    1000,   3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67,   NULL, 0, 1, 0, 2.5,   CURDATE()),
+        (9,  4, 4, 1.25,    1000,   3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67,   NULL, 0, 1, 0, 4,     CURDATE()),
+        (10, 5, 1, 50,      10,     4, 1, 2.500, 2.500, 0.000, 1,  1,  1, NULL, 0.00, 99.6, 99.4,   NULL, 0, 1, 0, 4,     CURDATE()),
+        (11, 5, 4, 1.25,    10,     3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67,   NULL, 0, 1, 0, 4,     CURDATE()),
+        (12, 6, 4, 1.25,    0,      3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67,   NULL, 0, 1, 0, 4,     CURDATE()),
+        (13, 7, 1, 50,      0,      3, 1, 2.000, 2.000, 0.000, 1,  1,  1, NULL, 0.00, 99.6, 99.4,   NULL, 0, 1, 0, 4,     CURDATE()),
+        (14, 7, 2, 5,       0,      3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 7.30, 7.00,   NULL, 0, 1, 0, 4,     CURDATE()),
+        (15, 7, 4, 1.25,    0,      3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67,   NULL, 0, 1, 0, 4,     CURDATE());
 
 INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`)
     VALUES
diff --git a/modules/entry/back/methods/entry/editLatestBuys.js b/modules/entry/back/methods/entry/editLatestBuys.js
index acda6ed1cc..a65764d6f6 100644
--- a/modules/entry/back/methods/entry/editLatestBuys.js
+++ b/modules/entry/back/methods/entry/editLatestBuys.js
@@ -1,6 +1,6 @@
 module.exports = Self => {
     Self.remoteMethod('editLatestBuys', {
-        description: 'Updates a column for one of more buys',
+        description: 'Updates a column for one or more buys',
         accessType: 'WRITE',
         accepts: [{
             arg: 'column',
@@ -27,9 +27,11 @@ module.exports = Self => {
     Self.editLatestBuys = async(column, buys) => {
         let modelName;
         let identifier;
+
         switch (column.field) {
         case 'size':
         case 'density':
+        case 'minPrice':
             modelName = 'Item';
             identifier = 'itemFk';
             break;
@@ -43,7 +45,6 @@ module.exports = Self => {
         case 'packageValue':
         case 'price2':
         case 'price3':
-        case 'minPrice':
         case 'weight':
             modelName = 'Buy';
             identifier = 'id';
diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js
index 50cd8cf3c0..efb47e17c8 100644
--- a/modules/entry/back/methods/entry/latestBuysFilter.js
+++ b/modules/entry/back/methods/entry/latestBuysFilter.js
@@ -104,11 +104,12 @@ module.exports = Self => {
                 i.size,
                 i.density,
                 i.typeFk,
-                t.name AS type,
                 i.family,
+                i.isActive,
+                i.minPrice,
+                t.name AS type,
                 intr.description AS intrastat,
                 ori.code AS origin,
-                i.isActive,
                 b.entryFk,
                 b.id,
                 b.quantity,
@@ -122,7 +123,6 @@ module.exports = Self => {
                 b.packageValue,
                 b.price2,
                 b.price3,
-                b.minPrice,
                 b.ektFk,
                 b.weight
             FROM cache.last_buy lb
diff --git a/modules/entry/back/models/buy.json b/modules/entry/back/models/buy.json
index 14f2490d8f..1f3f1b8623 100644
--- a/modules/entry/back/models/buy.json
+++ b/modules/entry/back/models/buy.json
@@ -46,9 +46,6 @@
         "price3": {
             "type": "number"
         },
-        "minPrice": {
-            "type": "number"
-        },
         "weight": {
             "type": "number"
         }
diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
index f389ec9530..d06a5fe69d 100644
--- a/modules/entry/front/latest-buys/index.html
+++ b/modules/entry/front/latest-buys/index.html
@@ -79,12 +79,12 @@
                     </span>
                 </vn-td>
                 <vn-td number>
-                    <vn-chip translate-attr="{title: 'Packing'}" ng-class="{'message': buy.groupingMode == 2}"> 
+                    <vn-chip translate-attr="buy.groupingMode == 2 ? {title: 'Minimun amount'} : {title: 'Packing'}" ng-class="{'message': buy.groupingMode == 2}"> 
                         <span translate>{{::buy.packing | dashIfEmpty}}</span>
                     </vn-chip>
                 </vn-td>
                 <vn-td number>
-                    <vn-chip translate-attr="{title: 'Grouping'}" ng-class="{'message': buy.groupingMode == 1}"> 
+                    <vn-chip translate-attr="buy.groupingMode == 1 ? {title: 'Minimun amount'} : {title: 'Grouping'}" ng-class="{'message': buy.groupingMode == 1}"> 
                         <span translate>{{::buy.grouping | dashIfEmpty}}</span>
                     </vn-chip>
                 </vn-td>
diff --git a/modules/entry/front/latest-buys/locale/en.yml b/modules/entry/front/latest-buys/locale/en.yml
new file mode 100644
index 0000000000..c8b2263c03
--- /dev/null
+++ b/modules/entry/front/latest-buys/locale/en.yml
@@ -0,0 +1,3 @@
+Minimun amount: Minimun purchase quantity
+price2: Package
+price3: Box
\ No newline at end of file
diff --git a/modules/entry/front/latest-buys/locale/es.yml b/modules/entry/front/latest-buys/locale/es.yml
index 148c80e4ef..7a59f12e79 100644
--- a/modules/entry/front/latest-buys/locale/es.yml
+++ b/modules/entry/front/latest-buys/locale/es.yml
@@ -4,8 +4,9 @@ Freight value: Porte
 Commission value: Comisión
 Package value: Embalaje
 Is ignored: Ignorado
-price 2: Paquete
-price 3: Caja
+price2: Paquete
+price3: Caja
 Min price: Precio min
 Ekt: Ekt
-Weight: Peso
\ No newline at end of file
+Weight: Peso
+Minimun amount: Cantidad mínima de compra
\ No newline at end of file
diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json
index 5d2e47d2a3..c5af8890b6 100644
--- a/modules/item/back/models/item.json
+++ b/modules/item/back/models/item.json
@@ -122,6 +122,9 @@
             "mysql": {
                 "columnName": "expenceFk"
             }
+        },
+        "minPrice": {
+            "type": "number"
         }
     },
     "relations": {

From 0b4f65724ef0e0bde4bd617ceb73809b5a1a47e1 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 28 Aug 2020 10:40:47 +0200
Subject: [PATCH 066/109] semantics, traductions and small aditions

---
 .../back/methods/entry/editLatestBuys.js      |  9 ++++----
 .../back/methods/entry/latestBuysFilter.js    | 21 ++++++++++---------
 modules/entry/front/latest-buys/index.html    |  8 +++++--
 modules/entry/front/latest-buys/index.js      |  8 +++----
 modules/entry/front/latest-buys/locale/en.yml |  4 ++--
 modules/entry/front/latest-buys/locale/es.yml |  4 ++--
 6 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/modules/entry/back/methods/entry/editLatestBuys.js b/modules/entry/back/methods/entry/editLatestBuys.js
index a65764d6f6..68a9b9bb4e 100644
--- a/modules/entry/back/methods/entry/editLatestBuys.js
+++ b/modules/entry/back/methods/entry/editLatestBuys.js
@@ -9,7 +9,7 @@ module.exports = Self => {
             description: `the column to edit and it's new value`
         },
         {
-            arg: 'buys',
+            arg: 'lines',
             type: ['Object'],
             required: true,
             description: `the buys which will be modified`
@@ -24,7 +24,7 @@ module.exports = Self => {
         }
     });
 
-    Self.editLatestBuys = async(column, buys) => {
+    Self.editLatestBuys = async(column, lines) => {
         let modelName;
         let identifier;
 
@@ -32,6 +32,7 @@ module.exports = Self => {
         case 'size':
         case 'density':
         case 'minPrice':
+        case 'description':
             modelName = 'Item';
             identifier = 'itemFk';
             break;
@@ -59,8 +60,8 @@ module.exports = Self => {
             let promises = [];
             let options = {transaction: tx};
 
-            let targets = buys.map(buy => {
-                return buy[identifier];
+            let targets = lines.map(line => {
+                return line[identifier];
             });
 
             let value = {};
diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js
index efb47e17c8..dffe5793dc 100644
--- a/modules/entry/back/methods/entry/latestBuysFilter.js
+++ b/modules/entry/back/methods/entry/latestBuysFilter.js
@@ -27,13 +27,13 @@ module.exports = Self => {
                 description: 'List of tags to filter with',
                 http: {source: 'query'}
             }, {
-                arg: 'categoryFk',
-                type: 'Integer',
-                description: 'Category id',
+                arg: 'description',
+                type: 'String',
+                description: 'The item description',
             }, {
-                arg: 'typeFk',
+                arg: 'salesPersonFk',
                 type: 'Integer',
-                description: 'Type id',
+                description: 'The buyer of the item',
             }, {
                 arg: 'active',
                 type: 'Boolean',
@@ -43,13 +43,13 @@ module.exports = Self => {
                 type: 'Boolean',
                 description: 'Whether the the item is or not visible',
             }, {
-                arg: 'salesPersonFk',
+                arg: 'typeFk',
                 type: 'Integer',
-                description: 'The buyer of the item',
+                description: 'Type id',
             }, {
-                arg: 'description',
-                type: 'String',
-                description: 'The item description',
+                arg: 'categoryFk',
+                type: 'Integer',
+                description: 'Category id',
             }
         ],
         returns: {
@@ -107,6 +107,7 @@ module.exports = Self => {
                 i.family,
                 i.isActive,
                 i.minPrice,
+                i.description,
                 t.name AS type,
                 intr.description AS intrastat,
                 ori.code AS origin,
diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
index d06a5fe69d..fcdd32f1af 100644
--- a/modules/entry/front/latest-buys/index.html
+++ b/modules/entry/front/latest-buys/index.html
@@ -33,6 +33,7 @@
                 <vn-th field="id">Id</vn-th>
                 <vn-th field="packing">Packing</vn-th>
                 <vn-th field="grouping">Grouping</vn-th>
+                <vn-th field="description" style="text-align: center">Description</vn-th>
                 <vn-th field="size">Size</vn-th>
                 <vn-th field="type">Type</vn-th>
                 <vn-th field="intrastat">Intrastat</vn-th>
@@ -47,8 +48,8 @@
                 <vn-th field="comissionValue" expand>Comission value</vn-th>
                 <vn-th field="packageValue" expand>Package value</vn-th>
                 <vn-th field="isIgnored">Is ignored</vn-th>
-                <vn-th field="price2">price2</vn-th>
-                <vn-th field="price3">price3</vn-th>
+                <vn-th expand field="price2">price2</vn-th>
+                <vn-th expand field="price3">price3</vn-th>
                 <vn-th field="minPrice">Min price</vn-th>
                 <vn-th field="ektFk">Ekt</vn-th>
                 <vn-th field="weight">Weight</vn-th>
@@ -88,6 +89,9 @@
                         <span translate>{{::buy.grouping | dashIfEmpty}}</span>
                     </vn-chip>
                 </vn-td>
+                <vn-td expand title="{{::buy.description}}">
+                    {{::buy.description | dashIfEmpty}}
+                </vn-td>
                 <vn-td number>{{::buy.size}}</vn-td>
                 <vn-td shrink title="{{::buy.type}}">
                     {{::buy.type}}
diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js
index 7fac10ece3..e5ce23603d 100644
--- a/modules/entry/front/latest-buys/index.js
+++ b/modules/entry/front/latest-buys/index.js
@@ -24,11 +24,11 @@ export default class Controller extends Section {
             {field: 'packageValue', displayName: 'packageValue'},
             {field: 'price2', displayName: 'price2'},
             {field: 'price3', displayName: 'price3'},
-            {field: 'minPrice', displayName: 'minPrice'},
             {field: 'weight', displayName: 'weight'},
+            {field: 'description', displayName: 'description'},
+            {field: 'minPrice', displayName: 'minPrice'},
             {field: 'size', displayName: 'size'},
-            {field: 'density', displayName: 'density'},
-            {field: 'description', displayName: 'description'}
+            {field: 'density', displayName: 'density'}
         ];
 
         return this._columns;
@@ -60,7 +60,7 @@ export default class Controller extends Section {
     onEditAccept() {
         let data = {
             column: this.editedColumn,
-            buys: this.checked
+            lines: this.checked
         };
 
         this.$http.post('Buys/editLatestBuys', data)
diff --git a/modules/entry/front/latest-buys/locale/en.yml b/modules/entry/front/latest-buys/locale/en.yml
index c8b2263c03..43101bc65c 100644
--- a/modules/entry/front/latest-buys/locale/en.yml
+++ b/modules/entry/front/latest-buys/locale/en.yml
@@ -1,3 +1,3 @@
 Minimun amount: Minimun purchase quantity
-price2: Package
-price3: Box
\ No newline at end of file
+price2: Grouping price
+price3: Packing price
\ No newline at end of file
diff --git a/modules/entry/front/latest-buys/locale/es.yml b/modules/entry/front/latest-buys/locale/es.yml
index 7a59f12e79..5744016b49 100644
--- a/modules/entry/front/latest-buys/locale/es.yml
+++ b/modules/entry/front/latest-buys/locale/es.yml
@@ -4,8 +4,8 @@ Freight value: Porte
 Commission value: Comisión
 Package value: Embalaje
 Is ignored: Ignorado
-price2: Paquete
-price3: Caja
+price2: Precio grouping
+price3: Precio packing
 Min price: Precio min
 Ekt: Ekt
 Weight: Peso

From 8b26c41b7fa9bdda5acdc98cda068b85615d5637 Mon Sep 17 00:00:00 2001
From: jgallego <jgallego@verdnatura.es>
Date: Fri, 28 Aug 2020 17:06:27 +0200
Subject: [PATCH 067/109] campo packageFk

---
 db/dump/fixtures.sql                          | 52 +++++++++----------
 .../ticket/back/methods/expedition/filter.js  | 14 +++--
 modules/ticket/back/models/expedition.json    | 15 +++---
 modules/ticket/front/expedition/index.html    | 14 ++---
 package-lock.json                             | 32 ++++++------
 5 files changed, 63 insertions(+), 64 deletions(-)

diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 2b70cf2bee..6cb6e3455c 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -735,36 +735,36 @@ INSERT INTO `vn`.`intrastat`(`id`, `description`, `taxClassFk`, `taxCodeFk`)
 
 INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `isOnOffer`, `expenceFk`, `isBargain`, `comment`, `relevancy`, `image`, `taxClassFk`, `subName`)
     VALUES
-        (1,  2, 70,   'AMA', 1,    1, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL),
-        (2,  2, 70,   'AZL', 1,    2, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL),
-        (3,  1, 60,   'AMR', 1,    3, NULL, 1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL),
-        (4,  1, 60,   'AMR', 1,    1, NULL, 1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL),
-        (5,  3, 30,   'GRE', 1,    2, NULL, 2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (6,  5, 30,   'GRE', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (7,  5, 90,   'AZL', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (8,  2, 70,   'AMA', 1,    1, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL),
-        (9,  2, 70,   'AZL', 1,    2, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL),
-        (10, 1, 60,   'AMR', 1,    3, NULL, 1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL),
-        (11, 1, 60,   'AMR', 1,    1, NULL, 1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL),
-        (12, 3, 30,   'GRE', 1,    2, NULL, 2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (13, 5, 30,   'GRE', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
-        (14, 5, 90,   'AZL', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
+        (1,  2, 70,   'AMA', 1,    1, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 67, 1, NULL),
+        (2,  2, 70,   'AZL', 1,    2, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 66, 1, NULL),
+        (3,  1, 60,   'AMR', 1,    3, NULL, 1,    05080000, 0, 4751000000, 0, NULL, 0, 65, 1, NULL),
+        (4,  1, 60,   'AMR', 1,    1, NULL, 1,    05080000, 1, 4751000000, 0, NULL, 0, 69, 2, NULL),
+        (5,  3, 30,   'GRE', 1,    2, NULL, 2,    06021010, 1, 4751000000, 0, NULL, 0, 74, 2, NULL),
+        (6,  5, 30,   'GRE', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 62, 2, NULL),
+        (7,  5, 90,   'AZL', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 64, 2, NULL),
+        (8,  2, 70,   'AMA', 1,    1, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 75, 1, NULL),
+        (9,  2, 70,   'AZL', 1,    2, NULL, 1,    06021010, 0, 2000000000, 0, NULL, 0, 76, 1, NULL),
+        (10, 1, 60,   'AMR', 1,    3, NULL, 1,    05080000, 0, 4751000000, 0, NULL, 0, 77, 1, NULL),
+        (11, 1, 60,   'AMR', 1,    1, NULL, 1,    05080000, 1, 4751000000, 0, NULL, 0, 78, 2, NULL),
+        (12, 3, 30,   'GRE', 1,    2, NULL, 2,    06021010, 1, 4751000000, 0, NULL, 0, 82, 2, NULL),
+        (13, 5, 30,   'GRE', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 83, 2, NULL),
+        (14, 5, 90,   'AZL', 1,    2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 84, 2, NULL),
         (15, 4, NULL,  NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350,  2, NULL),
         (16, 4, NULL,  NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350,  2, NULL),
-        (71, 4, NULL,  NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, 67350,  2, NULL);
+        (71, 4, NULL,  NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, 88,  2, NULL);
 
-INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`)
+INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `workerFk`, `packagingFk`)
     VALUES
-        (1,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 18),
-        (2,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 18),
-        (3,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 3, 1, 18),
-        (4,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 18),
-        (5,  1, 2, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 18),
-        (6,  7, 3, 71, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 1, 1, 18),
-        (7,  2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 1, 1, 1, 18),
-        (8,  3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), 1, 1, 1, 18),
-        (9,  3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 18),
-        (10, 7, 7, 71, CURDATE(),                              1, 1, 1, 18);
+        (2,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 1),
+        (1,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
+        (3,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 3, 1, 1),
+        (4,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 1),
+        (5,  1, 2, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
+        (1,  7, 3, 71, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 1, 1, 1),
+        (7,  2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 1, 1, 1, 1),
+        (8,  3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), 1, 1, 1, 1),
+        (9,  3, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
+        (10, 7, 7, 71, CURDATE(),                              1, 1, 1, 1);
 
 INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPackageReturnable`, `created`, `itemFk`, `price`)
     VALUES
diff --git a/modules/ticket/back/methods/expedition/filter.js b/modules/ticket/back/methods/expedition/filter.js
index 3ff2fcb595..79c7131ea3 100644
--- a/modules/ticket/back/methods/expedition/filter.js
+++ b/modules/ticket/back/methods/expedition/filter.js
@@ -29,20 +29,24 @@ module.exports = Self => {
                 e.ticketFk,
                 e.isBox,
                 e.workerFk,
-                i1.name namePackage,
+                i1.name packageItemName,
                 e.counter,
                 e.checked,
-                i2.name nameBox,
+                i2.name freightItemName,
                 e.itemFk,
                 u.nickname userNickname,
                 e.created,
-                e.externalId
+                e.externalId,
+                i3.name packagingName,
+                i3.id packagingItemFk,
+                e.packagingFk
             FROM
                 vn.expedition e
                 LEFT JOIN vn.item i2 ON i2.id = e.itemFk 
                 INNER JOIN vn.item i1 ON i1.id = e.isBox
-                LEFT JOIN vn.worker w ON w.id = e.workerFk
-                LEFT JOIN account.user u ON u.id = w.userFk
+                LEFT JOIN vn.packaging p ON p.id = e.packagingFk
+                LEFT JOIN vn.item i3 ON i3.id = p.itemFk
+                LEFT JOIN account.user u ON u.id = e.workerFk
                 `);
         stmt.merge(Self.buildSuffix(filter, 'e'));
 
diff --git a/modules/ticket/back/models/expedition.json b/modules/ticket/back/models/expedition.json
index 4a9682e03a..c0b8d65085 100644
--- a/modules/ticket/back/models/expedition.json
+++ b/modules/ticket/back/models/expedition.json
@@ -24,12 +24,6 @@
       },
       "counter": {
         "type": "Number"
-      },
-      "checked": {
-        "type": "Number"
-      },
-      "externalId": {
-        "type": "Number"
       }
     },
     "relations": {
@@ -43,7 +37,7 @@
         "model": "agency-mode",
         "foreignKey": "agencyModeFk"
       },
-      "item": {
+      "packageItem": {
         "type": "belongsTo",
         "model": "Item",
         "foreignKey": "itemFk"
@@ -58,10 +52,15 @@
         "model": "TicketPackaging",
         "foreignKey": "ticketFk"
       },
-      "box": {
+      "freightItem": {
         "type": "belongsTo",
         "model": "Item",
         "foreignKey": "isBox"
+      },
+      "packaging": {
+        "type": "belongsTo",
+        "model": "Package",
+        "foreignKey": "packagingFk"
       }
     }
   }
diff --git a/modules/ticket/front/expedition/index.html b/modules/ticket/front/expedition/index.html
index 3b17a3b880..fc7b473cc7 100644
--- a/modules/ticket/front/expedition/index.html
+++ b/modules/ticket/front/expedition/index.html
@@ -14,12 +14,10 @@
             <vn-tr>
                 <vn-th></vn-th>
                 <vn-th field="itemFk" number>Expedition</vn-th>
-                <vn-th field="itemFk" number>Envialia</vn-th>
                 <vn-th field="itemFk" number>Item</vn-th>
                 <vn-th field="name">Name</vn-th>
                 <vn-th field="isBox">Package type</vn-th>
                 <vn-th field="counter" number>Counter</vn-th>
-                <vn-th field="checked" number>Checked</vn-th>
                 <vn-th field="worker">Worker</vn-th>
                 <vn-th field="created">Created</vn-th>
             </vn-tr>
@@ -33,18 +31,16 @@
                     </vn-icon-button>
                 </vn-td>
                 <vn-td number>{{expedition.id | zeroFill:6}}</vn-td>
-                <vn-td number>{{expedition.externalId | zeroFill:6}}</vn-td>
                 <vn-td number>
                     <span
-                        ng-class="{link: expedition.itemFk}"
-                        ng-click="itemDescriptor.show($event, expedition.itemFk)">
-                        {{expedition.itemFk | zeroFill:6}}
+                        ng-class="{link: expedition.packagingItemFk}"
+                        ng-click="itemDescriptor.show($event, expedition.packagingItemFk)">
+                        {{expedition.packagingFk}}
                     </span>
                 </vn-td>
-                <vn-td>{{::expedition.namePackage}}</vn-td>
-                <vn-td>{{::expedition.nameBox}}</vn-td>
+                <vn-td>{{::expedition.packageItemName}}</vn-td>
+                <vn-td>{{::expedition.freightItemName}}</vn-td>
                 <vn-td number>{{::expedition.counter}}</vn-td>
-                <vn-td number>{{::expedition.checked}}</vn-td>
                 <vn-td expand>
                     <span 
                         class="link" 
diff --git a/package-lock.json b/package-lock.json
index afded3c936..85f6650f19 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5824,7 +5824,7 @@
                 },
                 "util": {
                     "version": "0.10.3",
-                    "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
+                    "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
                     "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
                     "dev": true,
                     "requires": {
@@ -6786,7 +6786,7 @@
         "base": {
             "version": "0.11.2",
             "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
-            "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+            "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=",
             "dev": true,
             "requires": {
                 "cache-base": "^1.0.1",
@@ -7293,7 +7293,7 @@
         "cache-base": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
-            "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+            "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=",
             "dev": true,
             "requires": {
                 "collection-visit": "^1.0.0",
@@ -7507,7 +7507,7 @@
         "class-utils": {
             "version": "0.3.6",
             "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
-            "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+            "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=",
             "dev": true,
             "requires": {
                 "arr-union": "^3.1.0",
@@ -9765,7 +9765,7 @@
         },
         "file-loader": {
             "version": "1.1.11",
-            "resolved": "http://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz",
+            "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz",
             "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==",
             "dev": true,
             "requires": {
@@ -10951,7 +10951,7 @@
         "global-modules": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
-            "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+            "integrity": "sha1-bXcPDrUjrHgWTXK15xqIdyZcw+o=",
             "dev": true,
             "requires": {
                 "global-prefix": "^1.0.1",
@@ -13104,7 +13104,7 @@
         },
         "is-obj": {
             "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+            "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
             "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
         },
         "is-path-cwd": {
@@ -13134,7 +13134,7 @@
         "is-plain-object": {
             "version": "2.0.4",
             "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
-            "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+            "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=",
             "dev": true,
             "requires": {
                 "isobject": "^3.0.1"
@@ -13488,7 +13488,7 @@
         "jasmine-spec-reporter": {
             "version": "4.2.1",
             "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz",
-            "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==",
+            "integrity": "sha1-HWMq7ANBZwrTJPkrqEtLMrNeniI=",
             "dev": true,
             "requires": {
                 "colors": "1.1.2"
@@ -22342,7 +22342,7 @@
         },
         "safe-regex": {
             "version": "1.1.0",
-            "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+            "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
             "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
             "dev": true,
             "requires": {
@@ -22543,7 +22543,7 @@
             "dependencies": {
                 "source-map": {
                     "version": "0.4.4",
-                    "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+                    "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
                     "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
                     "dev": true,
                     "requires": {
@@ -22991,7 +22991,7 @@
         "snapdragon-node": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
-            "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+            "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=",
             "dev": true,
             "requires": {
                 "define-property": "^1.0.0",
@@ -23042,7 +23042,7 @@
         "snapdragon-util": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
-            "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+            "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=",
             "dev": true,
             "requires": {
                 "kind-of": "^3.2.0"
@@ -23326,7 +23326,7 @@
         "split-string": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
-            "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+            "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=",
             "dev": true,
             "requires": {
                 "extend-shallow": "^3.0.0"
@@ -24599,7 +24599,7 @@
         "touch": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
-            "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+            "integrity": "sha1-/jZfX3XsntTlaCXgu3bSSrdK+Ds=",
             "dev": true,
             "requires": {
                 "nopt": "~1.0.10"
@@ -26363,7 +26363,7 @@
         },
         "xmlbuilder": {
             "version": "9.0.7",
-            "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+            "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
             "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
         },
         "xmlchars": {

From 5c53c9301e94a763321f14b2e5954e9f367eff72 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Fri, 28 Aug 2020 19:52:54 +0200
Subject: [PATCH 068/109] path e2e + fixes + exclusion

---
 e2e/helpers/selectors.js                      | 38 +++++++++------
 e2e/paths/02-client/05_add_address.spec.js    |  1 +
 e2e/paths/05-ticket/10_request.spec.js        |  2 +-
 e2e/paths/08-route/03_create.spec.js          |  1 +
 .../09-invoice-out/02_descriptor.spec.js      |  5 +-
 e2e/paths/12-entry/03_latestBuys.spec.js      | 46 +++++++++++++++++++
 6 files changed, 76 insertions(+), 17 deletions(-)
 create mode 100644 e2e/paths/12-entry/03_latestBuys.spec.js

diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index 6eca623bd6..47fcc7edf0 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -219,23 +219,23 @@ export default {
         topbarSearch: 'vn-topbar',
         searchButton: 'vn-searchbar vn-icon[icon="search"]',
         closeItemSummaryPreview: '.vn-popup.shown',
-        fieldsToShowButton: 'vn-item-index vn-table > div > div > vn-icon-button[icon="menu"]',
-        fieldsToShowForm: '.vn-dialog.shown form',
+        fieldsToShowButton: 'vn-item-index vn-table > div > div > vn-icon-button[icon="more_vert"]',
+        fieldsToShowForm: '.vn-popover.shown .content',
         firstItemImage: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(1) > img',
         firstItemImageTd: 'vn-item-index vn-table a:nth-child(1) vn-td:nth-child(1)',
         firstItemId: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(2)',
-        idCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(2) > vn-check',
-        stemsCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(3) > vn-check',
-        sizeCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(4) > vn-check',
-        nicheCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(5) > vn-check',
-        typeCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(6) > vn-check',
-        categoryCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(7) > vn-check',
-        intrastadCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(8) > vn-check',
-        originCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(9) > vn-check',
-        buyerCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(10) > vn-check',
-        destinyCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(11) > vn-check',
-        taxClassCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(12) > vn-check',
-        saveFieldsButton: '.vn-dialog.shown vn-horizontal:nth-child(16) > vn-button > button'
+        idCheckbox: '.vn-popover.shown vn-horizontal:nth-child(2) > vn-check',
+        stemsCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check',
+        sizeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(4) > vn-check',
+        nicheCheckbox: '.vn-popover.shown vn-horizontal:nth-child(5) > vn-check',
+        typeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(6) > vn-check',
+        categoryCheckbox: '.vn-popover.shown vn-horizontal:nth-child(7) > vn-check',
+        intrastadCheckbox: '.vn-popover.shown vn-horizontal:nth-child(8) > vn-check',
+        originCheckbox: '.vn-popover.shown vn-horizontal:nth-child(9) > vn-check',
+        buyerCheckbox: '.vn-popover.shown vn-horizontal:nth-child(10) > vn-check',
+        destinyCheckbox: '.vn-popover.shown vn-horizontal:nth-child(11) > vn-check',
+        taxClassCheckbox: '.vn-popover.shown vn-horizontal:nth-child(12) > vn-check',
+        saveFieldsButton: '.vn-popover.shown vn-horizontal:nth-child(16) > vn-button > button'
     },
     itemCreateView: {
         temporalName: 'vn-item-create vn-textfield[ng-model="$ctrl.item.provisionalName"]',
@@ -897,5 +897,15 @@ export default {
         agency: 'vn-entry-descriptor div.body vn-label-value:nth-child(1) span',
         travelsQuicklink: 'vn-entry-descriptor vn-quick-link[icon="local_airport"] > a',
         entriesQuicklink: 'vn-entry-descriptor vn-quick-link[icon="icon-entry"] > a'
+    },
+    entryLatestBuys: {
+        firstBuy: 'vn-entry-latest-buys vn-tbody > a:nth-child(1)',
+        allBuysCheckBox: 'vn-entry-latest-buys vn-thead vn-check',
+        secondBuyCheckBox: 'vn-entry-latest-buys a:nth-child(2) vn-check[ng-model="buy.checked"]',
+        editBuysButton: 'vn-entry-latest-buys vn-button[icon="edit"]',
+        fieldAutocomplete: 'vn-autocomplete[ng-model="$ctrl.editedColumn.field"]',
+        newValueInput: 'vn-textfield[ng-model="$ctrl.editedColumn.newValue"]',
+        latestBuysSectionButton: 'a[ui-sref="entry.latestBuys"]',
+        acceptEditBuysDialog: 'button[response="accept"]'
     }
 };
diff --git a/e2e/paths/02-client/05_add_address.spec.js b/e2e/paths/02-client/05_add_address.spec.js
index f16408b343..c946bc7746 100644
--- a/e2e/paths/02-client/05_add_address.spec.js
+++ b/e2e/paths/02-client/05_add_address.spec.js
@@ -17,6 +17,7 @@ describe('Client Add address path', () => {
     });
 
     it(`should click on the add new address button to access to the new address form`, async() => {
+        await page.waitFor(500);
         await page.waitToClick(selectors.clientAddresses.createAddress);
         await page.waitForState('client.card.address.create');
     });
diff --git a/e2e/paths/05-ticket/10_request.spec.js b/e2e/paths/05-ticket/10_request.spec.js
index afab9b9e98..c01964d2b9 100644
--- a/e2e/paths/05-ticket/10_request.spec.js
+++ b/e2e/paths/05-ticket/10_request.spec.js
@@ -18,7 +18,7 @@ describe('Ticket purchase request path', () => {
     });
 
     it('should add a new request', async() => {
-        await page.waitFor('.vn-popup', {hidden: true}),
+        await page.waitFor(500);
         await page.waitToClick(selectors.ticketRequests.addRequestButton);
         await page.write(selectors.ticketRequests.descriptionInput, 'New stuff');
         await page.write(selectors.ticketRequests.quantity, '9');
diff --git a/e2e/paths/08-route/03_create.spec.js b/e2e/paths/08-route/03_create.spec.js
index 80c0071b6b..7c6c3f75d8 100644
--- a/e2e/paths/08-route/03_create.spec.js
+++ b/e2e/paths/08-route/03_create.spec.js
@@ -17,6 +17,7 @@ describe('Route create path', () => {
 
     describe('as employee', () => {
         it('should click on the add new route button and open the creation form', async() => {
+            await page.waitFor(500);
             await page.waitToClick(selectors.routeIndex.addNewRouteButton);
             await page.waitForState('route.create');
         });
diff --git a/e2e/paths/09-invoice-out/02_descriptor.spec.js b/e2e/paths/09-invoice-out/02_descriptor.spec.js
index ade121a8b4..b28730b4ed 100644
--- a/e2e/paths/09-invoice-out/02_descriptor.spec.js
+++ b/e2e/paths/09-invoice-out/02_descriptor.spec.js
@@ -1,7 +1,8 @@
 import selectors from '../../helpers/selectors.js';
 import getBrowser from '../../helpers/puppeteer';
 
-describe('InvoiceOut descriptor path', () => {
+// #2415 e2e fix InvoiceOut descriptor path
+xdescribe('InvoiceOut descriptor path', () => {
     let browser;
     let page;
 
@@ -63,7 +64,7 @@ describe('InvoiceOut descriptor path', () => {
             await page.waitForState('ticket.index');
         });
 
-        it('should search for tickets with an specific invoiceOut to find no results', async() => {
+        it('should search now for tickets with an specific invoiceOut to find no results', async() => {
             await page.doSearch('T2222222');
             const nResults = await page.countElement(selectors.ticketsIndex.searchResult);
 
diff --git a/e2e/paths/12-entry/03_latestBuys.spec.js b/e2e/paths/12-entry/03_latestBuys.spec.js
new file mode 100644
index 0000000000..e3cfadbcc8
--- /dev/null
+++ b/e2e/paths/12-entry/03_latestBuys.spec.js
@@ -0,0 +1,46 @@
+import selectors from '../../helpers/selectors.js';
+import getBrowser from '../../helpers/puppeteer';
+
+describe('Entry lastest buys path', () => {
+    let browser;
+    let page;
+
+    beforeAll(async() => {
+        browser = await getBrowser();
+        page = browser.page;
+        await page.loginAndModule('buyer', 'entry');
+    });
+
+    afterAll(async() => {
+        await browser.close();
+    });
+
+    it('should access the latest buys seccion and search not seeing the edit buys button yet', async() => {
+        await page.waitToClick(selectors.entryLatestBuys.latestBuysSectionButton);
+        await page.waitFor(250);
+        await page.keyboard.press('Enter');
+        await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: false});
+    });
+
+    it('should select all lines but one and then check the edit buys button appears', async() => {
+        await page.waitToClick(selectors.entryLatestBuys.allBuysCheckBox);
+        await page.waitToClick(selectors.entryLatestBuys.secondBuyCheckBox);
+        await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: true});
+    });
+
+    it('should open the edit dialog', async() => {
+        await page.waitToClick(selectors.entryLatestBuys.editBuysButton);
+        await page.waitForSelector(selectors.entryLatestBuys.fieldAutocomplete, {visible: true});
+    });
+
+    it('should search for the "Description" field and type a new description for the items in each selected buy', async() => {
+        await page.autocompleteSearch(selectors.entryLatestBuys.fieldAutocomplete, 'Description');
+        await page.write(selectors.entryLatestBuys.newValueInput, 'Crafted item');
+        await page.waitToClick(selectors.entryLatestBuys.acceptEditBuysDialog);
+    });
+
+    it('should navigate to the entry.buy section by clicking one of the buys', async() => {
+        await page.waitToClick(selectors.entryLatestBuys.firstBuy);
+        await page.waitForState('entry.card.buy');
+    });
+});

From baf9ec6e7052257702bfe8394fd5630964cfdd6c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 31 Aug 2020 08:32:30 +0200
Subject: [PATCH 069/109] 2416 - Item request - Added state filter

---
 e2e/paths/04-item/13_request.spec.js          |  4 +-
 front/core/components/contextmenu/index.js    |  4 +-
 .../front/request-search-panel/index.html     | 14 ++++---
 .../item/front/request-search-panel/index.js  | 14 ++++++-
 modules/item/front/request/index.html         | 38 ++++++++++++++++---
 modules/item/front/request/index.js           | 34 +++++++++++++++--
 modules/item/front/request/index.spec.js      |  6 +--
 modules/item/front/request/locale/es.yml      |  5 ++-
 .../back/methods/ticket-request/filter.js     | 10 +++--
 .../ticket/front/search-panel/locale/es.yml   |  2 +-
 10 files changed, 102 insertions(+), 29 deletions(-)

diff --git a/e2e/paths/04-item/13_request.spec.js b/e2e/paths/04-item/13_request.spec.js
index ab48e0c375..66cd7a0f5a 100644
--- a/e2e/paths/04-item/13_request.spec.js
+++ b/e2e/paths/04-item/13_request.spec.js
@@ -31,7 +31,7 @@ describe('Item request path', () => {
     it('should the status of the request should now be accepted', async() => {
         let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
 
-        expect(status).toContain('Aceptada');
+        expect(status).toContain('Accepted');
     });
 
     it('should now click on the second declain request icon then type the reason', async() => {
@@ -40,6 +40,6 @@ describe('Item request path', () => {
         await page.respondToDialog('accept');
         let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
 
-        expect(status).toContain('Denegada');
+        expect(status).toContain('Denied');
     });
 });
diff --git a/front/core/components/contextmenu/index.js b/front/core/components/contextmenu/index.js
index 90c14b7e3c..db74848a68 100755
--- a/front/core/components/contextmenu/index.js
+++ b/front/core/components/contextmenu/index.js
@@ -67,13 +67,13 @@ export default class Contextmenu {
     get cell() {
         if (!this.target) return null;
 
-        return this.target.closest('vn-td, .vn-td');
+        return this.target.closest('vn-td, .vn-td, vn-td-editable');
     }
 
     get cellIndex() {
         if (!this.row) return null;
 
-        const cells = this.row.querySelectorAll('vn-td, .vn-td');
+        const cells = this.row.querySelectorAll('vn-td, .vn-td, vn-td-editable');
         return Array.from(cells).findIndex(
             cellItem => cellItem == this.cell
         );
diff --git a/modules/item/front/request-search-panel/index.html b/modules/item/front/request-search-panel/index.html
index 453f3105b5..10d5f97620 100644
--- a/modules/item/front/request-search-panel/index.html
+++ b/modules/item/front/request-search-panel/index.html
@@ -56,12 +56,14 @@
                 label="For me" 
                 ng-model="filter.mine">
             </vn-check>
-            <vn-check 
-                vn-one 
-                triple-state="true" 
-                label="Confirmed" 
-                ng-model="filter.isOk">
-            </vn-check>
+            <vn-autocomplete
+                vn-one
+                ng-model="filter.state"
+                data="$ctrl.states"
+                value-field="code"
+                label="State">
+                <tpl-item>{{name}}</tpl-item>
+            </vn-autocomplete>
         </vn-horizontal>
         <vn-horizontal class="vn-mt-lg">
             <vn-submit label="Search"></vn-submit>
diff --git a/modules/item/front/request-search-panel/index.js b/modules/item/front/request-search-panel/index.js
index 82639b6e29..823346e30e 100644
--- a/modules/item/front/request-search-panel/index.js
+++ b/modules/item/front/request-search-panel/index.js
@@ -1,7 +1,19 @@
 import ngModule from '../module';
 import SearchPanel from 'core/components/searchbar/search-panel';
 
+class Controller extends SearchPanel {
+    constructor($element, $) {
+        super($element, $);
+
+        this.states = [
+            {code: 'pending', name: this.$t('Pending')},
+            {code: 'accepted', name: this.$t('Accepted')},
+            {code: 'denied', name: this.$t('Denied')}
+        ];
+    }
+}
+
 ngModule.vnComponent('vnRequestSearchPanel', {
     template: require('./index.html'),
-    controller: SearchPanel
+    controller: Controller
 });
diff --git a/modules/item/front/request/index.html b/modules/item/front/request/index.html
index a677d0754d..29a103746c 100644
--- a/modules/item/front/request/index.html
+++ b/modules/item/front/request/index.html
@@ -24,14 +24,15 @@
             <vn-tr>
                 <vn-th field="ticketFk" number>Ticket ID</vn-th>
                 <vn-th field="shipped" expand>Shipped</vn-th>
-                <vn-th field="description" expand>Description</vn-th>
+                <vn-th field="description" filter-enabled="false" expand>Description</vn-th>
                 <vn-th field="quantity" number editable>Requested</vn-th>
                 <vn-th field="price" number>Price</vn-th>
-                <vn-th field="atenderNickname">Atender</vn-th>
-                <vn-th field="itemFk">Item</vn-th>
+                <vn-th field="attenderName">Atender</vn-th>
+                <vn-th>Item</vn-th>
                 <vn-th field="saleQuantity">Achieved</vn-th>
-                <vn-th field="description">Concept</vn-th>
+                <vn-th field="description" filter-enabled="false">Concept</vn-th>
                 <vn-th field="isOk">State</vn-th>
+                <vn-th></vn-th>
             </vn-tr>
         </vn-thead>
         <vn-tbody>
@@ -83,7 +84,7 @@
                         {{request.itemDescription}}
                     </span>
                 </vn-td>
-                <vn-td>{{$ctrl.getState(request.isOk)}}</vn-td>
+                <vn-td translate>{{$ctrl.getState(request.isOk)}}</vn-td>
                 <vn-td>
                     <vn-icon
                         ng-if="request.response.length"
@@ -128,4 +129,29 @@
         <input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
         <button response="accept" translate>Save</button>
     </tpl-buttons>
-</vn-dialog>
\ No newline at end of file
+</vn-dialog>
+
+<vn-contextmenu vn-id="contextmenu" targets="['vn-data-viewer']" model="model"
+    expr-builder="$ctrl.exprBuilder(param, value)">
+    <slot-menu>
+        <vn-item translate
+        ng-if="contextmenu.isFilterAllowed()"
+        ng-click="contextmenu.filterBySelection()">
+            Filter by selection
+        </vn-item>
+        <vn-item translate 
+        ng-if="contextmenu.isFilterAllowed()" 
+        ng-click="contextmenu.excludeSelection()">
+            Exclude selection
+        </vn-item>
+        <vn-item translate 
+        ng-if="contextmenu.isFilterAllowed()" 
+        ng-click="contextmenu.removeFilter()" >
+            Remove filter
+        </vn-item>
+        <vn-item translate 
+        ng-click="contextmenu.removeAllFilters()" >
+            Remove all filters
+        </vn-item>
+    </slot-menu>
+</vn-contextmenu>
\ No newline at end of file
diff --git a/modules/item/front/request/index.js b/modules/item/front/request/index.js
index 3801c926fa..231d5eda74 100644
--- a/modules/item/front/request/index.js
+++ b/modules/item/front/request/index.js
@@ -17,18 +17,19 @@ export default class Controller extends Section {
             this.filterParams = {
                 mine: true,
                 from: today,
-                to: nextWeek
+                to: nextWeek,
+                state: 'pending'
             };
         }
     }
 
     getState(isOk) {
         if (isOk === null)
-            return 'Nueva';
+            return 'Pending';
         else if (isOk)
-            return 'Aceptada';
+            return 'Accepted';
         else
-            return 'Denegada';
+            return 'Denied';
     }
 
     confirmRequest(request) {
@@ -92,6 +93,31 @@ export default class Controller extends Section {
                 this.vnApp.showSuccess(this.$t('Data saved!'));
             });
     }
+
+    exprBuilder(param, value) {
+        switch (param) {
+        case 'ticketFk':
+        case 'quantity':
+        case 'price':
+        case 'isOk':
+            return {[`tr.${param}`]: value};
+        case 'attenderName':
+            return {[`ua.name`]: value};
+        case 'shipped':
+            return {'t.shipped': {
+                between: this.dateRange(value)}
+            };
+        }
+    }
+
+    dateRange(value) {
+        const minHour = new Date(value);
+        minHour.setHours(0, 0, 0, 0);
+        const maxHour = new Date(value);
+        maxHour.setHours(23, 59, 59, 59);
+
+        return [minHour, maxHour];
+    }
 }
 
 ngModule.vnComponent('vnItemRequest', {
diff --git a/modules/item/front/request/index.spec.js b/modules/item/front/request/index.spec.js
index a33a21ec21..0fc0610236 100644
--- a/modules/item/front/request/index.spec.js
+++ b/modules/item/front/request/index.spec.js
@@ -24,17 +24,17 @@ describe('Item', () => {
                 let isOk = null;
                 let result = controller.getState(isOk);
 
-                expect(result).toEqual('Nueva');
+                expect(result).toEqual('Pending');
 
                 isOk = 1;
                 result = controller.getState(isOk);
 
-                expect(result).toEqual('Aceptada');
+                expect(result).toEqual('Accepted');
 
                 isOk = 0;
                 result = controller.getState(isOk);
 
-                expect(result).toEqual('Denegada');
+                expect(result).toEqual('Denied');
             });
         });
 
diff --git a/modules/item/front/request/locale/es.yml b/modules/item/front/request/locale/es.yml
index 33710a3275..c61a001302 100644
--- a/modules/item/front/request/locale/es.yml
+++ b/modules/item/front/request/locale/es.yml
@@ -3,4 +3,7 @@ Specify the reasons to deny this request: Especifica las razones para descartar
 Buy requests:  Peticiones de compra
 Search request by id or alias: Buscar peticiones por identificador o alias
 Requested: Solicitado
-Achieved: Conseguido
\ No newline at end of file
+Achieved: Conseguido
+Pending: Pendiente
+Accepted: Aceptada
+Denied: Rechazada
\ No newline at end of file
diff --git a/modules/ticket/back/methods/ticket-request/filter.js b/modules/ticket/back/methods/ticket-request/filter.js
index ecd88caeb4..f1cd08662e 100644
--- a/modules/ticket/back/methods/ticket-request/filter.js
+++ b/modules/ticket/back/methods/ticket-request/filter.js
@@ -44,8 +44,8 @@ module.exports = Self => {
                 type: 'Date',
                 description: `Date to`
             }, {
-                arg: 'isOk',
-                type: 'Boolean',
+                arg: 'state',
+                type: 'String',
                 description: `Search request by request state`
             }
         ],
@@ -77,7 +77,11 @@ module.exports = Self => {
                 return {'t.id': value};
             case 'attenderFk':
                 return {'tr.attenderFk': value};
-            case 'isOk':
+            case 'state':
+                switch (value) {
+                case 'pending':
+                    return {'tr.isOk': null};
+                }
                 return {'tr.isOk': value};
             case 'clientFk':
                 return {'t.clientFk': value};
diff --git a/modules/ticket/front/search-panel/locale/es.yml b/modules/ticket/front/search-panel/locale/es.yml
index d8cde5b2a2..0e338ab0b5 100644
--- a/modules/ticket/front/search-panel/locale/es.yml
+++ b/modules/ticket/front/search-panel/locale/es.yml
@@ -12,4 +12,4 @@ Order id: Id cesta
 Grouped States: Estado agrupado
 Days onward: Días adelante
 With problems: Con problemas
-Pending: Pendientes
\ No newline at end of file
+Pending: Pendiente
\ No newline at end of file

From 95601f5d55dcf38a2fc51bada4c643edfa223825 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 31 Aug 2020 10:15:02 +0200
Subject: [PATCH 070/109] Updated translations

---
 modules/order/front/locale/es.yml              | 3 ++-
 modules/order/front/search-panel/locale/es.yml | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/modules/order/front/locale/es.yml b/modules/order/front/locale/es.yml
index fbc384f21c..c35898378f 100644
--- a/modules/order/front/locale/es.yml
+++ b/modules/order/front/locale/es.yml
@@ -23,4 +23,5 @@ Created from: Creado desde
 Search order by id: Buscar el pedido por identificador
 order: pedido
 Confirm lines: Confirmar las lineas
-Confirm: Confirmar
\ No newline at end of file
+Confirm: Confirmar
+Real hour: Hora real
\ No newline at end of file
diff --git a/modules/order/front/search-panel/locale/es.yml b/modules/order/front/search-panel/locale/es.yml
index 949f9b2024..9546c7f747 100644
--- a/modules/order/front/search-panel/locale/es.yml
+++ b/modules/order/front/search-panel/locale/es.yml
@@ -7,4 +7,5 @@ Agency: Agencia
 Application: Aplicación
 SalesPerson: Comercial
 Order confirmed: Pedido confirmado
-Show empty: Mostrar vacías
\ No newline at end of file
+Show empty: Mostrar vacías
+Search orders by id: Buscar pedido por id
\ No newline at end of file

From 6297d09de281efef3209e80a2a588e8541846b43 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 31 Aug 2020 12:14:39 +0200
Subject: [PATCH 071/109] Updated syntax

---
 modules/ticket/back/methods/ticket-request/filter.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/ticket/back/methods/ticket-request/filter.js b/modules/ticket/back/methods/ticket-request/filter.js
index f1cd08662e..4b7b088f4c 100644
--- a/modules/ticket/back/methods/ticket-request/filter.js
+++ b/modules/ticket/back/methods/ticket-request/filter.js
@@ -81,8 +81,9 @@ module.exports = Self => {
                 switch (value) {
                 case 'pending':
                     return {'tr.isOk': null};
+                default:
+                    return {'tr.isOk': value};
                 }
-                return {'tr.isOk': value};
             case 'clientFk':
                 return {'t.clientFk': value};
             case 'from':

From daee9081d11c834b16801116e030fbbd7f9164a4 Mon Sep 17 00:00:00 2001
From: "LaptopVerdnatura\\Javi" <jgallego@verdnatura.es>
Date: Mon, 31 Aug 2020 12:29:51 +0200
Subject: [PATCH 072/109] test excepto invoiceOut

---
 db/dump/fixtures.sql                     | 26 ++++++++++----------
 gulpfile.js                              |  1 -
 modules/item/front/basic-data/index.html |  8 +++++++
 package-lock.json                        | 30 ++++++++++++------------
 4 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 6cb6e3455c..9feecb0f65 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -753,19 +753,6 @@ INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `d
         (16, 4, NULL,  NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350,  2, NULL),
         (71, 4, NULL,  NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, 88,  2, NULL);
 
-INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `workerFk`, `packagingFk`)
-    VALUES
-        (2,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 1),
-        (1,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
-        (3,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 3, 1, 1),
-        (4,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 1),
-        (5,  1, 2, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
-        (1,  7, 3, 71, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 1, 1, 1),
-        (7,  2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 1, 1, 1, 1),
-        (8,  3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), 1, 1, 1, 1),
-        (9,  3, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
-        (10, 7, 7, 71, CURDATE(),                              1, 1, 1, 1);
-
 INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPackageReturnable`, `created`, `itemFk`, `price`)
     VALUES
         (1,             0.00,       10,     10,     0,      1, CURDATE(), 6,    1.50),
@@ -777,6 +764,19 @@ INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPack
         ('cc',          1640038.00, 56.00,  220.00, 128.00, 1, CURDATE(), 15,   90.00),
         ('pallet 100',  2745600.00, 100.00, 220.00, 120.00, 1, CURDATE(), 16,   0.00);
 
+INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `workerFk`, `packagingFk`)
+    VALUES
+        (1,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
+        (2,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 1),
+        (3,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 3, 1, 1),
+        (4,  1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 1),
+        (5,  1, 2, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
+        (6,  7, 3, 71, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 1, 1, 1),
+        (7,  2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 1, 1, 1, 1),
+        (8,  3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), 1, 1, 1, 1),
+        (9,  3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1),
+        (10, 7, 7, 71, CURDATE(),                              1, 1, 1, 1);
+
 INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`, `created`, `pvp`)
     VALUES
         (1, 1, 2, 2, CURDATE(), NULL),
diff --git a/gulpfile.js b/gulpfile.js
index 096c445845..d645ea0cd6 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -403,7 +403,6 @@ module.exports = {
     back,
     backOnly,
     backWatch,
-    backTestOnce,
     backTest,
     e2e,
     i,
diff --git a/modules/item/front/basic-data/index.html b/modules/item/front/basic-data/index.html
index 7b3504b3c4..99146deb00 100644
--- a/modules/item/front/basic-data/index.html
+++ b/modules/item/front/basic-data/index.html
@@ -109,6 +109,14 @@
                 ng-model="$ctrl.item.density"
                 rule>
             </vn-input-number>
+            <vn-input-number
+                vn-one
+                min="0"
+                step="0.01"
+                label="Compression" 
+                ng-model="$ctrl.item.compression"
+                rule>
+            </vn-input-number>
             <vn-input-number
                 vn-one
                 min="0"
diff --git a/package-lock.json b/package-lock.json
index 85f6650f19..37af78e3ae 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7102,7 +7102,7 @@
         },
         "browserify-rsa": {
             "version": "4.0.1",
-            "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+            "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
             "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
             "dev": true,
             "requires": {
@@ -7162,7 +7162,7 @@
         },
         "buffer": {
             "version": "4.9.1",
-            "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
             "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
             "requires": {
                 "base64-js": "^1.0.2",
@@ -7363,7 +7363,7 @@
         },
         "camelcase-keys": {
             "version": "2.1.0",
-            "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+            "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
             "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
             "dev": true,
             "requires": {
@@ -8664,7 +8664,7 @@
                 },
                 "readable-stream": {
                     "version": "1.1.14",
-                    "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+                    "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
                     "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
                     "dev": true,
                     "requires": {
@@ -10988,7 +10988,7 @@
         },
         "globby": {
             "version": "5.0.0",
-            "resolved": "http://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+            "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
             "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
             "dev": true,
             "requires": {
@@ -13104,7 +13104,7 @@
         },
         "is-obj": {
             "version": "1.0.1",
-            "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+            "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
             "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
         },
         "is-path-cwd": {
@@ -13488,7 +13488,7 @@
         "jasmine-spec-reporter": {
             "version": "4.2.1",
             "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz",
-            "integrity": "sha1-HWMq7ANBZwrTJPkrqEtLMrNeniI=",
+            "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==",
             "dev": true,
             "requires": {
                 "colors": "1.1.2"
@@ -18514,7 +18514,7 @@
         },
         "load-json-file": {
             "version": "1.1.0",
-            "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+            "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
             "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
             "dev": true,
             "requires": {
@@ -19395,7 +19395,7 @@
         },
         "media-typer": {
             "version": "0.3.0",
-            "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+            "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
             "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
         },
         "mem": {
@@ -19420,7 +19420,7 @@
         },
         "meow": {
             "version": "3.7.0",
-            "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+            "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
             "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
             "dev": true,
             "requires": {
@@ -19869,7 +19869,7 @@
         },
         "multipipe": {
             "version": "0.1.2",
-            "resolved": "http://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
+            "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
             "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=",
             "dev": true,
             "requires": {
@@ -20761,7 +20761,7 @@
         },
         "os-homedir": {
             "version": "1.0.2",
-            "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+            "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
             "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
             "dev": true
         },
@@ -20777,7 +20777,7 @@
         },
         "os-tmpdir": {
             "version": "1.0.2",
-            "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+            "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
             "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
             "dev": true
         },
@@ -24398,7 +24398,7 @@
         },
         "through": {
             "version": "2.3.8",
-            "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
+            "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
             "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
         },
         "through2": {
@@ -24681,7 +24681,7 @@
         },
         "tty-browserify": {
             "version": "0.0.0",
-            "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+            "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
             "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
             "dev": true
         },

From a156a26e19328a43249b1e6b567405f08a3b11fb Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Mon, 31 Aug 2020 15:00:11 +0200
Subject: [PATCH 073/109] e2e updated

---
 e2e/helpers/selectors.js               |  5 +++--
 e2e/paths/02-client/14_balance.spec.js | 21 +++++++++++++++++----
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index 6eca623bd6..d93b724834 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -189,8 +189,9 @@ export default {
         newPaymentBank: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]',
         newPaymentAmount: '.vn-dialog.shown vn-input-number[ng-model="$ctrl.receipt.amountPaid"]',
         saveButton: '.vn-dialog.shown [response="accept"]',
-        firstBalanceLine: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)'
-
+        firstLineBalance: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)',
+        firstLineReference: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td-editable',
+        firstLineReferenceInput: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td-editable > div > field > vn-textfield'
     },
     webPayment: {
         confirmFirstPaymentButton: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon-button[icon="done_all"]',
diff --git a/e2e/paths/02-client/14_balance.spec.js b/e2e/paths/02-client/14_balance.spec.js
index 108f767108..6c16d455d7 100644
--- a/e2e/paths/02-client/14_balance.spec.js
+++ b/e2e/paths/02-client/14_balance.spec.js
@@ -53,15 +53,28 @@ describe('Client balance path', () => {
         expect(message.type).toBe('success');
     });
 
-    it('should check balance is now 0 and the company is now VNL becouse the user local settings were removed', async() => {
+    it('should edit the 1st line reference', async() => {
+        await page.waitToClick(selectors.clientBalance.firstLineReference);
+        await page.write(selectors.clientBalance.firstLineReferenceInput, 'Miscellaneous payment');
+        await page.keyboard.press('Enter');
+        const message = await page.waitForSnackbar();
+
+        expect(message.type).toBe('success');
+    });
+
+    it('should check balance is now 0, the reference was saved and the company is now VNL becouse the user local settings were removed', async() => {
         await page.waitForSpinnerLoad();
         let company = await page
             .waitToGetProperty(selectors.clientBalance.company, 'value');
 
+        let reference = await page
+            .waitToGetProperty(selectors.clientBalance.firstLineReference, 'innerText');
+
         let firstBalanceLine = await page
-            .waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText');
+            .waitToGetProperty(selectors.clientBalance.firstLineBalance, 'innerText');
 
         expect(company).toEqual('VNL');
+        expect(reference).toEqual('Miscellaneous payment');
         expect(firstBalanceLine).toContain('0.00');
     });
 
@@ -76,7 +89,7 @@ describe('Client balance path', () => {
 
     it('should check balance is now -100', async() => {
         let result = await page
-            .waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText');
+            .waitToGetProperty(selectors.clientBalance.firstLineBalance, 'innerText');
 
         expect(result).toContain('-€100.00');
     });
@@ -92,7 +105,7 @@ describe('Client balance path', () => {
 
     it('should check balance is now 50', async() => {
         let result = await page
-            .waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText');
+            .waitToGetProperty(selectors.clientBalance.firstLineBalance, 'innerText');
 
         expect(result).toEqual('€50.00');
     });

From 8aa9918d844ec0c9b525b7bcf7a6afe0d07cc49d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 31 Aug 2020 15:03:00 +0200
Subject: [PATCH 074/109] 2409 - Added filter by selection

---
 .../item/back/methods/item/getLastEntries.js  | 28 ---------
 .../back/methods/item/lastEntriesFilter.js    | 62 +++++++++++++++++++
 ...ries.spec.js => lastEntriesFilter.spec.js} |  6 +-
 modules/item/back/models/item.js              |  2 +-
 modules/item/front/last-entries/index.html    | 48 +++++++++++---
 modules/item/front/last-entries/index.js      | 42 +++++++++++--
 6 files changed, 141 insertions(+), 47 deletions(-)
 delete mode 100644 modules/item/back/methods/item/getLastEntries.js
 create mode 100644 modules/item/back/methods/item/lastEntriesFilter.js
 rename modules/item/back/methods/item/specs/{getLastEntries.spec.js => lastEntriesFilter.spec.js} (73%)

diff --git a/modules/item/back/methods/item/getLastEntries.js b/modules/item/back/methods/item/getLastEntries.js
deleted file mode 100644
index a438afcb63..0000000000
--- a/modules/item/back/methods/item/getLastEntries.js
+++ /dev/null
@@ -1,28 +0,0 @@
-module.exports = Self => {
-    Self.remoteMethod('getLastEntries', {
-        description: 'Returns last entries',
-        accessType: 'READ',
-        accepts: [{
-            arg: 'filter',
-            type: 'object',
-            required: true,
-            description: 'itemFk, id'
-        }],
-        returns: {
-            type: 'Array',
-            root: true
-        },
-        http: {
-            path: `/getLastEntries`,
-            verb: 'GET'
-        }
-    });
-
-    Self.getLastEntries = async filter => {
-        let where = filter.where;
-        let query = `CALL vn.itemLastEntries(?, ?)`;
-        let [lastEntries] = await Self.rawSql(query, [where.itemFk, where.date]);
-
-        return lastEntries;
-    };
-};
diff --git a/modules/item/back/methods/item/lastEntriesFilter.js b/modules/item/back/methods/item/lastEntriesFilter.js
new file mode 100644
index 0000000000..63e154b9e8
--- /dev/null
+++ b/modules/item/back/methods/item/lastEntriesFilter.js
@@ -0,0 +1,62 @@
+
+const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
+
+module.exports = Self => {
+    Self.remoteMethod('lastEntriesFilter', {
+        description: 'Returns last entries',
+        accessType: 'READ',
+        accepts: [{
+            arg: 'filter',
+            type: 'object',
+            required: true,
+            description: 'itemFk, id'
+        }],
+        returns: {
+            type: 'Array',
+            root: true
+        },
+        http: {
+            path: `/lastEntriesFilter`,
+            verb: 'GET'
+        }
+    });
+
+    Self.lastEntriesFilter = async filter => {
+        const conn = Self.dataSource.connector;
+        const stmt = new ParameterizedSQL(
+            `SELECT
+                w.id AS warehouseFk,
+                w.name AS warehouse,
+                tr.landed,
+                b.id AS buyFk,
+                b.entryFk,
+                b.isIgnored,
+                b.price2, 
+                b.price3,
+                b.stickers,
+                b.packing,
+                b.grouping,
+                b.groupingMode,
+                b.weight,
+                i.stems,
+                b.quantity,
+                b.buyingValue,
+                b.packageFk ,
+                s.id AS supplierFk,
+                s.name AS supplier
+            FROM itemType it
+            RIGHT JOIN (entry e 
+                    LEFT JOIN supplier s ON s.id = e.supplierFk
+                    RIGHT JOIN buy b ON b.entryFk = e.id
+                    LEFT JOIN item i ON i.id = b.itemFk
+                    LEFT JOIN ink ON ink.id = i.inkFk 
+                    LEFT JOIN travel tr ON tr.id = e.travelFk
+                    LEFT JOIN warehouse w ON w.id = tr.warehouseInFk
+                    LEFT JOIN origin o ON o.id = i.originFk
+                    ) ON it.id = i.typeFk
+            LEFT JOIN edi.ekt ek ON b.ektFk = ek.id`);
+        stmt.merge(conn.makeSuffix(filter));
+
+        return conn.executeStmt(stmt);
+    };
+};
diff --git a/modules/item/back/methods/item/specs/getLastEntries.spec.js b/modules/item/back/methods/item/specs/lastEntriesFilter.spec.js
similarity index 73%
rename from modules/item/back/methods/item/specs/getLastEntries.spec.js
rename to modules/item/back/methods/item/specs/lastEntriesFilter.spec.js
index 5c996d8e3a..9ae54afe51 100644
--- a/modules/item/back/methods/item/specs/getLastEntries.spec.js
+++ b/modules/item/back/methods/item/specs/lastEntriesFilter.spec.js
@@ -1,10 +1,10 @@
 const app = require('vn-loopback/server/server');
 
-describe('item getLastEntries()', () => {
+describe('item lastEntriesFilter()', () => {
     it('should return one entry for a given item', async() => {
         let date = new Date();
         let filter = {where: {itemFk: 1, date: date}};
-        let result = await app.models.Item.getLastEntries(filter);
+        let result = await app.models.Item.lastEntriesFilter(filter);
 
         expect(result.length).toEqual(1);
     });
@@ -15,7 +15,7 @@ describe('item getLastEntries()', () => {
         date.setMonth(date.getMonth() - 2, 1);
 
         let filter = {where: {itemFk: 1, date: date}};
-        let result = await app.models.Item.getLastEntries(filter);
+        let result = await app.models.Item.lastEntriesFilter(filter);
 
         expect(result.length).toEqual(5);
     });
diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js
index d273404ea0..9ddd056e6a 100644
--- a/modules/item/back/models/item.js
+++ b/modules/item/back/models/item.js
@@ -5,7 +5,7 @@ module.exports = Self => {
     require('../methods/item/clone')(Self);
     require('../methods/item/updateTaxes')(Self);
     require('../methods/item/getBalance')(Self);
-    require('../methods/item/getLastEntries')(Self);
+    require('../methods/item/lastEntriesFilter')(Self);
     require('../methods/item/getSummary')(Self);
     require('../methods/item/getCard')(Self);
     require('../methods/item/regularize')(Self);
diff --git a/modules/item/front/last-entries/index.html b/modules/item/front/last-entries/index.html
index 6f2dba989c..f306fb4f02 100644
--- a/modules/item/front/last-entries/index.html
+++ b/modules/item/front/last-entries/index.html
@@ -1,11 +1,15 @@
 <vn-crud-model
     vn-id="model"
-    url="Items/getLastEntries"
+    url="Items/lastEntriesFilter"
     filter="::$ctrl.filter"
     data="entries"
-    auto-load="false">
+    auto-load="true"
+    order="landed DESC, buyFk DESC"
+    limit="20">
 </vn-crud-model>
-<vn-vertical>
+<vn-data-viewer
+    model="model"
+    class="vn-mb-xl vn-w-xl">
     <vn-card class="vn-pa-lg">
         <vn-vertical>
             <vn-horizontal>
@@ -20,8 +24,8 @@
                 <vn-thead>
                     <vn-tr>
                         <vn-th vn-tooltip="Ignored" center>Ig</vn-th>
-                        <vn-th>Warehouse</vn-th>
-                        <vn-th>Landed</vn-th>
+                        <vn-th field="warehouseFk">Warehouse</vn-th>
+                        <vn-th field="landed">Landed</vn-th>
                         <vn-th number>Entry</vn-th>
                         <vn-th number vn-tooltip="Price Per Unit">P.P.U</vn-th>
                         <vn-th number vn-tooltip="Price Per Package">P.P.P</vn-th>
@@ -29,11 +33,11 @@
                         <vn-th number>Packing</vn-th>
                         <vn-th number>Grouping</vn-th>
                         <vn-th number class="expendable">Stems</vn-th>
-                        <vn-th number>Quantity</vn-th>
+                        <vn-th field="quantity" number>Quantity</vn-th>
                         <vn-th number class="expendable">Cost</vn-th>
                         <vn-th number>Kg.</vn-th>
-                        <vn-th number>Cube</vn-th>
-                        <vn-th class="expendable">Provider</vn-th>
+                        <vn-th field="packageFk" number>Cube</vn-th>
+                        <vn-th field="supplierFk" class="expendable">Provider</vn-th>
                     </vn-tr>
                 </vn-thead>
                 <vn-tbody>
@@ -70,6 +74,30 @@
                 </vn-tbody>
             </vn-table>
         </vn-vertical>
-        <vn-pagination model="model"></vn-pagination>
     </vn-card>
-</vn-vertical>
+</vn-data-viewer>
+
+<vn-contextmenu vn-id="contextmenu" targets="['vn-data-viewer']" model="model"
+    expr-builder="$ctrl.exprBuilder(param, value)">
+    <slot-menu>
+        <vn-item translate
+        ng-if="contextmenu.isFilterAllowed()"
+        ng-click="contextmenu.filterBySelection()">
+            Filter by selection
+        </vn-item>
+        <vn-item translate 
+        ng-if="contextmenu.isFilterAllowed()" 
+        ng-click="contextmenu.excludeSelection()">
+            Exclude selection
+        </vn-item>
+        <vn-item translate 
+        ng-if="contextmenu.isFilterAllowed()" 
+        ng-click="contextmenu.removeFilter()" >
+            Remove filter
+        </vn-item>
+        <vn-item translate 
+        ng-click="contextmenu.removeAllFilters()" >
+            Remove all filters
+        </vn-item>
+    </slot-menu>
+</vn-contextmenu>
\ No newline at end of file
diff --git a/modules/item/front/last-entries/index.js b/modules/item/front/last-entries/index.js
index 3f9d7be36b..11a2bf20eb 100644
--- a/modules/item/front/last-entries/index.js
+++ b/modules/item/front/last-entries/index.js
@@ -6,17 +6,23 @@ class Controller extends Section {
     constructor($element, $) {
         super($element, $);
 
-        let defaultDate = new Date();
-        defaultDate.setDate(defaultDate.getDate() - 75);
-        defaultDate.setHours(0, 0, 0, 0);
+        const from = new Date();
+        from.setDate(from.getDate() - 75);
+        from.setHours(0, 0, 0, 0);
+
+        const to = new Date();
+        to.setDate(to.getDate() + 10);
+        to.setHours(23, 59, 59, 59);
 
         this.filter = {
             where: {
                 itemFk: this.$params.id,
-                date: defaultDate
+                shipped: {
+                    between: [from, to]
+                }
             }
         };
-        this._date = defaultDate;
+        this._date = from;
     }
 
     set date(value) {
@@ -31,6 +37,32 @@ class Controller extends Section {
     get date() {
         return this._date;
     }
+
+    exprBuilder(param, value) {
+        switch (param) {
+        case 'id':
+        case 'quantity':
+        case 'packageFk':
+            return {[`b.${param}`]: value};
+        case 'supplierFk':
+            return {[`s.id`]: value};
+        case 'warehouseFk':
+            return {'tr.warehouseInFk': value};
+        case 'landed':
+            return {'tr.landed': {
+                between: this.dateRange(value)}
+            };
+        }
+    }
+
+    dateRange(value) {
+        const minHour = new Date(value);
+        minHour.setHours(0, 0, 0, 0);
+        const maxHour = new Date(value);
+        maxHour.setHours(23, 59, 59, 59);
+
+        return [minHour, maxHour];
+    }
 }
 
 Controller.$inject = ['$element', '$scope'];

From 0a542a205780033bc32d819ace3a59ba5f5148b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 1 Sep 2020 07:38:03 +0200
Subject: [PATCH 075/109] Updated unit test

---
 .../item/specs/lastEntriesFilter.spec.js       | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/modules/item/back/methods/item/specs/lastEntriesFilter.spec.js b/modules/item/back/methods/item/specs/lastEntriesFilter.spec.js
index 9ae54afe51..f64bfed8a3 100644
--- a/modules/item/back/methods/item/specs/lastEntriesFilter.spec.js
+++ b/modules/item/back/methods/item/specs/lastEntriesFilter.spec.js
@@ -1,21 +1,23 @@
 const app = require('vn-loopback/server/server');
 
 describe('item lastEntriesFilter()', () => {
+    const minDate = new Date(value);
+    minHour.setHours(0, 0, 0, 0);
+    const maxDate = new Date(value);
+    maxHour.setHours(23, 59, 59, 59);
+
     it('should return one entry for a given item', async() => {
-        let date = new Date();
-        let filter = {where: {itemFk: 1, date: date}};
-        let result = await app.models.Item.lastEntriesFilter(filter);
+        const filter = {where: {itemFk: 1, landed: {between: [minDate, maxDate]}}};
+        const result = await app.models.Item.lastEntriesFilter(filter);
 
         expect(result.length).toEqual(1);
     });
 
     it('should return five entries for a given item', async() => {
-        let date = new Date();
+        minDate.setMonth(minDate.getMonth() - 2, 1);
 
-        date.setMonth(date.getMonth() - 2, 1);
-
-        let filter = {where: {itemFk: 1, date: date}};
-        let result = await app.models.Item.lastEntriesFilter(filter);
+        const filter = {where: {itemFk: 1, landed: {between: [minDate, maxDate]}}};
+        const result = await app.models.Item.lastEntriesFilter(filter);
 
         expect(result.length).toEqual(5);
     });

From 8ae7871318989ba6bca48b5d4723595d49591b30 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 1 Sep 2020 07:56:56 +0200
Subject: [PATCH 076/109] Removed procedure

---
 .../10200-normality/00-itemLastEntries.sql    | 44 +++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 db/changes/10200-normality/00-itemLastEntries.sql

diff --git a/db/changes/10200-normality/00-itemLastEntries.sql b/db/changes/10200-normality/00-itemLastEntries.sql
new file mode 100644
index 0000000000..ce600b39f0
--- /dev/null
+++ b/db/changes/10200-normality/00-itemLastEntries.sql
@@ -0,0 +1,44 @@
+
+USE `vn`;
+DROP procedure IF EXISTS `vn`.`itemLastEntries`;
+
+DELIMITER $$
+USE `vn`$$
+CREATE DEFINER=`root`@`%` PROCEDURE `itemLastEntries__`(IN `vItem` INT, IN `vDays` DATE)
+BEGIN
+	SELECT
+		w.id AS warehouseFk,
+        w.name AS warehouse,
+		tr.landed,
+		b.entryFk,
+		b.isIgnored,
+		b.price2, 
+		b.price3,
+		b.stickers,
+		b.packing,
+		b.`grouping`,
+        b.groupingMode,
+        b.weight,
+		i.stems,
+		b.quantity,
+		b.buyingValue,
+		b.packageFk ,
+		s.id AS supplierFk,
+        s.name AS supplier
+	FROM itemType it
+	RIGHT JOIN (entry e 
+			LEFT JOIN supplier s ON s.id = e.supplierFk
+			RIGHT JOIN buy b ON b.entryFk = e.id
+			LEFT JOIN item i ON i.id = b.itemFk
+			LEFT JOIN ink ON ink.id = i.inkFk 
+			LEFT JOIN travel tr ON tr.id = e.travelFk
+			LEFT JOIN warehouse w ON w.id = tr.warehouseInFk
+			LEFT JOIN origin o ON o.id = i.originFk
+			) ON it.id = i.typeFk
+	LEFT JOIN edi.ekt ek ON b.ektFk = ek.id
+	WHERE b.itemFk = vItem And tr.shipped BETWEEN  vDays AND DATE_ADD(CURDATE(), INTERVAl + 10 DAY)
+	ORDER BY tr.landed DESC , b.id DESC;
+END$$
+
+DELIMITER ;
+;

From a567738f2caa2675d97059d216dc0e8aa04cb25d Mon Sep 17 00:00:00 2001
From: jgallego <jgallego@verdnatura.es>
Date: Tue, 1 Sep 2020 08:33:11 +0200
Subject: [PATCH 077/109] set addressFk

---
 modules/ticket/front/basic-data/step-one/index.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/ticket/front/basic-data/step-one/index.js b/modules/ticket/front/basic-data/step-one/index.js
index 68f5ac54d7..45fd397ddf 100644
--- a/modules/ticket/front/basic-data/step-one/index.js
+++ b/modules/ticket/front/basic-data/step-one/index.js
@@ -155,7 +155,7 @@ class Controller extends Component {
         let query = `Clients/${value}`;
         this.$http.get(query).then(res => {
             if (res.data)
-                this.ticket.addressFk = res.data.defaultAddressFk;
+                this.addressId = res.data.defaultAddressFk;
         });
     }
 

From a5fbe571597dc36338268eaa06b0465b3c26ba22 Mon Sep 17 00:00:00 2001
From: jgallego <jgallego@verdnatura.es>
Date: Tue, 1 Sep 2020 08:42:31 +0200
Subject: [PATCH 078/109] gulpfile

---
 gulpfile.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gulpfile.js b/gulpfile.js
index d645ea0cd6..40590d7c27 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -404,6 +404,7 @@ module.exports = {
     backOnly,
     backWatch,
     backTest,
+    backTestOnce,
     e2e,
     i,
     install,

From ecb98dfac50c911d961d74fabe5600b937c631d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 1 Sep 2020 12:10:32 +0200
Subject: [PATCH 079/109] Descriptor fix

---
 modules/ticket/front/descriptor/index.js | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/modules/ticket/front/descriptor/index.js b/modules/ticket/front/descriptor/index.js
index 7ce94f53d4..fdcd50e3c0 100644
--- a/modules/ticket/front/descriptor/index.js
+++ b/modules/ticket/front/descriptor/index.js
@@ -8,7 +8,6 @@ class Controller extends Descriptor {
 
     set ticket(value) {
         this.entity = value;
-        this.isTicketEditable();
     }
 
     get entity() {
@@ -18,6 +17,7 @@ class Controller extends Descriptor {
     set entity(value) {
         super.entity = value;
         this.canStowaway();
+        this.isTicketEditable();
 
         if (value && this.$params.sendSMS)
             this.showSMSDialog();
@@ -45,7 +45,8 @@ class Controller extends Descriptor {
     }
 
     isTicketEditable() {
-        this.$http.get(`Tickets/${this.$state.params.id}/isEditable`).then(res => {
+        if (!this.ticket) return;
+        this.$http.get(`Tickets/${this.id}/isEditable`).then(res => {
             this.isEditable = res.data;
         });
     }

From 6a065091de9322e5d82cbfc10fced4836b79667f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Tue, 1 Sep 2020 15:13:33 +0200
Subject: [PATCH 080/109] First version of multicheck selection

---
 .../components/multi-check/multi-check.html   |  2 +-
 .../components/multi-check/multi-check.js     | 42 +++++++++++++++++--
 2 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/front/core/components/multi-check/multi-check.html b/front/core/components/multi-check/multi-check.html
index 86c35d6d0d..fb950aaff1 100644
--- a/front/core/components/multi-check/multi-check.html
+++ b/front/core/components/multi-check/multi-check.html
@@ -1,5 +1,5 @@
 <vn-check
     ng-model="$ctrl.checked"
-    intermediate="$ctrl.isIntermediate"
+    indeterminate="$ctrl.isIndeterminate"
     translate-attr="{title: 'Check all'}">
 </vn-check>
\ No newline at end of file
diff --git a/front/core/components/multi-check/multi-check.js b/front/core/components/multi-check/multi-check.js
index 3de9b4c718..d8fda64047 100644
--- a/front/core/components/multi-check/multi-check.js
+++ b/front/core/components/multi-check/multi-check.js
@@ -15,6 +15,19 @@ export default class MultiCheck extends FormInput {
         this._checked = false;
         this.checkField = 'checked';
         this.isIntermediate = false;
+        this.mayusEnabled = false;
+        this.window.addEventListener('keydown', event => {
+            if (event.key === 'Shift')
+                this.mayusEnabled = true;
+        });
+        this.window.addEventListener('keyup', event => {
+            if (event.key === 'Shift')
+                this.mayusEnabled = false;
+        });
+        this.window.addEventListener('selectstart', event => {
+            if (this.mayusEnabled)
+                event.preventDefault();
+        });
     }
 
     /**
@@ -28,7 +41,7 @@ export default class MultiCheck extends FormInput {
 
     /**
      * Sets the array model instance
-     * Changes intermediate property for
+     * Changes indeterminate property for
      * the check component
      *
      * @param {ArrayModel} value - Array model instance
@@ -37,8 +50,17 @@ export default class MultiCheck extends FormInput {
         this._model = value;
 
         if (value) {
-            value.on('rowChange', () => {
-                this.isIntermediate = !this.areAllUnchecked() && !this.areAllChecked();
+            value.on('rowChange', row => {
+                this.isIndeterminate = !this.areAllUnchecked() && !this.areAllChecked();
+
+                if (this.mayusEnabled) {
+                    this.currentSelection = row.obj.$orgIndex;
+
+                    if (this.lastSelection != undefined && this.currentSelection != undefined)
+                        this.setSelection(row.value, this.lastSelection, this.currentSelection);
+                }
+
+                this.lastSelection = row.obj.$orgIndex;
 
                 if (this.areAllChecked())
                     this._checked = true;
@@ -52,6 +74,20 @@ export default class MultiCheck extends FormInput {
         }
     }
 
+    setSelection(value, from, to) {
+        let start = from;
+        let end = to;
+
+        if (from > to) {
+            start = to;
+            end = from;
+        }
+
+        const data = this.model.data;
+        for (let i = start; i <= end; i++)
+            data[i].checked = value;
+    }
+
     /**
      * Gets current check state
      */

From 33aec33cba81bacde625810527629ed989bf0fd2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Wed, 2 Sep 2020 08:12:32 +0200
Subject: [PATCH 081/109] Updated unit test

---
 .../multi-check/multi-check.spec.js           | 40 +++++++++++++++++--
 modules/ticket/front/descriptor/index.spec.js |  2 +-
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/front/core/components/multi-check/multi-check.spec.js b/front/core/components/multi-check/multi-check.spec.js
index e49c68d2b0..c8069da3cc 100644
--- a/front/core/components/multi-check/multi-check.spec.js
+++ b/front/core/components/multi-check/multi-check.spec.js
@@ -62,7 +62,7 @@ describe('Component vnMultiCheck', () => {
     });
 
     describe('areAllChecked()', () => {
-        it(`should set return true if all elements are checked`, () => {
+        it(`should return true if all elements are checked`, () => {
             const data = controller.model.data;
             data[0].checked = true;
             data[1].checked = true;
@@ -71,7 +71,7 @@ describe('Component vnMultiCheck', () => {
             expect(controller.areAllChecked()).toBeTruthy();
         });
 
-        it(`should set return false if not all elements are checked`, () => {
+        it(`should return false if not all elements are checked`, () => {
             const data = controller.model.data;
             data[0].checked = true;
             data[1].checked = false;
@@ -82,7 +82,7 @@ describe('Component vnMultiCheck', () => {
     });
 
     describe('areAllUnchecked()', () => {
-        it(`should set return true if all elements are unchecked`, () => {
+        it(`should return true if all elements are unchecked`, () => {
             const data = controller.model.data;
             data[0].checked = false;
             data[1].checked = false;
@@ -91,7 +91,7 @@ describe('Component vnMultiCheck', () => {
             expect(controller.areAllUnchecked()).toBeTruthy();
         });
 
-        it(`should set return false if not all elements are unchecked`, () => {
+        it(`should return false if not all elements are unchecked`, () => {
             const data = controller.model.data;
             data[0].checked = false;
             data[1].checked = true;
@@ -100,4 +100,36 @@ describe('Component vnMultiCheck', () => {
             expect(controller.areAllUnchecked()).toBeFalsy();
         });
     });
+
+    describe('setSelection()', () => {
+        it(`should check all elements between the index range`, () => {
+            controller.setSelection(true, 0, 2);
+
+            const data = controller.model.data;
+            const firstRow = data[0];
+            const secondRow = data[1];
+            const thirdRow = data[2];
+
+            expect(firstRow.checked).toBeTruthy();
+            expect(secondRow.checked).toBeTruthy();
+            expect(thirdRow.checked).toBeTruthy();
+        });
+
+        it(`should uncheck all elements between the index range`, () => {
+            const data = controller.model.data;
+            const firstRow = data[0];
+            const secondRow = data[1];
+            const thirdRow = data[2];
+
+            firstRow.checked = true;
+            secondRow.checked = true;
+            thirdRow.checked = true;
+
+            controller.setSelection(false, 0, 1);
+
+            expect(firstRow.checked).toBeFalsy();
+            expect(secondRow.checked).toBeFalsy();
+            expect(thirdRow.checked).toBeTruthy();
+        });
+    });
 });
diff --git a/modules/ticket/front/descriptor/index.spec.js b/modules/ticket/front/descriptor/index.spec.js
index 4904f2ff15..fe7f60c148 100644
--- a/modules/ticket/front/descriptor/index.spec.js
+++ b/modules/ticket/front/descriptor/index.spec.js
@@ -28,7 +28,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
     beforeEach(inject(($componentController, _$httpBackend_, _$state_) => {
         $httpBackend = _$httpBackend_;
         $httpBackend.whenGET(`Tickets/${ticket.id}/canHaveStowaway`).respond(true);
-        $httpBackend.whenGET(`Tickets/1/isEditable`).respond(true);
+        $httpBackend.expect('GET', `Tickets/${ticket.id}/isEditable`).respond(true);
 
         $state = _$state_;
         $state.params.id = 1;

From 742a1c9ea8e7ead19c28cc719d769a4b0e7ec566 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Wed, 2 Sep 2020 09:42:10 +0200
Subject: [PATCH 082/109] removed focus on test

---
 modules/ticket/front/descriptor/index.spec.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/ticket/front/descriptor/index.spec.js b/modules/ticket/front/descriptor/index.spec.js
index 4904f2ff15..1a38ed6a97 100644
--- a/modules/ticket/front/descriptor/index.spec.js
+++ b/modules/ticket/front/descriptor/index.spec.js
@@ -135,7 +135,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
     });
 
     describe('canStowaway()', () => {
-        fit('should make a query and return if the ticket can be stowawayed', () => {
+        it('should make a query and return if the ticket can be stowawayed', () => {
             controller.canStowaway();
             $httpBackend.flush();
 

From 605fbe799943f9d69a29d7e88e54ae1e290c1f0f Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Wed, 2 Sep 2020 13:09:30 +0200
Subject: [PATCH 083/109] refactor

---
 front/core/directives/smart-table.js          |  3 +-
 .../back/methods/entry/editLatestBuys.js      | 19 ++++++----
 .../entry/specs/editLatestBuys.spec.js        | 11 +++---
 .../front/latest-buys-search-panel/index.js   |  2 +-
 .../latest-buys-search-panel/locale/es.yml    |  8 -----
 modules/entry/front/latest-buys/index.html    | 15 ++++----
 modules/entry/front/latest-buys/index.js      | 36 +++++++++----------
 modules/entry/front/latest-buys/index.spec.js | 13 ++-----
 modules/entry/front/latest-buys/locale/en.yml |  4 +--
 modules/entry/front/latest-buys/locale/es.yml |  7 ++--
 modules/item/front/index/index.html           |  2 +-
 modules/route/front/index/index.html          | 12 +++----
 modules/ticket/front/descriptor/index.spec.js | 13 +++----
 13 files changed, 66 insertions(+), 79 deletions(-)
 delete mode 100644 modules/entry/front/latest-buys-search-panel/locale/es.yml

diff --git a/front/core/directives/smart-table.js b/front/core/directives/smart-table.js
index c7072c09e0..08d1b6463a 100644
--- a/front/core/directives/smart-table.js
+++ b/front/core/directives/smart-table.js
@@ -4,11 +4,12 @@ import './smart-table.scss';
 
 /**
  * Directive to hide/show selected columns of a table, don't use with rowspan.
+ * Property smart-table-ignore ignores one or more vn-th with prop field.
  */
 directive.$inject = ['$http', '$compile', 'vnApp', '$translate'];
 export function directive($http, $compile, vnApp, $translate) {
     function getHeaderList($element, $scope) {
-        let filtrableHeaders = $element[0].querySelectorAll('vn-th[field]');
+        let filtrableHeaders = $element[0].querySelectorAll('vn-th[field]:not([smart-table-ignore])');
         let headerList = Array.from(filtrableHeaders);
         let ids = [];
         let titles = {};
diff --git a/modules/entry/back/methods/entry/editLatestBuys.js b/modules/entry/back/methods/entry/editLatestBuys.js
index 68a9b9bb4e..bd5358e316 100644
--- a/modules/entry/back/methods/entry/editLatestBuys.js
+++ b/modules/entry/back/methods/entry/editLatestBuys.js
@@ -3,10 +3,16 @@ module.exports = Self => {
         description: 'Updates a column for one or more buys',
         accessType: 'WRITE',
         accepts: [{
-            arg: 'column',
-            type: 'Object',
+            arg: 'field',
+            type: 'String',
             required: true,
-            description: `the column to edit and it's new value`
+            description: `the column to edit`
+        },
+        {
+            arg: 'newValue',
+            type: 'Any',
+            required: true,
+            description: `The new value to save`
         },
         {
             arg: 'lines',
@@ -24,11 +30,11 @@ module.exports = Self => {
         }
     });
 
-    Self.editLatestBuys = async(column, lines) => {
+    Self.editLatestBuys = async(field, newValue, lines) => {
         let modelName;
         let identifier;
 
-        switch (column.field) {
+        switch (field) {
         case 'size':
         case 'density':
         case 'minPrice':
@@ -65,8 +71,9 @@ module.exports = Self => {
             });
 
             let value = {};
-            value[column.field] = column.newValue;
+            value[field] = newValue;
 
+            // intentarlo con updateAll
             for (let target of targets)
                 promises.push(model.upsertWithWhere({id: target}, value, options));
 
diff --git a/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js b/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js
index c82ca036b4..5d1bd5a0da 100644
--- a/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js
+++ b/modules/entry/back/methods/entry/specs/editLatestBuys.spec.js
@@ -11,17 +11,18 @@ describe('Buy editLatestsBuys()', () => {
 
         let [original] = await model.latestBuysFilter(ctx);
 
-        const column = {field: 'size', newValue: 99};
-        const buys = [{itemFk: 1, id: 3}];
+        const field = 'size';
+        let newValue = 99;
+        const lines = [{itemFk: original.itemFk, id: original.id}];
 
-        await model.editLatestBuys(column, buys);
+        await model.editLatestBuys(field, newValue, lines);
 
         let [result] = await model.latestBuysFilter(ctx);
 
         expect(result.size).toEqual(99);
 
-        column.newValue = original.size;
-        await model.editLatestBuys(column, buys);
+        newValue = original.size;
+        await model.editLatestBuys(field, newValue, lines);
 
         let [restoredFixture] = await model.latestBuysFilter(ctx);
 
diff --git a/modules/entry/front/latest-buys-search-panel/index.js b/modules/entry/front/latest-buys-search-panel/index.js
index 187fe91719..adc95f43d0 100644
--- a/modules/entry/front/latest-buys-search-panel/index.js
+++ b/modules/entry/front/latest-buys-search-panel/index.js
@@ -5,7 +5,7 @@ class Controller extends SearchPanel {
     constructor($element, $) {
         super($element, $);
         let model = 'Item';
-        let moreFields = ['id', 'description', 'name'];
+        let moreFields = ['description', 'name'];
 
         let properties;
         let validations = window.validations;
diff --git a/modules/entry/front/latest-buys-search-panel/locale/es.yml b/modules/entry/front/latest-buys-search-panel/locale/es.yml
deleted file mode 100644
index 197da0695c..0000000000
--- a/modules/entry/front/latest-buys-search-panel/locale/es.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-Ink: Tinta
-Origin: Origen
-Producer: Productor.
-With visible: Con visible
-Field: Campo
-More fields: Más campos
-Add field: Añadir campo
-Remove field: Quitar campo
\ No newline at end of file
diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
index fcdd32f1af..4386971ad5 100644
--- a/modules/entry/front/latest-buys/index.html
+++ b/modules/entry/front/latest-buys/index.html
@@ -24,12 +24,12 @@
         vn-smart-table="latestBuys">
         <vn-thead>
             <vn-tr>
-                <vn-th shrink>
+                <vn-th smart-table-ignore shrink>
                     <vn-multi-check
                         model="model">
                     </vn-multi-check>
                 </vn-th>
-                <vn-th field="picture">Picture</vn-th>
+                <vn-th smart-table-ignore shrink></vn-th>
                 <vn-th field="id">Id</vn-th>
                 <vn-th field="packing">Packing</vn-th>
                 <vn-th field="grouping">Grouping</vn-th>
@@ -45,11 +45,11 @@
                 <vn-th field="quantity">Quantity</vn-th>
                 <vn-th field="buyingValue">Buying value</vn-th>
                 <vn-th field="freightValue">Freight value</vn-th>
-                <vn-th field="comissionValue" expand>Comission value</vn-th>
+                <vn-th field="comissionValue" expand>Commission value</vn-th>
                 <vn-th field="packageValue" expand>Package value</vn-th>
                 <vn-th field="isIgnored">Is ignored</vn-th>
-                <vn-th expand field="price2">price2</vn-th>
-                <vn-th expand field="price3">price3</vn-th>
+                <vn-th expand field="price2">Grouping price</vn-th>
+                <vn-th expand field="price3">Packing price</vn-th>
                 <vn-th field="minPrice">Min price</vn-th>
                 <vn-th field="ektFk">Ekt</vn-th>
                 <vn-th field="weight">Weight</vn-th>
@@ -68,7 +68,7 @@
                 <vn-td shrink >
                     <img 
                         ng-src="{{::$root.imagePath}}/catalog/50x50/{{::buy.image}}"
-                        zoom-image="{{::$root.imagePath}}/catalog/1600x900/{{::item.image}}"
+                        zoom-image="{{::$root.imagePath}}/catalog/1600x900/{{::buy.image}}"
                         vn-click-stop
                         on-error-src/>
                 </vn-td>
@@ -145,6 +145,7 @@
 <vn-dialog class="edit" 
     vn-id="edit"
     on-accept="$ctrl.onEditAccept()"
+    on-close="$ctrl.editedColumn = null"
     message="Edit buy(s)">
     <tpl-body>
         <vn-horizontal>
@@ -152,8 +153,8 @@
                 vn-two
                 ng-model="$ctrl.editedColumn.field"
                 data="$ctrl.columns"
-                show-field="displayName"
                 value-field="field"
+                show-field="displayName"
                 label="Field to edit">
             </vn-autocomplete>
             <vn-textfield
diff --git a/modules/entry/front/latest-buys/index.js b/modules/entry/front/latest-buys/index.js
index e5ce23603d..8d2c5fe13b 100644
--- a/modules/entry/front/latest-buys/index.js
+++ b/modules/entry/front/latest-buys/index.js
@@ -15,20 +15,20 @@ export default class Controller extends Section {
         if (this._columns) return this._columns;
 
         this._columns = [
-            {field: 'quantity', displayName: 'quantity'},
-            {field: 'buyingValue', displayName: 'buyingValue'},
-            {field: 'freightValue', displayName: 'freightValue'},
-            {field: 'packing', displayName: 'packing'},
-            {field: 'grouping', displayName: 'grouping'},
-            {field: 'comissionValue', displayName: 'comissionValue'},
-            {field: 'packageValue', displayName: 'packageValue'},
-            {field: 'price2', displayName: 'price2'},
-            {field: 'price3', displayName: 'price3'},
-            {field: 'weight', displayName: 'weight'},
-            {field: 'description', displayName: 'description'},
-            {field: 'minPrice', displayName: 'minPrice'},
-            {field: 'size', displayName: 'size'},
-            {field: 'density', displayName: 'density'}
+            {field: 'quantity', displayName: this.$t('Quantity')},
+            {field: 'buyingValue', displayName: this.$t('Buying value')},
+            {field: 'freightValue', displayName: this.$t('Freight value')},
+            {field: 'packing', displayName: this.$t('Packing')},
+            {field: 'grouping', displayName: this.$t('Grouping')},
+            {field: 'comissionValue', displayName: this.$t('Commission value')},
+            {field: 'packageValue', displayName: this.$t('Package value')},
+            {field: 'price2', displayName: this.$t('Grouping price')},
+            {field: 'price3', displayName: this.$t('Packing price')},
+            {field: 'weight', displayName: this.$t('Weight')},
+            {field: 'description', displayName: this.$t('Description')},
+            {field: 'minPrice', displayName: this.$t('Min price')},
+            {field: 'size', displayName: this.$t('Size')},
+            {field: 'density', displayName: this.$t('Density')}
         ];
 
         return this._columns;
@@ -59,18 +59,16 @@ export default class Controller extends Section {
 
     onEditAccept() {
         let data = {
-            column: this.editedColumn,
+            field: this.editedColumn.field,
+            newValue: this.editedColumn.newValue,
             lines: this.checked
         };
 
-        this.$http.post('Buys/editLatestBuys', data)
+        return this.$http.post('Buys/editLatestBuys', data)
             .then(() => {
-                this.$.edit.hide();
                 this.uncheck();
                 this.$.model.refresh();
             });
-
-        this.editedColumn = null;
     }
 }
 
diff --git a/modules/entry/front/latest-buys/index.spec.js b/modules/entry/front/latest-buys/index.spec.js
index ed6d6ca21d..658a2dc86c 100644
--- a/modules/entry/front/latest-buys/index.spec.js
+++ b/modules/entry/front/latest-buys/index.spec.js
@@ -65,17 +65,9 @@ describe('Entry', () => {
         });
 
         describe('onEditAccept()', () => {
-            it(`should perform a query to update columns and then `, () => {
-                controller.editedColumn = {someColumnName: 'some Value'};
+            it(`should perform a query to update columns`, () => {
+                controller.editedColumn = {field: 'my field', newValue: 'the new value'};
                 let query = 'Buys/editLatestBuys';
-                controller.$.model.data = [
-                    {checked: true, id: 1},
-                    {checked: true, id: 2},
-                    {checked: true, id: 3},
-                    {checked: false, id: 4},
-                ];
-
-                expect(controller.editedColumn).toBeDefined();
 
                 $httpBackend.expectPOST(query).respond();
                 controller.onEditAccept();
@@ -84,7 +76,6 @@ describe('Entry', () => {
                 const result = controller.checked;
 
                 expect(result.length).toEqual(0);
-                expect(controller.editedColumn).toBeNull();
             });
         });
     });
diff --git a/modules/entry/front/latest-buys/locale/en.yml b/modules/entry/front/latest-buys/locale/en.yml
index 43101bc65c..4f53d6126e 100644
--- a/modules/entry/front/latest-buys/locale/en.yml
+++ b/modules/entry/front/latest-buys/locale/en.yml
@@ -1,3 +1 @@
-Minimun amount: Minimun purchase quantity
-price2: Grouping price
-price3: Packing price
\ No newline at end of file
+Minimun amount: Minimun purchase quantity
\ No newline at end of file
diff --git a/modules/entry/front/latest-buys/locale/es.yml b/modules/entry/front/latest-buys/locale/es.yml
index 5744016b49..7144caa8aa 100644
--- a/modules/entry/front/latest-buys/locale/es.yml
+++ b/modules/entry/front/latest-buys/locale/es.yml
@@ -4,9 +4,10 @@ Freight value: Porte
 Commission value: Comisión
 Package value: Embalaje
 Is ignored: Ignorado
-price2: Precio grouping
-price3: Precio packing
+Grouping price: Precio grouping
+Packing price: Precio packing
 Min price: Precio min
 Ekt: Ekt
 Weight: Peso
-Minimun amount: Cantidad mínima de compra
\ No newline at end of file
+Minimun amount: Cantidad mínima de compra
+Field to edit: Campo a editar
\ No newline at end of file
diff --git a/modules/item/front/index/index.html b/modules/item/front/index/index.html
index b34445d367..eaef0f34f2 100644
--- a/modules/item/front/index/index.html
+++ b/modules/item/front/index/index.html
@@ -11,7 +11,7 @@
         vn-smart-table="itemIndex">
         <vn-thead>
             <vn-tr>
-                <vn-th field="picture" shrink></vn-th>
+                <vn-th shrink></vn-th>
                 <vn-th field="id" shrink>Id</vn-th>
                 <vn-th field="grouping" shrink>Grouping</vn-th>
                 <vn-th field="packing" shrink>Packing</vn-th>
diff --git a/modules/route/front/index/index.html b/modules/route/front/index/index.html
index 909d782490..7258018f10 100644
--- a/modules/route/front/index/index.html
+++ b/modules/route/front/index/index.html
@@ -14,12 +14,12 @@
                     </vn-multi-check>
                 </vn-th>
                 <vn-th field="id" number>Id</vn-th>
-                <vn-th field="worker">Worker</vn-th>
-                <vn-th field="agency">Agency</vn-th>
-                <vn-th field="vehicle">Vehicle</vn-th>
-                <vn-th field="created">Date</vn-th>
-                <vn-th field="m3" number>m³</vn-th>
-                <vn-th field="description">Description</vn-th>
+                <vn-th th-id="worker">Worker</vn-th>
+                <vn-th th-id="agency">Agency</vn-th>
+                <vn-th th-id="vehicle">Vehicle</vn-th>
+                <vn-th th-id="created">Date</vn-th>
+                <vn-th th-id="m3" number>m³</vn-th>
+                <vn-th th-id="description">Description</vn-th>
                 <vn-th shrink></vn-th>
             </vn-tr>
         </vn-thead>
diff --git a/modules/ticket/front/descriptor/index.spec.js b/modules/ticket/front/descriptor/index.spec.js
index 5bdbe34016..a725a2d4aa 100644
--- a/modules/ticket/front/descriptor/index.spec.js
+++ b/modules/ticket/front/descriptor/index.spec.js
@@ -70,7 +70,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
 
             window.open = jasmine.createSpy('open');
             const params = {
-                clientId: ticket.client.id,
+                recipientId: ticket.client.id,
                 ticketId: ticket.id
             };
             controller.showDeliveryNote();
@@ -85,7 +85,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
 
             const params = {
                 recipient: ticket.client.email,
-                clientId: ticket.client.id,
+                recipientId: ticket.client.id,
                 ticketId: ticket.id
             };
             controller.sendDeliveryNote();
@@ -179,13 +179,10 @@ describe('Ticket Component vnTicketDescriptor', () => {
 
     describe('loadData()', () => {
         it(`should perform a get query to store the ticket data into the controller`, () => {
-            controller.ticket = null;
-
-            $httpBackend.expectRoute('GET', `Tickets/${ticket.id}`).respond(ticket);
-            controller.id = ticket.id;
+            $httpBackend.when('GET', `Tickets/${ticket.id}/isEditable`).respond();
+            $httpBackend.expectRoute('GET', `Tickets/${ticket.id}`).respond();
+            controller.loadData();
             $httpBackend.flush();
-
-            expect(controller.ticket).toEqual(ticket);
         });
     });
 });

From a3382300f97d207ed6fef2cf3ef0e699695a81e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Wed, 2 Sep 2020 14:08:56 +0200
Subject: [PATCH 084/109] 2402 - Added create entry section

---
 modules/entry/back/models/entry.json     |  2 +-
 modules/entry/front/create/index.html    | 54 ++++++++++++++++++++++++
 modules/entry/front/create/index.js      | 42 ++++++++++++++++++
 modules/entry/front/create/locale/es.yml |  1 +
 modules/entry/front/index.js             |  1 +
 modules/entry/front/index/index.html     | 14 +++++-
 modules/entry/front/routes.json          |  6 +++
 modules/item/back/models/supplier.json   |  4 +-
 modules/route/front/index/index.html     |  3 +-
 modules/ticket/front/index/index.html    |  3 +-
 10 files changed, 122 insertions(+), 8 deletions(-)
 create mode 100644 modules/entry/front/create/index.html
 create mode 100644 modules/entry/front/create/index.js
 create mode 100644 modules/entry/front/create/locale/es.yml

diff --git a/modules/entry/back/models/entry.json b/modules/entry/back/models/entry.json
index d3f149680f..2739156ea5 100644
--- a/modules/entry/back/models/entry.json
+++ b/modules/entry/back/models/entry.json
@@ -1,6 +1,6 @@
 {
     "name": "Entry",
-    "base": "VnModel",
+    "base": "Loggable",
     "log": {
 		"model":"EntryLog"
 	},
diff --git a/modules/entry/front/create/index.html b/modules/entry/front/create/index.html
new file mode 100644
index 0000000000..3bc086f4e9
--- /dev/null
+++ b/modules/entry/front/create/index.html
@@ -0,0 +1,54 @@
+<mg-ajax path="Entries" options="vnPost"></mg-ajax>
+<vn-watcher
+    vn-id="watcher"
+    data="$ctrl.entry"
+    form="form"
+    save="post">
+</vn-watcher>
+<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
+    <vn-card class="vn-pa-lg">
+        <vn-horizontal>
+            <vn-autocomplete 
+                vn-one
+                ng-model="$ctrl.entry.supplierFk"
+                url="Suppliers"
+                show-field="nickname"
+                search-function="{or: [{id: $search}, {name: {like: '%'+ $search +'%'}}]}"
+                value-field="id"
+                order="nickname"
+                label="Supplier">
+                <tpl-item>
+                    {{::id}} - {{::nickname}}
+                </tpl-item>
+            </vn-autocomplete>
+        </vn-horizontal>
+        <vn-horizontal>
+            <vn-autocomplete 
+                vn-one
+                ng-model="$ctrl.entry.travelFk"
+                url="Travels/filter"
+                search-function="$ctrl.searchFunction($search)"
+                value-field="t.id"
+                order="t.id"
+                label="Travel">
+                <tpl-item>
+                    {{::agencyModeName}} - {{::warehouseInName}} ({{::shipped | date: 'dd/MM/yyyy'}}) &#x2192;
+                    {{::warehouseOutName}} ({{::landed | date: 'dd/MM/yyyy'}})
+                </tpl-item>
+            </vn-autocomplete>
+        </vn-horizontal>
+        <vn-horizontal>
+            <vn-autocomplete
+                url="Companies"
+                label="Company"
+                show-field="code"
+                value-field="id"
+                ng-model="$ctrl.entry.companyFk">
+            </vn-autocomplete>
+        </vn-horizontal>
+    </vn-card>
+    <vn-button-bar>
+        <vn-submit label="Create"></vn-submit>
+        <vn-button ui-sref="entry.index" label="Cancel"></vn-button>
+    </vn-button-bar>
+</form>
diff --git a/modules/entry/front/create/index.js b/modules/entry/front/create/index.js
new file mode 100644
index 0000000000..b94cbe2ca9
--- /dev/null
+++ b/modules/entry/front/create/index.js
@@ -0,0 +1,42 @@
+import ngModule from '../module';
+import Section from 'salix/components/section';
+
+export default class Controller extends Section {
+    constructor($element, $) {
+        super($element, $);
+
+        this.entry = {
+            companyFk: this.vnConfig.companyFk
+        };
+
+        if (this.$params && this.$params.supplierFk)
+            this.entry.supplierFk = parseInt(this.$params.supplierFk);
+        if (this.$params && this.$params.travelFk)
+            this.entry.travelFk = parseInt(this.$params.travelFk);
+        if (this.$params && this.$params.companyFk)
+            this.entry.companyFk = parseInt(this.$params.companyFk);
+    }
+
+    onSubmit() {
+        this.$.watcher.submit().then(
+            res => this.$state.go('entry.card.basicData', {id: res.data.id})
+        );
+    }
+
+    searchFunction($search) {
+        return {or: [
+            {'am.name': {like: `%${$search}%`}},
+            {'win.name': {like: `%${$search}%`}},
+            {'wout.name': {like: `%${$search}%`}},
+            {'t.shipped': new Date($search)},
+            {'t.landed': new Date($search)}
+        ]};
+    }
+}
+
+Controller.$inject = ['$element', '$scope'];
+
+ngModule.vnComponent('vnEntryCreate', {
+    template: require('./index.html'),
+    controller: Controller
+});
diff --git a/modules/entry/front/create/locale/es.yml b/modules/entry/front/create/locale/es.yml
new file mode 100644
index 0000000000..bb20b313c7
--- /dev/null
+++ b/modules/entry/front/create/locale/es.yml
@@ -0,0 +1 @@
+New entry: Nueva entrada
\ No newline at end of file
diff --git a/modules/entry/front/index.js b/modules/entry/front/index.js
index f0c845b149..9352da6933 100644
--- a/modules/entry/front/index.js
+++ b/modules/entry/front/index.js
@@ -2,6 +2,7 @@ export * from './module';
 
 import './main';
 import './index/';
+import './create';
 import './search-panel';
 import './descriptor';
 import './card';
diff --git a/modules/entry/front/index/index.html b/modules/entry/front/index/index.html
index e3d174cbfe..8a28888b09 100644
--- a/modules/entry/front/index/index.html
+++ b/modules/entry/front/index/index.html
@@ -69,4 +69,16 @@
 </vn-data-viewer>
 <vn-travel-descriptor-popover 
     vn-id="travelDescriptor">
-</vn-travel-descriptor-popover>
\ No newline at end of file
+</vn-travel-descriptor-popover>
+
+<div fixed-bottom-right>
+    <vn-vertical style="align-items: center;">
+        <a ui-sref="entry.create" vn-bind="+">
+            <vn-button class="round md vn-mb-sm"
+                icon="add"
+                vn-tooltip="New entry"
+                tooltip-position="left">
+            </vn-button>
+        </a>
+    </vn-vertical>
+</div>
\ No newline at end of file
diff --git a/modules/entry/front/routes.json b/modules/entry/front/routes.json
index 084ff7bb22..e4f3b6a3f3 100644
--- a/modules/entry/front/routes.json
+++ b/modules/entry/front/routes.json
@@ -25,6 +25,12 @@
             "state": "entry.index",
             "component": "vn-entry-index",
             "description": "Entries"
+        }, {
+            "url": "/create?supplierFk&travelFk&companyFk",
+            "state": "entry.create",
+            "component": "vn-entry-create",
+            "description": "New entry",
+            "acl": ["buyer"]
         }, {
             "url": "/:id",
             "state": "entry.card",
diff --git a/modules/item/back/models/supplier.json b/modules/item/back/models/supplier.json
index bc13e79b95..41fc9c45cc 100644
--- a/modules/item/back/models/supplier.json
+++ b/modules/item/back/models/supplier.json
@@ -33,13 +33,13 @@
         "retAccount": {
             "type": "Number"
         },
-        "commision": {
+        "commission": {
             "type": "Boolean"
         },
         "created": {
             "type": "Date"
         },
-        "poscodeFk": {
+        "postcodeFk": {
             "type": "Number"
         },
         "isActive": {
diff --git a/modules/route/front/index/index.html b/modules/route/front/index/index.html
index 7258018f10..76938d9cf9 100644
--- a/modules/route/front/index/index.html
+++ b/modules/route/front/index/index.html
@@ -79,10 +79,9 @@
             tooltip-position="left">
         </vn-button>
 
-        <a ui-sref="route.create">
+        <a ui-sref="route.create" vn-bind="+">
             <vn-button class="round md vn-mb-sm"
                 icon="add"
-                vn-bind="+"
                 vn-tooltip="New route"
                 tooltip-position="left">
             </vn-button>
diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html
index b0aff5b911..2c598ca031 100644
--- a/modules/ticket/front/index/index.html
+++ b/modules/ticket/front/index/index.html
@@ -143,10 +143,9 @@
             vn-tooltip="Payment on account..."
             tooltip-position="left">
         </vn-button>
-        <a ui-sref="ticket.create">
+        <a ui-sref="ticket.create" vn-bind="+">
             <vn-button class="round md vn-mb-sm"
                 icon="add"
-                vn-bind="+"
                 vn-tooltip="New ticket"
                 tooltip-position="left">
             </vn-button>

From c796132e77aaf9abe72e2e647921ce69c36b90d0 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Wed, 2 Sep 2020 15:20:28 +0200
Subject: [PATCH 085/109] e2e + fixtures amended + refactor

---
 db/dump/fixtures.sql                       | 34 +++++++++++-----------
 e2e/helpers/selectors.js                   | 24 +++++++--------
 e2e/paths/04-item/10_index.spec.js         |  1 -
 modules/entry/front/latest-buys/index.html |  8 ++---
 4 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 4dc5409555..22fa2076a8 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -735,23 +735,23 @@ INSERT INTO `vn`.`intrastat`(`id`, `description`, `taxClassFk`, `taxCodeFk`)
 
 INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `isOnOffer`, `expenceFk`, `isBargain`, `comment`, `relevancy`, `image`, `taxClassFk`, `subName`, `minPrice`)
     VALUES
-        (1,  2, 70,   'AMA', 1,    1, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL, 0),
-        (2,  2, 70,   'AZL', 1,    2, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL, 0),
-        (3,  1, 60,   'AMR', 1,    3, NULL,              1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL, 0),
-        (4,  1, 60,   'AMR', 1,    1, 'Increases block', 1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL, 0),
-        (5,  3, 30,   'GRE', 1,    2, NULL,              2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
-        (6,  5, 30,   'GRE', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
-        (7,  5, 90,   'AZL', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
-        (8,  2, 70,   'AMA', 1,    1, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 66540, 1, NULL, 0),
-        (9,  2, 70,   'AZL', 1,    2, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 65540, 1, NULL, 0),
-        (10, 1, 60,   'AMR', 1,    3, NULL,              1,    05080000, 0, 4751000000, 0, NULL, 0, 61692, 1, NULL, 0),
-        (11, 1, 60,   'AMR', 1,    1, NULL,              1,    05080000, 1, 4751000000, 0, NULL, 0, 66090, 2, NULL, 0),
-        (12, 3, 30,   'GRE', 1,    2, NULL,              2,    06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
-        (13, 5, 30,   'GRE', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
-        (14, 5, 90,   'AZL', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
-        (15, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
-        (16, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
-        (71, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 1, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0);
+        (1,  2, 70,   'AMA', 1,    1, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 67,     1, NULL, 0),
+        (2,  2, 70,   'AZL', 1,    2, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 66,     1, NULL, 0),
+        (3,  1, 60,   'AMR', 1,    3, NULL,              1,    05080000, 0, 4751000000, 0, NULL, 0, 65,     1, NULL, 0),
+        (4,  1, 60,   'AMR', 1,    1, 'Increases block', 1,    05080000, 1, 4751000000, 0, NULL, 0, 69,     2, NULL, 0),
+        (5,  3, 30,   'GRE', 1,    2, NULL,              2,    06021010, 1, 4751000000, 0, NULL, 0, 74,     2, NULL, 0),
+        (6,  5, 30,   'GRE', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 62,     2, NULL, 0),
+        (7,  5, 90,   'AZL', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 64,     2, NULL, 0),
+        (8,  2, 70,   'AMA', 1,    1, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 75,     1, NULL, 0),
+        (9,  2, 70,   'AZL', 1,    2, NULL,              1,    06021010, 0, 2000000000, 0, NULL, 0, 76,     1, NULL, 0),
+        (10, 1, 60,   'AMR', 1,    3, NULL,              1,    05080000, 0, 4751000000, 0, NULL, 0, 77,     1, NULL, 0),
+        (11, 1, 60,   'AMR', 1,    1, NULL,              1,    05080000, 1, 4751000000, 0, NULL, 0, 78,     2, NULL, 0),
+        (12, 3, 30,   'GRE', 1,    2, NULL,              2,    06021010, 1, 4751000000, 0, NULL, 0, 82,     2, NULL, 0),
+        (13, 5, 30,   'GRE', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 83,     2, NULL, 0),
+        (14, 5, 90,   'AZL', 1,    2, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 84,     2, NULL, 0),
+        (15, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350,  2, NULL, 0),
+        (16, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350,  2, NULL, 0),
+        (71, 4, NULL,  NULL, NULL, 1, NULL,              NULL, 06021010, 1, 4751000000, 0, NULL, 0, 88,     2, NULL, 0);
 
 INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`)
     VALUES
diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index 3a48d881e6..607ace0962 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -225,18 +225,18 @@ export default {
         firstItemImage: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(1) > img',
         firstItemImageTd: 'vn-item-index vn-table a:nth-child(1) vn-td:nth-child(1)',
         firstItemId: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(2)',
-        idCheckbox: '.vn-popover.shown vn-horizontal:nth-child(2) > vn-check',
-        stemsCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check',
-        sizeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(4) > vn-check',
-        nicheCheckbox: '.vn-popover.shown vn-horizontal:nth-child(5) > vn-check',
-        typeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(6) > vn-check',
-        categoryCheckbox: '.vn-popover.shown vn-horizontal:nth-child(7) > vn-check',
-        intrastadCheckbox: '.vn-popover.shown vn-horizontal:nth-child(8) > vn-check',
-        originCheckbox: '.vn-popover.shown vn-horizontal:nth-child(9) > vn-check',
-        buyerCheckbox: '.vn-popover.shown vn-horizontal:nth-child(10) > vn-check',
-        destinyCheckbox: '.vn-popover.shown vn-horizontal:nth-child(11) > vn-check',
-        taxClassCheckbox: '.vn-popover.shown vn-horizontal:nth-child(12) > vn-check',
-        saveFieldsButton: '.vn-popover.shown vn-horizontal:nth-child(16) > vn-button > button'
+        idCheckbox: '.vn-popover.shown vn-horizontal:nth-child(1) > vn-check',
+        stemsCheckbox: '.vn-popover.shown vn-horizontal:nth-child(2) > vn-check',
+        sizeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check',
+        nicheCheckbox: '.vn-popover.shown vn-horizontal:nth-child(4) > vn-check',
+        typeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(5) > vn-check',
+        categoryCheckbox: '.vn-popover.shown vn-horizontal:nth-child(6) > vn-check',
+        intrastadCheckbox: '.vn-popover.shown vn-horizontal:nth-child(7) > vn-check',
+        originCheckbox: '.vn-popover.shown vn-horizontal:nth-child(8) > vn-check',
+        buyerCheckbox: '.vn-popover.shown vn-horizontal:nth-child(9) > vn-check',
+        destinyCheckbox: '.vn-popover.shown vn-horizontal:nth-child(10) > vn-check',
+        taxClassCheckbox: '.vn-popover.shown vn-horizontal:nth-child(11) > vn-check',
+        saveFieldsButton: '.vn-popover.shown vn-button[label="Save"] > button'
     },
     itemCreateView: {
         temporalName: 'vn-item-create vn-textfield[ng-model="$ctrl.item.provisionalName"]',
diff --git a/e2e/paths/04-item/10_index.spec.js b/e2e/paths/04-item/10_index.spec.js
index b4c4b636e6..60e807246f 100644
--- a/e2e/paths/04-item/10_index.spec.js
+++ b/e2e/paths/04-item/10_index.spec.js
@@ -55,7 +55,6 @@ describe('Item index path', () => {
     });
 
     it('should mark all unchecked boxes to leave the index as it was', async() => {
-        await page.waitFor(3000); // otherwise the snackbar doesnt appear some times.
         await page.waitToClick(selectors.itemsIndex.fieldsToShowButton);
         await page.waitToClick(selectors.itemsIndex.idCheckbox);
         await page.waitToClick(selectors.itemsIndex.stemsCheckbox);
diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
index 4386971ad5..4aa3aeae2a 100644
--- a/modules/entry/front/latest-buys/index.html
+++ b/modules/entry/front/latest-buys/index.html
@@ -24,13 +24,13 @@
         vn-smart-table="latestBuys">
         <vn-thead>
             <vn-tr>
-                <vn-th smart-table-ignore shrink>
+                <vn-th shrink>
                     <vn-multi-check
                         model="model">
                     </vn-multi-check>
                 </vn-th>
-                <vn-th smart-table-ignore shrink></vn-th>
-                <vn-th field="id">Id</vn-th>
+                <vn-th field="Image">Picture</vn-th>
+                <vn-th smart-table-ignore field="id">Id</vn-th>
                 <vn-th field="packing">Packing</vn-th>
                 <vn-th field="grouping">Grouping</vn-th>
                 <vn-th field="description" style="text-align: center">Description</vn-th>
@@ -89,7 +89,7 @@
                         <span translate>{{::buy.grouping | dashIfEmpty}}</span>
                     </vn-chip>
                 </vn-td>
-                <vn-td expand title="{{::buy.description}}">
+                <vn-td vn-two title="{{::buy.description}}">
                     {{::buy.description | dashIfEmpty}}
                 </vn-td>
                 <vn-td number>{{::buy.size}}</vn-td>

From 5fa9489f9a00d1edfb936cbc3f562f0abeddd198 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 3 Sep 2020 08:09:37 +0200
Subject: [PATCH 086/109] Added fields as required, added info icon

---
 modules/entry/back/models/entry.json     | 12 ++++++++++++
 modules/entry/front/create/index.html    | 15 +++++++++++----
 modules/entry/front/create/index.js      |  1 +
 modules/entry/front/create/locale/es.yml |  3 ++-
 modules/entry/front/create/style.scss    | 10 ++++++++++
 5 files changed, 36 insertions(+), 5 deletions(-)
 create mode 100644 modules/entry/front/create/style.scss

diff --git a/modules/entry/back/models/entry.json b/modules/entry/back/models/entry.json
index 2739156ea5..a67641b0c5 100644
--- a/modules/entry/back/models/entry.json
+++ b/modules/entry/back/models/entry.json
@@ -62,6 +62,18 @@
         },
         "loadPriority": {
             "type": "number"
+        },
+        "supplierFk": {
+            "type": "number",
+            "required": true
+        },
+        "travelFk": {
+            "type": "number",
+            "required": true
+        },
+        "companyFk": {
+            "type": "number",
+            "required": true
         }
     },
     "relations": {
diff --git a/modules/entry/front/create/index.html b/modules/entry/front/create/index.html
index 3bc086f4e9..262e904d79 100644
--- a/modules/entry/front/create/index.html
+++ b/modules/entry/front/create/index.html
@@ -7,6 +7,10 @@
 </vn-watcher>
 <form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
     <vn-card class="vn-pa-lg">
+        <vn-icon color-marginal
+            icon="info"
+            vn-tooltip="Required fields (*)">
+        </vn-icon>
         <vn-horizontal>
             <vn-autocomplete 
                 vn-one
@@ -16,21 +20,23 @@
                 search-function="{or: [{id: $search}, {name: {like: '%'+ $search +'%'}}]}"
                 value-field="id"
                 order="nickname"
-                label="Supplier">
+                label="Supplier"
+                required="true">
                 <tpl-item>
                     {{::id}} - {{::nickname}}
                 </tpl-item>
             </vn-autocomplete>
         </vn-horizontal>
         <vn-horizontal>
-            <vn-autocomplete 
+            <vn-autocomplete
                 vn-one
                 ng-model="$ctrl.entry.travelFk"
                 url="Travels/filter"
                 search-function="$ctrl.searchFunction($search)"
                 value-field="t.id"
                 order="t.id"
-                label="Travel">
+                label="Travel"
+                required="true">
                 <tpl-item>
                     {{::agencyModeName}} - {{::warehouseInName}} ({{::shipped | date: 'dd/MM/yyyy'}}) &#x2192;
                     {{::warehouseOutName}} ({{::landed | date: 'dd/MM/yyyy'}})
@@ -43,7 +49,8 @@
                 label="Company"
                 show-field="code"
                 value-field="id"
-                ng-model="$ctrl.entry.companyFk">
+                ng-model="$ctrl.entry.companyFk"
+                required="true">
             </vn-autocomplete>
         </vn-horizontal>
     </vn-card>
diff --git a/modules/entry/front/create/index.js b/modules/entry/front/create/index.js
index b94cbe2ca9..ec022afeda 100644
--- a/modules/entry/front/create/index.js
+++ b/modules/entry/front/create/index.js
@@ -1,5 +1,6 @@
 import ngModule from '../module';
 import Section from 'salix/components/section';
+import './style.scss';
 
 export default class Controller extends Section {
     constructor($element, $) {
diff --git a/modules/entry/front/create/locale/es.yml b/modules/entry/front/create/locale/es.yml
index bb20b313c7..aa269ed151 100644
--- a/modules/entry/front/create/locale/es.yml
+++ b/modules/entry/front/create/locale/es.yml
@@ -1 +1,2 @@
-New entry: Nueva entrada
\ No newline at end of file
+New entry: Nueva entrada
+Required fields (*): Campos requeridos (*)
\ No newline at end of file
diff --git a/modules/entry/front/create/style.scss b/modules/entry/front/create/style.scss
new file mode 100644
index 0000000000..2dc52b1ff3
--- /dev/null
+++ b/modules/entry/front/create/style.scss
@@ -0,0 +1,10 @@
+vn-entry-create {
+    vn-card {
+        position: relative
+    }
+    vn-icon[icon="info"] {
+        position: absolute; 
+        top: 16px;
+        right: 16px
+    }
+}
\ No newline at end of file

From 68f011e53c842899491863bb27184ae492e4cfea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 3 Sep 2020 11:53:39 +0200
Subject: [PATCH 087/109] Added waitFor(500) ms

---
 e2e/paths/04-item/10_index.spec.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/e2e/paths/04-item/10_index.spec.js b/e2e/paths/04-item/10_index.spec.js
index 60e807246f..a6c0d49198 100644
--- a/e2e/paths/04-item/10_index.spec.js
+++ b/e2e/paths/04-item/10_index.spec.js
@@ -55,6 +55,7 @@ describe('Item index path', () => {
     });
 
     it('should mark all unchecked boxes to leave the index as it was', async() => {
+        await page.waitFor(500); // otherwise the snackbar doesnt appear some times.
         await page.waitToClick(selectors.itemsIndex.fieldsToShowButton);
         await page.waitToClick(selectors.itemsIndex.idCheckbox);
         await page.waitToClick(selectors.itemsIndex.stemsCheckbox);

From 8e05915ff46bd39efa4b4297b98e4d1fc8fdb697 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Thu, 3 Sep 2020 12:01:57 +0200
Subject: [PATCH 088/109] e2e path now clears days onwards input for search

---
 e2e/helpers/selectors.js                       | 3 ++-
 e2e/paths/09-invoice-out/02_descriptor.spec.js | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index 607ace0962..fe93e8b411 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -372,6 +372,8 @@ export default {
     ticketsIndex: {
         openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
         advancedSearchInvoiceOut: 'vn-ticket-search-panel vn-textfield[ng-model="filter.refFk"]',
+        advancedSearchDaysOnward: 'vn-ticket-search-panel vn-input-number[ng-model="filter.scopeDays"]',
+        advancedSearchButton: 'vn-ticket-search-panel button[type=submit]',
         newTicketButton: 'vn-ticket-index a[ui-sref="ticket.create"]',
         searchResult: 'vn-ticket-index vn-card > vn-table > div > vn-tbody > a.vn-tr',
         secondTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(2) > vn-td:nth-child(1) > vn-check',
@@ -384,7 +386,6 @@ export default {
         searchWeeklyResult: 'vn-ticket-weekly-index vn-table vn-tbody > vn-tr',
         searchResultDate: 'vn-ticket-summary [label=Landed] span',
         topbarSearch: 'vn-searchbar',
-        advancedSearchButton: 'vn-ticket-search-panel button[type=submit]',
         searchButton: 'vn-searchbar vn-icon[icon="search"]',
         moreMenu: 'vn-ticket-index vn-icon-button[icon=more_vert]',
         sixthWeeklyTicket: 'vn-ticket-weekly-index vn-table vn-tr:nth-child(6)',
diff --git a/e2e/paths/09-invoice-out/02_descriptor.spec.js b/e2e/paths/09-invoice-out/02_descriptor.spec.js
index b28730b4ed..cb60fd4a74 100644
--- a/e2e/paths/09-invoice-out/02_descriptor.spec.js
+++ b/e2e/paths/09-invoice-out/02_descriptor.spec.js
@@ -1,8 +1,7 @@
 import selectors from '../../helpers/selectors.js';
 import getBrowser from '../../helpers/puppeteer';
 
-// #2415 e2e fix InvoiceOut descriptor path
-xdescribe('InvoiceOut descriptor path', () => {
+describe('InvoiceOut descriptor path', () => {
     let browser;
     let page;
 
@@ -19,6 +18,7 @@ xdescribe('InvoiceOut descriptor path', () => {
     describe('as Administrative', () => {
         it('should search for tickets with an specific invoiceOut', async() => {
             await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton);
+            await page.clearInput(selectors.ticketsIndex.advancedSearchDaysOnward);
             await page.write(selectors.ticketsIndex.advancedSearchInvoiceOut, 'T2222222');
             await page.waitToClick(selectors.ticketsIndex.advancedSearchButton);
             await page.waitForState('ticket.card.summary');

From 5b4a3cd3709f8ee9920f926b347e973d95139b17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Thu, 3 Sep 2020 16:52:35 +0200
Subject: [PATCH 089/109] Travel autocomplete fix

---
 modules/entry/front/create/index.html        |  4 ++--
 modules/entry/front/create/index.js          | 10 +++++-----
 modules/travel/back/methods/travel/filter.js |  5 +++--
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/modules/entry/front/create/index.html b/modules/entry/front/create/index.html
index 262e904d79..77fd92d55b 100644
--- a/modules/entry/front/create/index.html
+++ b/modules/entry/front/create/index.html
@@ -33,8 +33,8 @@
                 ng-model="$ctrl.entry.travelFk"
                 url="Travels/filter"
                 search-function="$ctrl.searchFunction($search)"
-                value-field="t.id"
-                order="t.id"
+                value-field="id"
+                order="id"
                 label="Travel"
                 required="true">
                 <tpl-item>
diff --git a/modules/entry/front/create/index.js b/modules/entry/front/create/index.js
index ec022afeda..5c61730f97 100644
--- a/modules/entry/front/create/index.js
+++ b/modules/entry/front/create/index.js
@@ -26,11 +26,11 @@ export default class Controller extends Section {
 
     searchFunction($search) {
         return {or: [
-            {'am.name': {like: `%${$search}%`}},
-            {'win.name': {like: `%${$search}%`}},
-            {'wout.name': {like: `%${$search}%`}},
-            {'t.shipped': new Date($search)},
-            {'t.landed': new Date($search)}
+            {'agencyModeName': {like: `%${$search}%`}},
+            {'warehouseInName': {like: `%${$search}%`}},
+            {'warehouseOutName': {like: `%${$search}%`}},
+            {'shipped': new Date($search)},
+            {'landed': new Date($search)}
         ]};
     }
 }
diff --git a/modules/travel/back/methods/travel/filter.js b/modules/travel/back/methods/travel/filter.js
index 0cfafd7bac..024448bfe4 100644
--- a/modules/travel/back/methods/travel/filter.js
+++ b/modules/travel/back/methods/travel/filter.js
@@ -112,7 +112,8 @@ module.exports = Self => {
         let stmts = [];
         let stmt;
         stmt = new ParameterizedSQL(
-            `SELECT
+            `SELECT * FROM
+                (SELECT
                     t.id,
                     t.shipped,
                     t.landed,
@@ -132,7 +133,7 @@ module.exports = Self => {
                 FROM vn.travel t
                     JOIN vn.agencyMode am ON am.id = t.agencyFk
                     JOIN vn.warehouse win ON win.id = t.warehouseInFk
-                    JOIN vn.warehouse wout ON wout.id = t.warehouseOutFk`
+                    JOIN vn.warehouse wout ON wout.id = t.warehouseOutFk) AS t`
         );
 
         stmt.merge(conn.makeSuffix(filter));

From d1e8bd894fbc221836620c45915755e71cc8f6d2 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Thu, 3 Sep 2020 17:30:24 +0200
Subject: [PATCH 090/109] e2e path as far as it can go atm

---
 e2e/helpers/selectors.js             |  7 ++++++
 e2e/paths/12-entry/04_create.spec.js | 37 ++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)
 create mode 100644 e2e/paths/12-entry/04_create.spec.js

diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index fe93e8b411..c1e13d8891 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -909,5 +909,12 @@ export default {
         newValueInput: 'vn-textfield[ng-model="$ctrl.editedColumn.newValue"]',
         latestBuysSectionButton: 'a[ui-sref="entry.latestBuys"]',
         acceptEditBuysDialog: 'button[response="accept"]'
+    },
+    entryIndex: {
+        createEntryButton: 'vn-entry-index vn-button[icon="add"]',
+        newEntrySupplier: 'vn-entry-create vn-autocomplete[ng-model="$ctrl.entry.supplierFk"]',
+        newEntryTravel: 'vn-entry-create vn-autocomplete[ng-model="$ctrl.entry.travelFk"]',
+        newEntryCompany: 'vn-entry-create vn-autocomplete[ng-model="$ctrl.entry.companyFk"]',
+        saveNewEntry: 'vn-entry-create button[type="submit"]'
     }
 };
diff --git a/e2e/paths/12-entry/04_create.spec.js b/e2e/paths/12-entry/04_create.spec.js
new file mode 100644
index 0000000000..d58326ecf8
--- /dev/null
+++ b/e2e/paths/12-entry/04_create.spec.js
@@ -0,0 +1,37 @@
+import selectors from '../../helpers/selectors.js';
+import getBrowser from '../../helpers/puppeteer';
+
+// #2434 [E2E] entry.create
+// esto explota por ahora al guardar con el error:
+// Possibly unhandled rejection:
+// {"$id":0,"type":4,"message":"This transition is invalid","detail":"Could not resolve 'entry.card.basicData' from state 'entry.create'"}
+xdescribe('Entry create path', () => {
+    let browser;
+    let page;
+
+    beforeAll(async() => {
+        browser = await getBrowser();
+        page = browser.page;
+        await page.loginAndModule('buyer', 'entry');
+    });
+
+    afterAll(async() => {
+        await browser.close();
+    });
+
+    it('should click the create entry button to open the form', async() => {
+        await page.waitToClick(selectors.entryIndex.createEntryButton);
+        await page.waitForState('entry.create');
+    });
+
+    it('should fill the form to create a valid entry', async() => {
+        await page.autocompleteSearch(selectors.entryIndex.newEntrySupplier, '2');
+        await page.autocompleteSearch(selectors.entryIndex.newEntryTravel, 'Warehouse Three');
+        await page.autocompleteSearch(selectors.entryIndex.newEntryCompany, 'ORN');
+        await page.waitToClick(selectors.entryIndex.saveNewEntry);
+    });
+
+    it('should check the new state is a summary or a basicData for a created entry', async() => {
+        expect(true).toBe(false); // to flag this isn't quite finished yet.
+    });
+});

From ba9cfedec74d6214ac5bef19ebc1f5181fc3b70f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 07:59:27 +0200
Subject: [PATCH 091/109] Worker calendar holiday name

---
 modules/worker/front/calendar/index.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/worker/front/calendar/index.js b/modules/worker/front/calendar/index.js
index 0067251727..eb2ea35cc9 100644
--- a/modules/worker/front/calendar/index.js
+++ b/modules/worker/front/calendar/index.js
@@ -91,7 +91,7 @@ class Controller extends Section {
 
         if (data.holidays) {
             data.holidays.forEach(holiday => {
-                const holidayDetail = holiday.detail && holiday.detail.description;
+                const holidayDetail = holiday.detail && holiday.detail.name;
                 const holidayType = holiday.type && holiday.type.name;
                 const holidayName = holidayDetail || holidayType;
 

From f8bb4d86fbfc4fa3f65b4df99f8458ea87623429 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 08:15:43 +0200
Subject: [PATCH 092/109] State fix & supplier search fix

---
 modules/entry/front/basic-data/index.html |  0
 modules/entry/front/basic-data/index.js   | 10 ++++++++++
 modules/entry/front/create/index.html     |  2 +-
 modules/entry/front/routes.json           |  9 +++++++++
 4 files changed, 20 insertions(+), 1 deletion(-)
 create mode 100644 modules/entry/front/basic-data/index.html
 create mode 100644 modules/entry/front/basic-data/index.js

diff --git a/modules/entry/front/basic-data/index.html b/modules/entry/front/basic-data/index.html
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/modules/entry/front/basic-data/index.js b/modules/entry/front/basic-data/index.js
new file mode 100644
index 0000000000..141a365fa3
--- /dev/null
+++ b/modules/entry/front/basic-data/index.js
@@ -0,0 +1,10 @@
+import ngModule from '../module';
+import Section from 'salix/components/section';
+
+ngModule.vnComponent('vnEntryBasicData', {
+    template: require('./index.html'),
+    controller: Section,
+    bindings: {
+        entry: '<'
+    }
+});
diff --git a/modules/entry/front/create/index.html b/modules/entry/front/create/index.html
index 77fd92d55b..7b5dfc928d 100644
--- a/modules/entry/front/create/index.html
+++ b/modules/entry/front/create/index.html
@@ -17,7 +17,7 @@
                 ng-model="$ctrl.entry.supplierFk"
                 url="Suppliers"
                 show-field="nickname"
-                search-function="{or: [{id: $search}, {name: {like: '%'+ $search +'%'}}]}"
+                search-function="{or: [{id: $search}, {nickname: {like: '%'+ $search +'%'}}]}"
                 value-field="id"
                 order="nickname"
                 label="Supplier"
diff --git a/modules/entry/front/routes.json b/modules/entry/front/routes.json
index 09a29db761..a430a95fa7 100644
--- a/modules/entry/front/routes.json
+++ b/modules/entry/front/routes.json
@@ -10,6 +10,7 @@
             {"state": "entry.latestBuys", "icon": "icon-latestBuys"}
         ],
         "card": [
+            {"state": "entry.card.basicData", "icon": "settings"},
             {"state": "entry.card.buy", "icon": "icon-lines"},
             {"state": "entry.card.log", "icon": "history"}
         ]
@@ -52,6 +53,14 @@
             "params": {
                 "entry": "$ctrl.entry"
             }
+        }, {
+            "url": "/basic-data",
+            "state": "entry.card.basicData",
+            "component": "vn-entry-basic-data",
+            "description": "Basic data",
+            "params": {
+                "entry": "$ctrl.entry"
+            }
         }, {
             "url" : "/log",
             "state": "entry.card.log",

From 52cbcf1fa35bad18ac128d0afea567ec07d6ddad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 08:34:04 +0200
Subject: [PATCH 093/109] Updated description

---
 db/changes/10210-summer/00-accountingType.sql | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/db/changes/10210-summer/00-accountingType.sql b/db/changes/10210-summer/00-accountingType.sql
index 1dbe29952a..7cb21ec314 100644
--- a/db/changes/10210-summer/00-accountingType.sql
+++ b/db/changes/10210-summer/00-accountingType.sql
@@ -1,2 +1,2 @@
 ALTER TABLE `vn`.`accountingType` 
-ADD COLUMN `receiptDescription` VARCHAR(50) NULL AFTER `description`;
+ADD COLUMN `receiptDescription` VARCHAR(50) NULL COMMENT 'Descripción por defecto al crear nuevo recibo' AFTER `description`;

From 03a0a22526f74775d733698c0bc0b895df35d36e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 08:53:47 +0200
Subject: [PATCH 094/109] Updated unit test

---
 modules/worker/front/calendar/index.spec.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/worker/front/calendar/index.spec.js b/modules/worker/front/calendar/index.spec.js
index ebf52dc663..cb42fb3168 100644
--- a/modules/worker/front/calendar/index.spec.js
+++ b/modules/worker/front/calendar/index.spec.js
@@ -81,8 +81,8 @@ describe('Worker', () => {
                 $httpBackend.whenRoute('GET', 'Calendars/absences')
                     .respond({
                         holidays: [
-                            {dated: today, detail: {description: 'New year'}},
-                            {dated: tomorrow, detail: {description: 'Easter'}}
+                            {dated: today, detail: {name: 'New year'}},
+                            {dated: tomorrow, detail: {name: 'Easter'}}
                         ],
                         absences: [
                             {dated: today, absenceType: {name: 'Holiday', rgb: '#aaa'}},

From 014a537169ac3fd62156c8c9c38f8551e40ad3a3 Mon Sep 17 00:00:00 2001
From: Carlos Jimenez Ruiz <jacarlosjimenezruiz@gmail.com>
Date: Mon, 7 Sep 2020 10:30:36 +0200
Subject: [PATCH 095/109] e2e path completed

---
 e2e/paths/12-entry/04_create.spec.js | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/e2e/paths/12-entry/04_create.spec.js b/e2e/paths/12-entry/04_create.spec.js
index d58326ecf8..90dac618ae 100644
--- a/e2e/paths/12-entry/04_create.spec.js
+++ b/e2e/paths/12-entry/04_create.spec.js
@@ -1,11 +1,7 @@
 import selectors from '../../helpers/selectors.js';
 import getBrowser from '../../helpers/puppeteer';
 
-// #2434 [E2E] entry.create
-// esto explota por ahora al guardar con el error:
-// Possibly unhandled rejection:
-// {"$id":0,"type":4,"message":"This transition is invalid","detail":"Could not resolve 'entry.card.basicData' from state 'entry.create'"}
-xdescribe('Entry create path', () => {
+describe('Entry create path', () => {
     let browser;
     let page;
 
@@ -31,7 +27,7 @@ xdescribe('Entry create path', () => {
         await page.waitToClick(selectors.entryIndex.saveNewEntry);
     });
 
-    it('should check the new state is a summary or a basicData for a created entry', async() => {
-        expect(true).toBe(false); // to flag this isn't quite finished yet.
+    it('should be redirected to entry basic data', async() => {
+        await page.waitForState('entry.card.basicData');
     });
 });

From f3a7fc514a9595c9cbb42cd13e0944d7df7d5db5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 10:54:39 +0200
Subject: [PATCH 096/109] Changes

---
 db/changes/10220-a/ticket_close.sql | 119 ++++++++++++++++++++++++++++
 print/methods/closure.js            |  15 +++-
 2 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 db/changes/10220-a/ticket_close.sql

diff --git a/db/changes/10220-a/ticket_close.sql b/db/changes/10220-a/ticket_close.sql
new file mode 100644
index 0000000000..dd9786dcdb
--- /dev/null
+++ b/db/changes/10220-a/ticket_close.sql
@@ -0,0 +1,119 @@
+USE `vn`;
+DROP procedure IF EXISTS `ticket_close`;
+
+DELIMITER $$
+USE `vn`$$
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_close`(vTicketFk INT)
+BEGIN
+/**
+ * Realiza el cierre de todos los 
+ * tickets de la tabla ticketClosure.
+ */
+	DECLARE vDone BOOL;
+	DECLARE vClientFk INT;
+    DECLARE vCurTicketFk INT;
+	DECLARE vIsTaxDataChecked BOOL;
+	DECLARE vCompanyFk INT;
+	DECLARE vShipped DATE;
+	DECLARE vPriority INT DEFAULT 1;
+	DECLARE vReportDeliveryNote INT DEFAULT 1;
+	DECLARE vNewInvoiceId INT;
+	DECLARE vHasDailyInvoice BOOL;
+	DECLARE vWithPackage BOOL;
+    DECLARE vHasToInvoice BOOL;
+
+	DECLARE cur CURSOR FOR
+		SELECT ticketFk FROM tmp.ticketClosure;
+		
+	DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
+	DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN
+		RESIGNAL;
+	END;
+
+	DROP TEMPORARY TABLE IF EXISTS  tmp.ticketClosure;
+	CREATE TEMPORARY TABLE tmp.ticketClosure
+			SELECT vTicketFk AS ticketFk;
+            
+	INSERT INTO tmp.ticketClosure 
+			SELECT id FROM stowaway s 
+				WHERE s.shipFk = vTicketFk;
+	OPEN cur;
+
+	proc: LOOP
+		SET vDone = FALSE;
+		
+		FETCH cur INTO vCurTicketFk;
+
+		IF vDone THEN
+			LEAVE proc;
+		END IF;
+
+		-- ticketClosure start
+		SELECT
+				c.id,
+				c.isTaxDataChecked,
+				t.companyFk,
+				t.shipped,
+				co.hasDailyInvoice,
+				w.isManaged,
+                c.hasToInvoice
+			INTO vClientFk,
+				vIsTaxDataChecked,
+				vCompanyFk, 
+				vShipped,
+				vHasDailyInvoice,
+				vWithPackage,
+                vHasToInvoice
+			FROM ticket t 
+				JOIN `client` c ON c.id = t.clientFk
+				JOIN province p ON p.id = c.provinceFk
+				JOIN country co ON co.id = p.countryFk
+				JOIN warehouse w ON w.id = t.warehouseFk
+			WHERE t.id = vCurTicketFk;
+
+		INSERT INTO ticketPackaging (ticketFk, packagingFk, quantity)
+			(SELECT vCurTicketFk, p.id, COUNT(*)
+				FROM expedition e 
+					JOIN packaging p ON p.itemFk = e.itemFk
+				WHERE e.ticketFk = vCurTicketFk AND p.isPackageReturnable
+					AND vWithPackage
+				GROUP BY p.itemFk);
+
+		-- No retornables o no catalogados
+		INSERT INTO sale (itemFk, ticketFk, concept, quantity, price, isPriceFixed) 
+			(SELECT e.itemFk, vCurTicketFk, i.name, COUNT(*) AS amount, getSpecialPrice(e.itemFk, vClientFk), 1 
+				FROM expedition e 
+					JOIN item i ON i.id = e.itemFk 
+					LEFT JOIN packaging p ON p.itemFk = i.id
+				WHERE e.ticketFk = vCurTicketFk AND IFNULL(p.isPackageReturnable, 0) = 0
+					AND getSpecialPrice(e.itemFk, vClientFk) > 0
+				GROUP BY e.itemFk);
+                
+		CALL vn.zonePromo_Make();
+			
+		IF(vHasDailyInvoice) AND vHasToInvoice THEN
+
+			-- Facturacion rapida
+			CALL ticketTrackingAdd(vCurTicketFk, 'DELIVERED', NULL);
+			-- Facturar si está contabilizado
+			IF vIsTaxDataChecked THEN
+				CALL invoiceOut_newFromClient(
+					vClientFk, 
+					(SELECT invoiceSerial(vClientFk, vCompanyFk, 'M')), 
+					vShipped, 
+					vCompanyFk, 
+					NULL,
+					vNewInvoiceId);
+			END IF;
+		ELSE
+			CALL ticketTrackingAdd(vCurTicketFk, (SELECT vn.getAlert3State(vCurTicketFk)), NULL);
+		END IF;
+	END LOOP;
+
+	CLOSE cur;
+    
+	DROP TEMPORARY TABLE IF EXISTS  tmp.ticketClosure;
+END$$
+
+DELIMITER ;
+
diff --git a/print/methods/closure.js b/print/methods/closure.js
index 15023263b9..a1450f4463 100644
--- a/print/methods/closure.js
+++ b/print/methods/closure.js
@@ -26,6 +26,19 @@ module.exports = app => {
                 GROUP BY e.ticketFk)`);
 
             await closeAll(req.args);
+
+            await db.rawSql(`
+            UPDATE ticket t
+                JOIN ticketState ts ON t.id = ts.ticketFk
+                JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                JOIN agencyMode am ON am.id = t.agencyModeFk 
+                JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
+                JOIN zone z ON z.id = t.zoneFk
+            SET t.routeFk = NULL
+                WHERE shipped BETWEEN CURDATE() AND util.dayEnd(CURDATE())
+                    AND al.code NOT IN('DELIVERED','PACKED')
+                    AND t.routeFk
+                    AND z.name LIKE '%MADRID%'`);
         } catch (error) {
             next(error);
         }
@@ -158,7 +171,7 @@ module.exports = app => {
 
         for (const ticket of tickets) {
             try {
-                await db.rawSql(`CALL vn.ticket_closeByTicket(:ticketId)`, {
+                await db.rawSql(`CALL vn.ticket_close(:ticketId)`, {
                     ticketId: ticket.id
                 });
 

From 7b42497f88ed5da1cf392895718b0e9404356cda Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 11:44:44 +0200
Subject: [PATCH 097/109] Removed procedures

---
 .../ticket_closeByAgency.sql                  | 32 --------------
 .../ticket_closeByAllWarehouses.sql           | 42 -------------------
 .../ticket_closeByRoute.sql                   | 29 -------------
 .../ticket_closeByTicket.sql                  | 28 -------------
 .../ticket_closeByWarehouse.sql               | 29 -------------
 5 files changed, 160 deletions(-)
 delete mode 100644 db/changes/10200-DeEscalation/ticket_closeByAgency.sql
 delete mode 100644 db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
 delete mode 100644 db/changes/10200-DeEscalation/ticket_closeByRoute.sql
 delete mode 100644 db/changes/10200-DeEscalation/ticket_closeByTicket.sql
 delete mode 100644 db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql

diff --git a/db/changes/10200-DeEscalation/ticket_closeByAgency.sql b/db/changes/10200-DeEscalation/ticket_closeByAgency.sql
deleted file mode 100644
index 155305afe2..0000000000
--- a/db/changes/10200-DeEscalation/ticket_closeByAgency.sql
+++ /dev/null
@@ -1,32 +0,0 @@
-CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByAgencyList`(vWarehouseFk INT, vDateTo DATE)
-BEGIN
-/**
- * Inserta los tickets de todos los almacenes en la tabla temporal
- * para ser cerrados.
- *
- * @param vWarehouseFk Id del almacén
- * @param vDate Fecha del cierre
- */
-
-	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
-
-	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
-		SELECT 
-			t.id AS ticketFk
-		FROM expedition e
-			JOIN ticket t ON t.id = e.ticketFk
-			JOIN tmp.ticketClosureAgencyList al ON al.agencyModeFk = t.agencyModeFk
-			JOIN ticketState ts ON ts.ticketFk = t.id
-		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-		WHERE al.code = 'PACKED'
-			AND t.warehouseFk = vWarehouseFk
-			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
-			AND t.refFk IS NULL
-		GROUP BY e.ticketFk);
-		
-        
-	CALL ticket_close();
-    
-	DROP TEMPORARY TABLE tmp.ticketClosureAgencyList;
-    DROP TEMPORARY TABLE tmp.ticketClosure;
-END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql b/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
deleted file mode 100644
index 4a3ae76c82..0000000000
--- a/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
+++ /dev/null
@@ -1,42 +0,0 @@
-CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByAllWarehouses`(vDateTo DATE)
-BEGIN
-/**
- * Inserta los tickets de todos los almacenes en la tabla temporal
- * para ser cerrados.
- *
- * @param vDate Fecha del cierre
- */
-	DECLARE vDateToEndDay DATETIME DEFAULT util.dayEnd(vDateTo);
-    
-	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
-
-	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
-		SELECT 
-			t.id AS ticketFk
-		FROM expedition e
-			JOIN ticket t ON t.id = e.ticketFk
-			JOIN warehouse w ON w.id = t.warehouseFk AND hasComission
-			JOIN ticketState ts ON ts.ticketFk = t.id
-		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-		WHERE al.code = 'PACKED'
-			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
-			AND t.refFk IS NULL
-		GROUP BY e.ticketFk);
-        
-	CALL ticket_close();
-    
-    -- cau 15033
-    UPDATE ticket t
-				JOIN ticketState ts ON t.id = ts.ticketFk
-                JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-                JOIN agencyMode am ON am.id = t.agencyModeFk 
-                JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
-                JOIN zone z ON z.id = t.zoneFk
-		SET t.routeFk = NULL
-            WHERE shipped BETWEEN vDateTo AND vDateToEndDay
-				AND al.code NOT IN('DELIVERED','PACKED')
-                AND t.routeFk
-				AND z.`name` LIKE '%MADRID%';
-            
-    DROP TEMPORARY TABLE tmp.ticketClosure;
-END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByRoute.sql b/db/changes/10200-DeEscalation/ticket_closeByRoute.sql
deleted file mode 100644
index 3c1500bd6b..0000000000
--- a/db/changes/10200-DeEscalation/ticket_closeByRoute.sql
+++ /dev/null
@@ -1,29 +0,0 @@
-CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByRoute`( vRouteFk INT)
-BEGIN
-/**
- * Inserta los tickets de la ruta en la tabla temporal
- * para ser cerrados.
- *
- * @param vWarehouseFk Almacén a cerrar
- * @param vRouteFk Ruta a cerrar
- * @param vDate Fecha del cierre
- */
-
-	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
-
-	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
-		SELECT 
-			t.id AS ticketFk
-		FROM expedition e
-			JOIN ticket t ON t.id = e.ticketFk
-			JOIN ticketState ts ON ts.ticketFk = t.id
-		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-		WHERE al.code = 'PACKED'
-			AND t.routeFk = vRouteFk
-			AND t.refFk IS NULL
-		GROUP BY e.ticketFk);
-        
-	CALL ticket_close();
-    
-    DROP TEMPORARY TABLE tmp.ticketClosure;
-END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByTicket.sql b/db/changes/10200-DeEscalation/ticket_closeByTicket.sql
deleted file mode 100644
index 1ffb5a2653..0000000000
--- a/db/changes/10200-DeEscalation/ticket_closeByTicket.sql
+++ /dev/null
@@ -1,28 +0,0 @@
-CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByTicket`(vTicketFk INT)
-BEGIN
-
-/**
- * Inserta el ticket en la tabla temporal
- * para ser cerrado.
- *
- * @param vTicketFk Id del ticket
- */
-
-	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
-
-	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
-		SELECT 
-			t.id AS ticketFk
-		FROM expedition e
-			JOIN ticket t ON t.id = e.ticketFk
-			JOIN ticketState ts ON ts.ticketFk = t.id
-            JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-		WHERE al.code = 'PACKED'
-            AND t.id = vTicketFk
-			AND t.refFk IS NULL
-		GROUP BY e.ticketFk);
-        
-	CALL ticket_close();
-    
-    DROP TEMPORARY TABLE tmp.ticketClosure;
-END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql b/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql
deleted file mode 100644
index e7996edb07..0000000000
--- a/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql
+++ /dev/null
@@ -1,29 +0,0 @@
-CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByWarehouse`(vWarehouseFk INT, vDateTo DATE)
-BEGIN
-/**
- * Inserta los tickets del almacen en la tabla temporal
- * para ser cerrados.
- *
- * @param vWarehouseFk Almacén a cerrar
- * @param vDate Fecha del cierre
- */
-
-	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
-
-	CREATE TEMPORARY TABLE ticketClosure ENGINE = MEMORY(
-		SELECT 
-			t.id AS ticketFk
-		FROM expedition e
-			JOIN ticket t ON t.id = e.ticketFk
-			JOIN ticketState ts ON ts.ticketFk = t.id
-		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-		WHERE al.code = 'PACKED' 
-			AND t.warehouseFk = vWarehouseFk
-			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
-			AND t.refFk IS NULL
-		GROUP BY e.ticketFk);
-        
-	CALL ticket_close();
-    
-    DROP TEMPORARY TABLE tmp.ticketClosure;
-END
\ No newline at end of file

From 13b3353e9a6feb748321f20d38fac63147dc9f02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 11:45:29 +0200
Subject: [PATCH 098/109] Changed sql folder

---
 db/changes/{10220-a => 10210-summer}/ticket_close.sql | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename db/changes/{10220-a => 10210-summer}/ticket_close.sql (100%)

diff --git a/db/changes/10220-a/ticket_close.sql b/db/changes/10210-summer/ticket_close.sql
similarity index 100%
rename from db/changes/10220-a/ticket_close.sql
rename to db/changes/10210-summer/ticket_close.sql

From 173aac0ba6ae92a020c830700d1064f5cd825c69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 11:45:54 +0200
Subject: [PATCH 099/109] Renamed sql file

---
 db/changes/10210-summer/{ticket_close.sql => 00-ticket_close.sql} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename db/changes/10210-summer/{ticket_close.sql => 00-ticket_close.sql} (100%)

diff --git a/db/changes/10210-summer/ticket_close.sql b/db/changes/10210-summer/00-ticket_close.sql
similarity index 100%
rename from db/changes/10210-summer/ticket_close.sql
rename to db/changes/10210-summer/00-ticket_close.sql

From c10e24b7cdb9b0cc0184d50655f40b02ee933278 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 11:50:23 +0200
Subject: [PATCH 100/109] Updated param description

---
 db/changes/10210-summer/00-ticket_close.sql | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/db/changes/10210-summer/00-ticket_close.sql b/db/changes/10210-summer/00-ticket_close.sql
index dd9786dcdb..e01fa8f7e8 100644
--- a/db/changes/10210-summer/00-ticket_close.sql
+++ b/db/changes/10210-summer/00-ticket_close.sql
@@ -8,6 +8,8 @@ BEGIN
 /**
  * Realiza el cierre de todos los 
  * tickets de la tabla ticketClosure.
+ *
+ * @param vTicketFk Id del ticket
  */
 	DECLARE vDone BOOL;
 	DECLARE vClientFk INT;

From bb092b1de97cce03439f0c897b91c020d81890e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 12:16:20 +0200
Subject: [PATCH 101/109] Removed unused vars

---
 db/changes/10210-summer/00-ticket_close.sql | 2 --
 1 file changed, 2 deletions(-)

diff --git a/db/changes/10210-summer/00-ticket_close.sql b/db/changes/10210-summer/00-ticket_close.sql
index e01fa8f7e8..96f9c55287 100644
--- a/db/changes/10210-summer/00-ticket_close.sql
+++ b/db/changes/10210-summer/00-ticket_close.sql
@@ -17,8 +17,6 @@ BEGIN
 	DECLARE vIsTaxDataChecked BOOL;
 	DECLARE vCompanyFk INT;
 	DECLARE vShipped DATE;
-	DECLARE vPriority INT DEFAULT 1;
-	DECLARE vReportDeliveryNote INT DEFAULT 1;
 	DECLARE vNewInvoiceId INT;
 	DECLARE vHasDailyInvoice BOOL;
 	DECLARE vWithPackage BOOL;

From fa634d2dada4fe149978371df03d2c6ff78a3814 Mon Sep 17 00:00:00 2001
From: Joan Sanchez <joan@verdnatura.es>
Date: Tue, 16 Jun 2020 08:17:01 +0200
Subject: [PATCH 102/109] 2285 - Added closure paths

---
 .../ticket_closeByAgency.sql                  |  32 ++++
 .../ticket_closeByAllWarehouses.sql           |  42 +++++
 .../ticket_closeByRoute.sql                   |  29 ++++
 .../ticket_closeByTicket.sql                  |  28 +++
 .../ticket_closeByWarehouse.sql               |  29 ++++
 print/methods/closure.js                      | 163 ++++++++++++++++--
 6 files changed, 304 insertions(+), 19 deletions(-)
 create mode 100644 db/changes/10200-DeEscalation/ticket_closeByAgency.sql
 create mode 100644 db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
 create mode 100644 db/changes/10200-DeEscalation/ticket_closeByRoute.sql
 create mode 100644 db/changes/10200-DeEscalation/ticket_closeByTicket.sql
 create mode 100644 db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql

diff --git a/db/changes/10200-DeEscalation/ticket_closeByAgency.sql b/db/changes/10200-DeEscalation/ticket_closeByAgency.sql
new file mode 100644
index 0000000000..155305afe2
--- /dev/null
+++ b/db/changes/10200-DeEscalation/ticket_closeByAgency.sql
@@ -0,0 +1,32 @@
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByAgencyList`(vWarehouseFk INT, vDateTo DATE)
+BEGIN
+/**
+ * Inserta los tickets de todos los almacenes en la tabla temporal
+ * para ser cerrados.
+ *
+ * @param vWarehouseFk Id del almacén
+ * @param vDate Fecha del cierre
+ */
+
+	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
+
+	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
+		SELECT 
+			t.id AS ticketFk
+		FROM expedition e
+			JOIN ticket t ON t.id = e.ticketFk
+			JOIN tmp.ticketClosureAgencyList al ON al.agencyModeFk = t.agencyModeFk
+			JOIN ticketState ts ON ts.ticketFk = t.id
+		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+		WHERE al.code = 'PACKED'
+			AND t.warehouseFk = vWarehouseFk
+			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
+			AND t.refFk IS NULL
+		GROUP BY e.ticketFk);
+		
+        
+	CALL ticket_close();
+    
+	DROP TEMPORARY TABLE tmp.ticketClosureAgencyList;
+    DROP TEMPORARY TABLE tmp.ticketClosure;
+END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql b/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
new file mode 100644
index 0000000000..4a3ae76c82
--- /dev/null
+++ b/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
@@ -0,0 +1,42 @@
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByAllWarehouses`(vDateTo DATE)
+BEGIN
+/**
+ * Inserta los tickets de todos los almacenes en la tabla temporal
+ * para ser cerrados.
+ *
+ * @param vDate Fecha del cierre
+ */
+	DECLARE vDateToEndDay DATETIME DEFAULT util.dayEnd(vDateTo);
+    
+	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
+
+	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
+		SELECT 
+			t.id AS ticketFk
+		FROM expedition e
+			JOIN ticket t ON t.id = e.ticketFk
+			JOIN warehouse w ON w.id = t.warehouseFk AND hasComission
+			JOIN ticketState ts ON ts.ticketFk = t.id
+		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+		WHERE al.code = 'PACKED'
+			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
+			AND t.refFk IS NULL
+		GROUP BY e.ticketFk);
+        
+	CALL ticket_close();
+    
+    -- cau 15033
+    UPDATE ticket t
+				JOIN ticketState ts ON t.id = ts.ticketFk
+                JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                JOIN agencyMode am ON am.id = t.agencyModeFk 
+                JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
+                JOIN zone z ON z.id = t.zoneFk
+		SET t.routeFk = NULL
+            WHERE shipped BETWEEN vDateTo AND vDateToEndDay
+				AND al.code NOT IN('DELIVERED','PACKED')
+                AND t.routeFk
+				AND z.`name` LIKE '%MADRID%';
+            
+    DROP TEMPORARY TABLE tmp.ticketClosure;
+END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByRoute.sql b/db/changes/10200-DeEscalation/ticket_closeByRoute.sql
new file mode 100644
index 0000000000..3c1500bd6b
--- /dev/null
+++ b/db/changes/10200-DeEscalation/ticket_closeByRoute.sql
@@ -0,0 +1,29 @@
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByRoute`( vRouteFk INT)
+BEGIN
+/**
+ * Inserta los tickets de la ruta en la tabla temporal
+ * para ser cerrados.
+ *
+ * @param vWarehouseFk Almacén a cerrar
+ * @param vRouteFk Ruta a cerrar
+ * @param vDate Fecha del cierre
+ */
+
+	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
+
+	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
+		SELECT 
+			t.id AS ticketFk
+		FROM expedition e
+			JOIN ticket t ON t.id = e.ticketFk
+			JOIN ticketState ts ON ts.ticketFk = t.id
+		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+		WHERE al.code = 'PACKED'
+			AND t.routeFk = vRouteFk
+			AND t.refFk IS NULL
+		GROUP BY e.ticketFk);
+        
+	CALL ticket_close();
+    
+    DROP TEMPORARY TABLE tmp.ticketClosure;
+END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByTicket.sql b/db/changes/10200-DeEscalation/ticket_closeByTicket.sql
new file mode 100644
index 0000000000..1ffb5a2653
--- /dev/null
+++ b/db/changes/10200-DeEscalation/ticket_closeByTicket.sql
@@ -0,0 +1,28 @@
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByTicket`(vTicketFk INT)
+BEGIN
+
+/**
+ * Inserta el ticket en la tabla temporal
+ * para ser cerrado.
+ *
+ * @param vTicketFk Id del ticket
+ */
+
+	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
+
+	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
+		SELECT 
+			t.id AS ticketFk
+		FROM expedition e
+			JOIN ticket t ON t.id = e.ticketFk
+			JOIN ticketState ts ON ts.ticketFk = t.id
+            JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+		WHERE al.code = 'PACKED'
+            AND t.id = vTicketFk
+			AND t.refFk IS NULL
+		GROUP BY e.ticketFk);
+        
+	CALL ticket_close();
+    
+    DROP TEMPORARY TABLE tmp.ticketClosure;
+END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql b/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql
new file mode 100644
index 0000000000..e7996edb07
--- /dev/null
+++ b/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql
@@ -0,0 +1,29 @@
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByWarehouse`(vWarehouseFk INT, vDateTo DATE)
+BEGIN
+/**
+ * Inserta los tickets del almacen en la tabla temporal
+ * para ser cerrados.
+ *
+ * @param vWarehouseFk Almacén a cerrar
+ * @param vDate Fecha del cierre
+ */
+
+	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
+
+	CREATE TEMPORARY TABLE ticketClosure ENGINE = MEMORY(
+		SELECT 
+			t.id AS ticketFk
+		FROM expedition e
+			JOIN ticket t ON t.id = e.ticketFk
+			JOIN ticketState ts ON ts.ticketFk = t.id
+		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+		WHERE al.code = 'PACKED' 
+			AND t.warehouseFk = vWarehouseFk
+			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
+			AND t.refFk IS NULL
+		GROUP BY e.ticketFk);
+        
+	CALL ticket_close();
+    
+    DROP TEMPORARY TABLE tmp.ticketClosure;
+END
\ No newline at end of file
diff --git a/print/methods/closure.js b/print/methods/closure.js
index 3bcca9d4e7..15023263b9 100644
--- a/print/methods/closure.js
+++ b/print/methods/closure.js
@@ -4,34 +4,157 @@ const smtp = require('../core/smtp');
 const config = require('../core/config');
 
 module.exports = app => {
-    app.get('/api/closure/by-ticket', async function(req, res) {
+    app.get('/api/closure/all', async function(req, res, next) {
+        try {
+            res.status(200).json({
+                message: 'Task executed successfully'
+            });
+
+            await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`);
+            await db.rawSql(`
+            CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY (
+                SELECT 
+                    t.id AS ticketFk
+                FROM expedition e
+                    JOIN ticket t ON t.id = e.ticketFk
+                    JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission
+                    JOIN ticketState ts ON ts.ticketFk = t.id
+                    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                WHERE al.code = 'PACKED'
+                    AND DATE(t.shipped) BETWEEN DATE_ADD(CURDATE(), INTERVAL -2 DAY) AND CURDATE()
+                    AND t.refFk IS NULL
+                GROUP BY e.ticketFk)`);
+
+            await closeAll(req.args);
+        } catch (error) {
+            next(error);
+        }
     });
 
-    app.get('/api/closure/all', async function(req, res) {
-        res.status(200).json({
-            message: 'Task executed successfully'
-        });
+    app.get('/api/closure/by-ticket', async function(req, res, next) {
+        try {
+            const reqArgs = req.args;
+            if (!reqArgs.ticketId)
+                throw new Error('The argument ticketId is required');
 
+            res.status(200).json({
+                message: 'Task executed successfully'
+            });
+
+            await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`);
+            await db.rawSql(`
+            CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY (
+                SELECT 
+                    t.id AS ticketFk
+                FROM expedition e
+                    JOIN ticket t ON t.id = e.ticketFk
+                    JOIN ticketState ts ON ts.ticketFk = t.id
+                    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                WHERE al.code = 'PACKED'
+                    AND t.id = :ticketId
+                    AND t.refFk IS NULL
+                GROUP BY e.ticketFk)`, {
+                ticketId: reqArgs.ticketId
+            });
+
+            await closeAll(reqArgs);
+        } catch (error) {
+            next(error);
+        }
+    });
+
+    app.get('/api/closure/by-agency', async function(req, res) {
+        try {
+            const reqArgs = req.args;
+            if (!reqArgs.agencyModeId)
+                throw new Error('The argument agencyModeId is required');
+
+            if (!reqArgs.warehouseId)
+                throw new Error('The argument warehouseId is required');
+
+            if (!reqArgs.to)
+                throw new Error('The argument to is required');
+
+            res.status(200).json({
+                message: 'Task executed successfully'
+            });
+
+            await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`);
+            await db.rawSql(`
+            CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY (
+                SELECT 
+                    t.id AS ticketFk
+                FROM expedition e
+                    JOIN ticket t ON t.id = e.ticketFk
+                    JOIN ticketState ts ON ts.ticketFk = t.id
+                    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                WHERE al.code = 'PACKED'
+                    AND t.agencyModeFk = :agencyModeId
+                    AND t.warehouseFk = :warehouseId
+                    AND DATE(t.shipped) BETWEEN DATE_ADD(:to, INTERVAL -2 DAY) AND :to
+                    AND t.refFk IS NULL
+                GROUP BY e.ticketFk)`, {
+                agencyModeId: reqArgs.agencyModeId,
+                warehouseId: reqArgs.warehouseId,
+                to: reqArgs.to
+            });
+
+            await closeAll(reqArgs);
+        } catch (error) {
+            next(error);
+        }
+    });
+
+    app.get('/api/closure/by-route', async function(req, res) {
+        try {
+            const reqArgs = req.args;
+            if (!reqArgs.routeId)
+                throw new Error('The argument routeId is required');
+
+            res.status(200).json({
+                message: 'Task executed successfully'
+            });
+
+            await db.rawSql(`DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close`);
+            await db.rawSql(`
+            CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY (
+                SELECT 
+                    t.id AS ticketFk
+                FROM expedition e
+                    JOIN ticket t ON t.id = e.ticketFk
+                    JOIN ticketState ts ON ts.ticketFk = t.id
+                    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                WHERE al.code = 'PACKED'
+                    AND t.routeFk = :routeId
+                    AND t.refFk IS NULL
+                GROUP BY e.ticketFk)`, {
+                routeId: reqArgs.routeId
+            });
+
+            await closeAll(reqArgs);
+        } catch (error) {
+            next(error);
+        }
+    });
+
+    async function closeAll(reqArgs) {
         const failedtickets = [];
         const tickets = await db.rawSql(`
             SELECT 
                 t.id,
                 t.clientFk,
                 c.email recipient,
-                c.isToBeMailed,
                 c.salesPersonFk,
+                c.isToBeMailed,
+                c.hasToInvoice,
+                co.hasDailyInvoice,
                 eu.email salesPersonEmail
-            FROM expedition e
-                JOIN ticket t ON t.id = e.ticketFk
+            FROM tmp.ticket_close tt
+                JOIN ticket t ON t.id = tt.ticketFk
                 JOIN client c ON c.id = t.clientFk
-                JOIN warehouse wh ON wh.id = t.warehouseFk AND wh.hasComission
-                JOIN ticketState ts ON ts.ticketFk = t.id
-                JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-                LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
-            WHERE al.code = 'PACKED'
-                AND DATE(t.shipped) BETWEEN DATE_ADD(CURDATE(), INTERVAL -2 DAY) AND CURDATE()
-                AND t.refFk IS NULL
-            GROUP BY e.ticketFk`);
+                JOIN province p ON p.id = c.provinceFk
+                JOIN country co ON co.id = p.countryFk
+                LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk`);
 
         for (const ticket of tickets) {
             try {
@@ -39,7 +162,8 @@ module.exports = app => {
                     ticketId: ticket.id
                 });
 
-                if (!ticket.salesPersonFk || !ticket.isToBeMailed) continue;
+                const hasToInvoice = ticket.hasToInvoice && ticket.hasDailyInvoice;
+                if (!ticket.salesPersonFk || !ticket.isToBeMailed || hasToInvoice) continue;
 
                 if (!ticket.recipient) {
                     const body = `No se ha podido enviar el albarán <strong>${ticket.id}</strong> 
@@ -54,7 +178,6 @@ module.exports = app => {
                     continue;
                 }
 
-                const reqArgs = req.args;
                 const args = Object.assign({
                     ticketId: ticket.id,
                     recipientId: ticket.clientFk,
@@ -88,5 +211,7 @@ module.exports = app => {
                 html: body
             });
         }
-    });
+
+        await db.rawSql(`DROP TEMPORARY TABLE tmp.ticket_close`);
+    }
 };

From c3e8c0cc58c62d0dc0d755a872d68d43fc591611 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 10:54:39 +0200
Subject: [PATCH 103/109] Changes

---
 db/changes/10220-a/ticket_close.sql | 119 ++++++++++++++++++++++++++++
 print/methods/closure.js            |  15 +++-
 2 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 db/changes/10220-a/ticket_close.sql

diff --git a/db/changes/10220-a/ticket_close.sql b/db/changes/10220-a/ticket_close.sql
new file mode 100644
index 0000000000..dd9786dcdb
--- /dev/null
+++ b/db/changes/10220-a/ticket_close.sql
@@ -0,0 +1,119 @@
+USE `vn`;
+DROP procedure IF EXISTS `ticket_close`;
+
+DELIMITER $$
+USE `vn`$$
+CREATE DEFINER=`root`@`%` PROCEDURE `ticket_close`(vTicketFk INT)
+BEGIN
+/**
+ * Realiza el cierre de todos los 
+ * tickets de la tabla ticketClosure.
+ */
+	DECLARE vDone BOOL;
+	DECLARE vClientFk INT;
+    DECLARE vCurTicketFk INT;
+	DECLARE vIsTaxDataChecked BOOL;
+	DECLARE vCompanyFk INT;
+	DECLARE vShipped DATE;
+	DECLARE vPriority INT DEFAULT 1;
+	DECLARE vReportDeliveryNote INT DEFAULT 1;
+	DECLARE vNewInvoiceId INT;
+	DECLARE vHasDailyInvoice BOOL;
+	DECLARE vWithPackage BOOL;
+    DECLARE vHasToInvoice BOOL;
+
+	DECLARE cur CURSOR FOR
+		SELECT ticketFk FROM tmp.ticketClosure;
+		
+	DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
+	DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN
+		RESIGNAL;
+	END;
+
+	DROP TEMPORARY TABLE IF EXISTS  tmp.ticketClosure;
+	CREATE TEMPORARY TABLE tmp.ticketClosure
+			SELECT vTicketFk AS ticketFk;
+            
+	INSERT INTO tmp.ticketClosure 
+			SELECT id FROM stowaway s 
+				WHERE s.shipFk = vTicketFk;
+	OPEN cur;
+
+	proc: LOOP
+		SET vDone = FALSE;
+		
+		FETCH cur INTO vCurTicketFk;
+
+		IF vDone THEN
+			LEAVE proc;
+		END IF;
+
+		-- ticketClosure start
+		SELECT
+				c.id,
+				c.isTaxDataChecked,
+				t.companyFk,
+				t.shipped,
+				co.hasDailyInvoice,
+				w.isManaged,
+                c.hasToInvoice
+			INTO vClientFk,
+				vIsTaxDataChecked,
+				vCompanyFk, 
+				vShipped,
+				vHasDailyInvoice,
+				vWithPackage,
+                vHasToInvoice
+			FROM ticket t 
+				JOIN `client` c ON c.id = t.clientFk
+				JOIN province p ON p.id = c.provinceFk
+				JOIN country co ON co.id = p.countryFk
+				JOIN warehouse w ON w.id = t.warehouseFk
+			WHERE t.id = vCurTicketFk;
+
+		INSERT INTO ticketPackaging (ticketFk, packagingFk, quantity)
+			(SELECT vCurTicketFk, p.id, COUNT(*)
+				FROM expedition e 
+					JOIN packaging p ON p.itemFk = e.itemFk
+				WHERE e.ticketFk = vCurTicketFk AND p.isPackageReturnable
+					AND vWithPackage
+				GROUP BY p.itemFk);
+
+		-- No retornables o no catalogados
+		INSERT INTO sale (itemFk, ticketFk, concept, quantity, price, isPriceFixed) 
+			(SELECT e.itemFk, vCurTicketFk, i.name, COUNT(*) AS amount, getSpecialPrice(e.itemFk, vClientFk), 1 
+				FROM expedition e 
+					JOIN item i ON i.id = e.itemFk 
+					LEFT JOIN packaging p ON p.itemFk = i.id
+				WHERE e.ticketFk = vCurTicketFk AND IFNULL(p.isPackageReturnable, 0) = 0
+					AND getSpecialPrice(e.itemFk, vClientFk) > 0
+				GROUP BY e.itemFk);
+                
+		CALL vn.zonePromo_Make();
+			
+		IF(vHasDailyInvoice) AND vHasToInvoice THEN
+
+			-- Facturacion rapida
+			CALL ticketTrackingAdd(vCurTicketFk, 'DELIVERED', NULL);
+			-- Facturar si está contabilizado
+			IF vIsTaxDataChecked THEN
+				CALL invoiceOut_newFromClient(
+					vClientFk, 
+					(SELECT invoiceSerial(vClientFk, vCompanyFk, 'M')), 
+					vShipped, 
+					vCompanyFk, 
+					NULL,
+					vNewInvoiceId);
+			END IF;
+		ELSE
+			CALL ticketTrackingAdd(vCurTicketFk, (SELECT vn.getAlert3State(vCurTicketFk)), NULL);
+		END IF;
+	END LOOP;
+
+	CLOSE cur;
+    
+	DROP TEMPORARY TABLE IF EXISTS  tmp.ticketClosure;
+END$$
+
+DELIMITER ;
+
diff --git a/print/methods/closure.js b/print/methods/closure.js
index 15023263b9..a1450f4463 100644
--- a/print/methods/closure.js
+++ b/print/methods/closure.js
@@ -26,6 +26,19 @@ module.exports = app => {
                 GROUP BY e.ticketFk)`);
 
             await closeAll(req.args);
+
+            await db.rawSql(`
+            UPDATE ticket t
+                JOIN ticketState ts ON t.id = ts.ticketFk
+                JOIN alertLevel al ON al.alertLevel = ts.alertLevel
+                JOIN agencyMode am ON am.id = t.agencyModeFk 
+                JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
+                JOIN zone z ON z.id = t.zoneFk
+            SET t.routeFk = NULL
+                WHERE shipped BETWEEN CURDATE() AND util.dayEnd(CURDATE())
+                    AND al.code NOT IN('DELIVERED','PACKED')
+                    AND t.routeFk
+                    AND z.name LIKE '%MADRID%'`);
         } catch (error) {
             next(error);
         }
@@ -158,7 +171,7 @@ module.exports = app => {
 
         for (const ticket of tickets) {
             try {
-                await db.rawSql(`CALL vn.ticket_closeByTicket(:ticketId)`, {
+                await db.rawSql(`CALL vn.ticket_close(:ticketId)`, {
                     ticketId: ticket.id
                 });
 

From e6804f6ee32d9470bf3442e61930c0359766ac7c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 11:44:44 +0200
Subject: [PATCH 104/109] Removed procedures

---
 .../ticket_closeByAgency.sql                  | 32 --------------
 .../ticket_closeByAllWarehouses.sql           | 42 -------------------
 .../ticket_closeByRoute.sql                   | 29 -------------
 .../ticket_closeByTicket.sql                  | 28 -------------
 .../ticket_closeByWarehouse.sql               | 29 -------------
 5 files changed, 160 deletions(-)
 delete mode 100644 db/changes/10200-DeEscalation/ticket_closeByAgency.sql
 delete mode 100644 db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
 delete mode 100644 db/changes/10200-DeEscalation/ticket_closeByRoute.sql
 delete mode 100644 db/changes/10200-DeEscalation/ticket_closeByTicket.sql
 delete mode 100644 db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql

diff --git a/db/changes/10200-DeEscalation/ticket_closeByAgency.sql b/db/changes/10200-DeEscalation/ticket_closeByAgency.sql
deleted file mode 100644
index 155305afe2..0000000000
--- a/db/changes/10200-DeEscalation/ticket_closeByAgency.sql
+++ /dev/null
@@ -1,32 +0,0 @@
-CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByAgencyList`(vWarehouseFk INT, vDateTo DATE)
-BEGIN
-/**
- * Inserta los tickets de todos los almacenes en la tabla temporal
- * para ser cerrados.
- *
- * @param vWarehouseFk Id del almacén
- * @param vDate Fecha del cierre
- */
-
-	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
-
-	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
-		SELECT 
-			t.id AS ticketFk
-		FROM expedition e
-			JOIN ticket t ON t.id = e.ticketFk
-			JOIN tmp.ticketClosureAgencyList al ON al.agencyModeFk = t.agencyModeFk
-			JOIN ticketState ts ON ts.ticketFk = t.id
-		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-		WHERE al.code = 'PACKED'
-			AND t.warehouseFk = vWarehouseFk
-			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
-			AND t.refFk IS NULL
-		GROUP BY e.ticketFk);
-		
-        
-	CALL ticket_close();
-    
-	DROP TEMPORARY TABLE tmp.ticketClosureAgencyList;
-    DROP TEMPORARY TABLE tmp.ticketClosure;
-END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql b/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
deleted file mode 100644
index 4a3ae76c82..0000000000
--- a/db/changes/10200-DeEscalation/ticket_closeByAllWarehouses.sql
+++ /dev/null
@@ -1,42 +0,0 @@
-CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByAllWarehouses`(vDateTo DATE)
-BEGIN
-/**
- * Inserta los tickets de todos los almacenes en la tabla temporal
- * para ser cerrados.
- *
- * @param vDate Fecha del cierre
- */
-	DECLARE vDateToEndDay DATETIME DEFAULT util.dayEnd(vDateTo);
-    
-	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
-
-	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
-		SELECT 
-			t.id AS ticketFk
-		FROM expedition e
-			JOIN ticket t ON t.id = e.ticketFk
-			JOIN warehouse w ON w.id = t.warehouseFk AND hasComission
-			JOIN ticketState ts ON ts.ticketFk = t.id
-		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-		WHERE al.code = 'PACKED'
-			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
-			AND t.refFk IS NULL
-		GROUP BY e.ticketFk);
-        
-	CALL ticket_close();
-    
-    -- cau 15033
-    UPDATE ticket t
-				JOIN ticketState ts ON t.id = ts.ticketFk
-                JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-                JOIN agencyMode am ON am.id = t.agencyModeFk 
-                JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
-                JOIN zone z ON z.id = t.zoneFk
-		SET t.routeFk = NULL
-            WHERE shipped BETWEEN vDateTo AND vDateToEndDay
-				AND al.code NOT IN('DELIVERED','PACKED')
-                AND t.routeFk
-				AND z.`name` LIKE '%MADRID%';
-            
-    DROP TEMPORARY TABLE tmp.ticketClosure;
-END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByRoute.sql b/db/changes/10200-DeEscalation/ticket_closeByRoute.sql
deleted file mode 100644
index 3c1500bd6b..0000000000
--- a/db/changes/10200-DeEscalation/ticket_closeByRoute.sql
+++ /dev/null
@@ -1,29 +0,0 @@
-CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByRoute`( vRouteFk INT)
-BEGIN
-/**
- * Inserta los tickets de la ruta en la tabla temporal
- * para ser cerrados.
- *
- * @param vWarehouseFk Almacén a cerrar
- * @param vRouteFk Ruta a cerrar
- * @param vDate Fecha del cierre
- */
-
-	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
-
-	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
-		SELECT 
-			t.id AS ticketFk
-		FROM expedition e
-			JOIN ticket t ON t.id = e.ticketFk
-			JOIN ticketState ts ON ts.ticketFk = t.id
-		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-		WHERE al.code = 'PACKED'
-			AND t.routeFk = vRouteFk
-			AND t.refFk IS NULL
-		GROUP BY e.ticketFk);
-        
-	CALL ticket_close();
-    
-    DROP TEMPORARY TABLE tmp.ticketClosure;
-END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByTicket.sql b/db/changes/10200-DeEscalation/ticket_closeByTicket.sql
deleted file mode 100644
index 1ffb5a2653..0000000000
--- a/db/changes/10200-DeEscalation/ticket_closeByTicket.sql
+++ /dev/null
@@ -1,28 +0,0 @@
-CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByTicket`(vTicketFk INT)
-BEGIN
-
-/**
- * Inserta el ticket en la tabla temporal
- * para ser cerrado.
- *
- * @param vTicketFk Id del ticket
- */
-
-	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
-
-	CREATE TEMPORARY TABLE tmp.ticketClosure ENGINE = MEMORY (
-		SELECT 
-			t.id AS ticketFk
-		FROM expedition e
-			JOIN ticket t ON t.id = e.ticketFk
-			JOIN ticketState ts ON ts.ticketFk = t.id
-            JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-		WHERE al.code = 'PACKED'
-            AND t.id = vTicketFk
-			AND t.refFk IS NULL
-		GROUP BY e.ticketFk);
-        
-	CALL ticket_close();
-    
-    DROP TEMPORARY TABLE tmp.ticketClosure;
-END
\ No newline at end of file
diff --git a/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql b/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql
deleted file mode 100644
index e7996edb07..0000000000
--- a/db/changes/10200-DeEscalation/ticket_closeByWarehouse.sql
+++ /dev/null
@@ -1,29 +0,0 @@
-CREATE DEFINER=`root`@`%` PROCEDURE `ticket_closeByWarehouse`(vWarehouseFk INT, vDateTo DATE)
-BEGIN
-/**
- * Inserta los tickets del almacen en la tabla temporal
- * para ser cerrados.
- *
- * @param vWarehouseFk Almacén a cerrar
- * @param vDate Fecha del cierre
- */
-
-	DROP TEMPORARY TABLE IF EXISTS tmp.ticketClosure;
-
-	CREATE TEMPORARY TABLE ticketClosure ENGINE = MEMORY(
-		SELECT 
-			t.id AS ticketFk
-		FROM expedition e
-			JOIN ticket t ON t.id = e.ticketFk
-			JOIN ticketState ts ON ts.ticketFk = t.id
-		    JOIN alertLevel al ON al.alertLevel = ts.alertLevel
-		WHERE al.code = 'PACKED' 
-			AND t.warehouseFk = vWarehouseFk
-			AND DATE(t.shipped) BETWEEN DATE_ADD(vDateTo, INTERVAL -2 DAY) AND vDateTo
-			AND t.refFk IS NULL
-		GROUP BY e.ticketFk);
-        
-	CALL ticket_close();
-    
-    DROP TEMPORARY TABLE tmp.ticketClosure;
-END
\ No newline at end of file

From 812847d82e0306f1cc477bbbdc10def136a80d17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 11:45:29 +0200
Subject: [PATCH 105/109] Changed sql folder

---
 db/changes/{10220-a => 10210-summer}/ticket_close.sql | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename db/changes/{10220-a => 10210-summer}/ticket_close.sql (100%)

diff --git a/db/changes/10220-a/ticket_close.sql b/db/changes/10210-summer/ticket_close.sql
similarity index 100%
rename from db/changes/10220-a/ticket_close.sql
rename to db/changes/10210-summer/ticket_close.sql

From 8faddef7e8ba504b56d03cb7b440282c8d5a4654 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 11:45:54 +0200
Subject: [PATCH 106/109] Renamed sql file

---
 db/changes/10210-summer/{ticket_close.sql => 00-ticket_close.sql} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename db/changes/10210-summer/{ticket_close.sql => 00-ticket_close.sql} (100%)

diff --git a/db/changes/10210-summer/ticket_close.sql b/db/changes/10210-summer/00-ticket_close.sql
similarity index 100%
rename from db/changes/10210-summer/ticket_close.sql
rename to db/changes/10210-summer/00-ticket_close.sql

From ee52581a06ad83ee32aed74e82d427fbee0a845c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 11:50:23 +0200
Subject: [PATCH 107/109] Updated param description

---
 db/changes/10210-summer/00-ticket_close.sql | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/db/changes/10210-summer/00-ticket_close.sql b/db/changes/10210-summer/00-ticket_close.sql
index dd9786dcdb..e01fa8f7e8 100644
--- a/db/changes/10210-summer/00-ticket_close.sql
+++ b/db/changes/10210-summer/00-ticket_close.sql
@@ -8,6 +8,8 @@ BEGIN
 /**
  * Realiza el cierre de todos los 
  * tickets de la tabla ticketClosure.
+ *
+ * @param vTicketFk Id del ticket
  */
 	DECLARE vDone BOOL;
 	DECLARE vClientFk INT;

From 3efe14fc537bc1902f63ffa30d87e7ac4f9f1b86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 12:16:20 +0200
Subject: [PATCH 108/109] Removed unused vars

---
 db/changes/10210-summer/00-ticket_close.sql | 2 --
 1 file changed, 2 deletions(-)

diff --git a/db/changes/10210-summer/00-ticket_close.sql b/db/changes/10210-summer/00-ticket_close.sql
index e01fa8f7e8..96f9c55287 100644
--- a/db/changes/10210-summer/00-ticket_close.sql
+++ b/db/changes/10210-summer/00-ticket_close.sql
@@ -17,8 +17,6 @@ BEGIN
 	DECLARE vIsTaxDataChecked BOOL;
 	DECLARE vCompanyFk INT;
 	DECLARE vShipped DATE;
-	DECLARE vPriority INT DEFAULT 1;
-	DECLARE vReportDeliveryNote INT DEFAULT 1;
 	DECLARE vNewInvoiceId INT;
 	DECLARE vHasDailyInvoice BOOL;
 	DECLARE vWithPackage BOOL;

From 7b9205ee1eb1b0ea34941a51b1a6ad6a1e78aa2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20S=C3=A1nchez?= <joan@verdnatura.es>
Date: Mon, 7 Sep 2020 15:06:00 +0200
Subject: [PATCH 109/109] =?UTF-8?q?Actualizados=20t=C3=ADtulos=20de=20alba?=
 =?UTF-8?q?r=C3=A1n?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 print/templates/email/delivery-note-link/locale/en.yml | 2 +-
 print/templates/email/delivery-note-link/locale/es.yml | 4 ++--
 print/templates/email/delivery-note-link/locale/fr.yml | 4 ++--
 print/templates/email/delivery-note-link/locale/pt.yml | 4 ++--
 print/templates/email/delivery-note/locale/en.yml      | 2 +-
 print/templates/email/delivery-note/locale/es.yml      | 4 ++--
 print/templates/email/delivery-note/locale/fr.yml      | 4 ++--
 print/templates/email/delivery-note/locale/pt.yml      | 4 ++--
 8 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/print/templates/email/delivery-note-link/locale/en.yml b/print/templates/email/delivery-note-link/locale/en.yml
index 5f15268284..aaa545525f 100644
--- a/print/templates/email/delivery-note-link/locale/en.yml
+++ b/print/templates/email/delivery-note-link/locale/en.yml
@@ -1,5 +1,5 @@
 subject: Your delivery note
-title: "Here is your delivery note!"
+title: Your delivery note
 dear: Dear client
 description: The delivery note from the order <strong>{0}</strong> is now available. <br/>
   You can download it by clicking <a href="https://www.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">this link</a>.
diff --git a/print/templates/email/delivery-note-link/locale/es.yml b/print/templates/email/delivery-note-link/locale/es.yml
index 47c7f11da2..0bafd459ab 100644
--- a/print/templates/email/delivery-note-link/locale/es.yml
+++ b/print/templates/email/delivery-note-link/locale/es.yml
@@ -1,5 +1,5 @@
-subject: Aquí tienes tu albarán
-title: "Aquí tienes tu albarán"
+subject: Tu albarán
+title: Tu albarán
 dear: Estimado cliente
 description: Ya está disponible el albarán correspondiente al pedido <strong>{0}</strong>. <br/>
   Puedes verlo haciendo clic <a href="https://www.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">en este enlace</a>.
diff --git a/print/templates/email/delivery-note-link/locale/fr.yml b/print/templates/email/delivery-note-link/locale/fr.yml
index 3ecf357e17..bcb16c09f8 100644
--- a/print/templates/email/delivery-note-link/locale/fr.yml
+++ b/print/templates/email/delivery-note-link/locale/fr.yml
@@ -1,5 +1,5 @@
-subject: Voici votre bon de livraison
-title: "Voici votre bon de livraison"
+subject: Votre bon de livraison
+title: Votre bon de livraison
 dear: Cher client,
 description: Le bon de livraison correspondant à la commande <strong>{0}</strong> est maintenant disponible.<br/>
   Vous pouvez le voir en cliquant <a href="https://www.verdnatura.es/#!form=ecomerce/ticket&ticket={0}" target="_blank">sur ce lien</a>.
diff --git a/print/templates/email/delivery-note-link/locale/pt.yml b/print/templates/email/delivery-note-link/locale/pt.yml
index c008ea2c70..cff3ea52bc 100644
--- a/print/templates/email/delivery-note-link/locale/pt.yml
+++ b/print/templates/email/delivery-note-link/locale/pt.yml
@@ -1,5 +1,5 @@
-subject: Vossa Nota de Entrega
-title: "Esta é vossa nota de entrega!"
+subject: Vossa nota de entrega
+title: Vossa nota de entrega
 dear: Estimado cliente
 description: Já está disponível sua nota de entrega correspondente a encomenda numero <strong>{0}</strong>. <br/>
   Para ver-lo faça um clique <a href="https://www.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">neste link</a>.
diff --git a/print/templates/email/delivery-note/locale/en.yml b/print/templates/email/delivery-note/locale/en.yml
index fcabe11ec6..50d39e8cff 100644
--- a/print/templates/email/delivery-note/locale/en.yml
+++ b/print/templates/email/delivery-note/locale/en.yml
@@ -1,5 +1,5 @@
 subject: Your delivery note
-title: "Here is your delivery note!"
+title: Your delivery note
 dear: Dear client
 description: The delivery note from the order <strong>{0}</strong> is now available. <br/>
   You can download it by clicking on the attachment of this email.
diff --git a/print/templates/email/delivery-note/locale/es.yml b/print/templates/email/delivery-note/locale/es.yml
index 3294b2316d..ffa99e12fb 100644
--- a/print/templates/email/delivery-note/locale/es.yml
+++ b/print/templates/email/delivery-note/locale/es.yml
@@ -1,5 +1,5 @@
-subject: Aquí tienes tu albarán
-title: "¡Este es tu albarán!"
+subject: Tu albarán
+title: Tu albarán
 dear: Estimado cliente
 description: Ya está disponible el albarán correspondiente al pedido {0}. <br/>
   Puedes descargarlo haciendo clic en el adjunto de este correo.
diff --git a/print/templates/email/delivery-note/locale/fr.yml b/print/templates/email/delivery-note/locale/fr.yml
index fdaf6e320a..f8fb5e7cde 100644
--- a/print/templates/email/delivery-note/locale/fr.yml
+++ b/print/templates/email/delivery-note/locale/fr.yml
@@ -1,5 +1,5 @@
-subject: Voici votre bon de livraison
-title: "Voici votre bon de livraison!"
+subject: Votre bon de livraison
+title: Votre bon de livraison
 dear: Cher client,
 description: Le bon de livraison correspondant à la commande {0} est maintenant disponible.<br/>
   Vous pouvez le télécharger en cliquant sur la pièce jointe dans cet email.
diff --git a/print/templates/email/delivery-note/locale/pt.yml b/print/templates/email/delivery-note/locale/pt.yml
index cbca170a36..818a4de4c0 100644
--- a/print/templates/email/delivery-note/locale/pt.yml
+++ b/print/templates/email/delivery-note/locale/pt.yml
@@ -1,5 +1,5 @@
-subject: Vossa Nota de Entrega
-title: "Esta é vossa nota de entrega!"
+subject: Vossa nota de entrega
+title: Vossa nota de entrega
 dear: Estimado cliente
 description: Já está disponível sua nota de entrega correspondente a encomenda {0}. <br/>
   Podes descarregar-la fazendo um clique no arquivo anexado ao e-mail.