Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2341-Entry_lastBuy_section

This commit is contained in:
Carlos Jimenez Ruiz 2020-08-26 09:49:52 +02:00
commit d23e3eff76
32 changed files with 577 additions and 342 deletions

View File

@ -55,8 +55,9 @@ module.exports = Self => {
}; };
await fs.mkdir(dstDir, {recursive: true}); await fs.mkdir(dstDir, {recursive: true});
await sharp(srcFilePath) await sharp(srcFilePath, {failOnError: false})
.resize(collection.maxWidth, collection.maxHeight, resizeOpts) .resize(collection.maxWidth, collection.maxHeight, resizeOpts)
.png()
.toFile(dstFile); .toFile(dstFile);
const sizes = collection.sizes(); const sizes = collection.sizes();
@ -69,8 +70,9 @@ module.exports = Self => {
}; };
await fs.mkdir(dstDir, {recursive: true}); await fs.mkdir(dstDir, {recursive: true});
await sharp(srcFilePath) await sharp(srcFilePath, {failOnError: false})
.resize(size.width, size.height, resizeOpts) .resize(size.width, size.height, resizeOpts)
.png()
.toFile(dstFile); .toFile(dstFile);
} }

View File

@ -601,11 +601,11 @@ INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `workerFk`, `created`)
(12, 3, 19, NOW()), (12, 3, 19, NOW()),
(13, 3, 19, NOW()), (13, 3, 19, NOW()),
(14, 3, 19, NOW()), (14, 3, 19, NOW()),
(15, 3, 19, NOW()), (15, 2, 19, NOW()),
(16, 3, 19, NOW()), (16, 3, 19, NOW()),
(17, 3, 19, NOW()), (17, 2, 19, NOW()),
(18, 3, 19, NOW()), (18, 2, 19, NOW()),
(19, 3, 19, NOW()), (19, 2, 19, NOW()),
(20, 1, 19, DATE_ADD(NOW(), INTERVAL +1 MONTH)), (20, 1, 19, DATE_ADD(NOW(), INTERVAL +1 MONTH)),
(21, 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)), (22, 1, 19, DATE_ADD(NOW(), INTERVAL +1 MONTH)),

View File

@ -371,7 +371,7 @@ export default {
ticketsIndex: { ticketsIndex: {
openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]', openAdvancedSearchButton: 'vn-searchbar .append vn-icon[icon="arrow_drop_down"]',
advancedSearchInvoiceOut: 'vn-ticket-search-panel vn-textfield[ng-model="filter.refFk"]', 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', 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', 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', 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"]', confirmButton: '.vn-confirm.shown button[response="accept"]',
}, },
routeIndex: { routeIndex: {
addNewRouteButton: 'vn-route-index > a[ui-sref="route.create"]' addNewRouteButton: 'vn-route-index a[ui-sref="route.create"]'
}, },
createRouteView: { createRouteView: {
worker: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.workerFk"]', worker: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.workerFk"]',
@ -804,6 +804,22 @@ export default {
navigateBackToIndex: 'vn-worker-descriptor [name="goToModuleIndex"]', navigateBackToIndex: 'vn-worker-descriptor [name="goToModuleIndex"]',
acceptDeleteDialog: '.vn-confirm.shown button[response="accept"]' 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: { invoiceOutIndex: {
topbarSearch: 'vn-searchbar', topbarSearch: 'vn-searchbar',
searchButton: 'vn-searchbar vn-icon[icon="search"]', searchButton: 'vn-searchbar vn-icon[icon="search"]',

View File

@ -0,0 +1,137 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Worker calendar path', () => {
let reasonableTimeBetweenClicks = 400;
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('hr', 'worker');
await page.accessToSearchResult('Hank Pym');
await page.accessToSection('worker.card.calendar');
});
afterAll(async() => {
await browser.close();
});
describe('as hr', () => {
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(' 5 ');
});
it('should set two days as holidays on the calendar', async() => {
await page.waitToClick(selectors.workerCalendar.holidays);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.absence);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.marchTwentyThird);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.halfHoliday);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.mayFourth);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.furlough);
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(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.halfFurlough);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.mayEighth);
});
it('should check the total holidays increased by 1.5', async() => {
const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
expect(result).toContain(' 6.5 ');
});
});
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(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.holidays);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.absence);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.marchTwentyThird);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.halfHoliday);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.mayFourth);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.furlough);
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(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.halfFurlough);
await page.waitFor(reasonableTimeBetweenClicks);
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(' 5 ');
});
});
describe(`as Hank`, () => {
it(`should log in and get to his calendar`, async() => {
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(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.holidays);
await page.waitFor(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst);
});
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(' 5 ');
});
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.waitFor(reasonableTimeBetweenClicks);
const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
expect(result).toContain(' 0 ');
});
});
});

View File

@ -19,7 +19,7 @@ describe('Ticket index payout path', () => {
await page.waitForState('ticket.index'); 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.keyboard.press('Enter');
await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox); await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox);
await page.waitToClick(selectors.ticketsIndex.sixthTicketCheckbox); await page.waitToClick(selectors.ticketsIndex.sixthTicketCheckbox);

View File

@ -134,5 +134,5 @@
"This ticket is deleted": "Este ticket está eliminado", "This ticket is deleted": "Este ticket está eliminado",
"A travel with this data already exists": "Ya existe un travel con estos datos", "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", "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"
} }

View File

@ -46,7 +46,11 @@
style="overflow: hidden; min-width: 14em;"> style="overflow: hidden; min-width: 14em;">
<div class="ellipsize"><b>{{::address.nickname}} - #{{::address.id}}</b></div> <div class="ellipsize"><b>{{::address.nickname}} - #{{::address.id}}</b></div>
<div class="ellipsize" name="street">{{::address.street}}</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"> <div class="ellipsize">
{{::address.phone}}<span ng-if="::address.mobile">, </span> {{::address.phone}}<span ng-if="::address.mobile">, </span>
{{::address.mobile}} {{::address.mobile}}

View File

@ -16,7 +16,8 @@ class Controller extends Section {
'provinceFk', 'provinceFk',
'phone', 'phone',
'mobile', 'mobile',
'isEqualizated' 'isEqualizated',
'postalCode'
], ],
order: [ order: [
'isDefaultAddress DESC', 'isDefaultAddress DESC',

View File

@ -19,35 +19,42 @@ module.exports = Self => {
Self.downloadImages = async() => { Self.downloadImages = async() => {
const models = Self.app.models; const models = Self.app.models;
let image;
try { try {
const imageQueue = await Self.find({where: {error: null}, limit: 25}); 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 // Create temporary path
await fs.mkdir(tempPath, {recursive: true}); await fs.mkdir(tempPath, {recursive: true});
for (let image of imageQueue) { const timer = setInterval(async() => {
image = await Self.findOne({where: {error: null}});
// Exit loop
if (!image) return clearInterval(timer);
const fileName = `${image.itemFk}.png`; const fileName = `${image.itemFk}.png`;
const filePath = path.join(tempPath, fileName); const filePath = path.join(tempPath, fileName);
const file = fs.createWriteStream(filePath);
const writeStream = fs.createWriteStream(filePath);
writeStream.on('open', () => {
https.get(image.url, async response => { https.get(image.url, async response => {
if (response.statusCode != 200) { if (response.statusCode != 200) {
const error = new Error(`Could not download the image. Status code ${response.statusCode}`); const error = new Error(`Could not download the image. Status code ${response.statusCode}`);
file.close(); return await errorHandler(image.itemFk, error, filePath);
await errorHandler(image.itemFk, error, filePath);
} }
response.pipe(file); response.pipe(writeStream);
}).on('error', async error => {
await errorHandler(image.itemFk, error, filePath);
});
});
file.on('error', async error => { writeStream.on('error', async error => {
await errorHandler(image.itemFk, error, filePath); await errorHandler(image.itemFk, error, filePath);
}); });
file.on('finish', async function() { writeStream.on('finish', async function() {
try { try {
await models.Image.registerImage('catalog', fileName, filePath); await models.Image.registerImage('catalog', fileName, filePath);
await image.destroy(); await image.destroy();
@ -55,20 +62,25 @@ module.exports = Self => {
await errorHandler(image.itemFk, error, filePath); await errorHandler(image.itemFk, error, filePath);
} }
}); });
}).on('error', async error => { }, 1500);
await errorHandler(image.itemFk, error, filePath);
});
}
} catch (error) { } catch (error) {
await errorHandler(image.itemFk, error); await errorHandler(image.itemFk, error);
} }
async function errorHandler(rowId, error, filePath) { async function errorHandler(rowId, error, filePath) {
try {
const row = await Self.findById(rowId); const row = await Self.findById(rowId);
if (!row)
throw new Error(`Could not update due error ${error}`);
await row.updateAttribute('error', error); await row.updateAttribute('error', error);
if (filePath) if (filePath)
await fs.unlink(filePath); await fs.unlink(filePath);
} catch (error) {
throw error;
}
} }
}; };
}; };

View File

@ -8,6 +8,11 @@
<vn-table model="model"> <vn-table model="model">
<vn-thead> <vn-thead>
<vn-tr> <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 field="id" number>Id</vn-th>
<vn-th th-id="worker">Worker</vn-th> <vn-th th-id="worker">Worker</vn-th>
<vn-th th-id="agency">Agency</vn-th> <vn-th th-id="agency">Agency</vn-th>
@ -22,6 +27,12 @@
<a ng-repeat="route in model.data" <a ng-repeat="route in model.data"
class="clickable vn-tr search-result" class="clickable vn-tr search-result"
ui-sref="route.card.summary({id: {{::route.id}}})"> 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 number>{{::route.id | dashIfEmpty}}</vn-td>
<vn-td expand> <vn-td expand>
<span <span
@ -55,9 +66,26 @@
<vn-worker-descriptor-popover <vn-worker-descriptor-popover
vn-id="workerDescriptor"> vn-id="workerDescriptor">
</vn-worker-descriptor-popover> </vn-worker-descriptor-popover>
<a ui-sref="route.create"
vn-tooltip="New route"
</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-bind="+"
fixed-bottom-right> vn-tooltip="New route"
<vn-float-button icon="add"></vn-float-button> tooltip-position="left">
</vn-button>
</a> </a>
</vn-vertical>
</div>

View File

@ -2,12 +2,46 @@ import ngModule from '../module';
import Section from 'salix/components/section'; import Section from 'salix/components/section';
export default class Controller extends Section { export default class Controller extends Section {
constructor($element, $, vnReport) {
super($element, $);
this.vnReport = vnReport;
}
preview(route) { preview(route) {
this.routeSelected = route; this.routeSelected = route;
this.$.summary.show(); 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', { ngModule.vnComponent('vnRouteIndex', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller controller: Controller

View File

@ -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 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 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);
});
});
});

View File

@ -1 +1,2 @@
Vehicle: Vehículo Vehicle: Vehículo
Download selected routes as PDF: Descargar rutas seleccionadas como PDF

View File

@ -71,7 +71,7 @@
<span <span
ng-click="ticketDescriptor.show($event, ticket.id)" ng-click="ticketDescriptor.show($event, ticket.id)"
class="link"> class="link">
{{ticket.id | zeroFill:6}} {{ticket.id}}
</span> </span>
</vn-td> </vn-td>
<vn-td> <vn-td>

View File

@ -2,6 +2,7 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
const buildFilter = require('vn-loopback/util/filter').buildFilter; const buildFilter = require('vn-loopback/util/filter').buildFilter;
const mergeFilters = require('vn-loopback/util/filter').mergeFilters; const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.remoteMethod('filter', { 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(stmt);
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems'); stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticketGetProblems');
@ -241,9 +242,11 @@ module.exports = Self => {
CREATE TEMPORARY TABLE tmp.ticketGetProblems CREATE TEMPORARY TABLE tmp.ticketGetProblems
(INDEX (ticketFk)) (INDEX (ticketFk))
ENGINE = MEMORY ENGINE = MEMORY
SELECT id ticketFk, clientFk, warehouseFk, shipped SELECT f.id ticketFk, f.clientFk, f.warehouseFk, f.shipped
FROM tmp.filter FROM tmp.filter f
WHERE alertLevel = 0 OR alertLevel IS NULL`); LEFT JOIN alertLevel al ON al.alertLevel = f.alertLevel
WHERE (f.alertLevelCode = 'FREE' OR f.alertLevel IS NULL)
AND f.shipped >= CURDATE()`);
stmts.push('CALL ticketGetProblems()'); stmts.push('CALL ticketGetProblems()');
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticket'); stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.ticket');
@ -262,6 +265,9 @@ module.exports = Self => {
LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id LEFT JOIN tmp.ticketProblems tp ON tp.ticketFk = f.id
LEFT JOIN tmp.ticketTotal tt ON tt.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 condition;
let hasProblem; let hasProblem;
let range; let range;
@ -293,6 +299,7 @@ module.exports = Self => {
stmt.merge(conn.makeWhere(problems)); stmt.merge(conn.makeWhere(problems));
stmt.merge(conn.makeOrderBy(filter.order)); stmt.merge(conn.makeOrderBy(filter.order));
stmt.merge(conn.makeLimit(filter));
let ticketsIndex = stmts.push(stmt); let ticketsIndex = stmts.push(stmt);
stmts.push( stmts.push(

View File

@ -17,7 +17,7 @@ describe('ticket deleteStowaway()', () => {
await app.models.Stowaway.rawSql( await app.models.Stowaway.rawSql(
`CALL ticketStateUpdate(?, ?)`, [shipId, 'OK']); `CALL ticketStateUpdate(?, ?)`, [shipId, 'OK']);
await app.models.Stowaway.rawSql( await app.models.Stowaway.rawSql(
`CALL ticketStateUpdate(?, ?)`, [stowawayId, 'OK']); `CALL ticketStateUpdate(?, ?)`, [stowawayId, 'FREE']);
}); });
it('should create an stowaway', async() => { it('should create an stowaway', async() => {
@ -97,6 +97,6 @@ describe('ticket deleteStowaway()', () => {
} }
}); });
expect(shipState.name).toEqual('OK'); expect(shipState.name).toEqual('Libre');
}); });
}); });

View File

@ -11,7 +11,16 @@ describe('ticket filter()', () => {
}); });
it('should return the tickets matching the problems on true', async() => { 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 filter = {};
const result = await app.models.Ticket.filter(ctx, 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() => { 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 filter = {};
const result = await app.models.Ticket.filter(ctx, 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() => { it('should return the tickets matching the problems on null', async() => {
@ -52,10 +71,10 @@ describe('ticket filter()', () => {
const secondRow = result[1]; const secondRow = result[1];
const thirdRow = result[2]; const thirdRow = result[2];
expect(result.length).toEqual(3); expect(result.length).toEqual(7);
expect(firstRow.state).toEqual('Arreglar'); expect(firstRow.state).toEqual('Libre');
expect(secondRow.state).toEqual('Arreglar'); expect(secondRow.state).toEqual('Libre');
expect(thirdRow.state).toEqual('Arreglar'); expect(thirdRow.state).toEqual('Libre');
}); });
it('should return the tickets that are not pending', async() => { it('should return the tickets that are not pending', async() => {

View File

@ -2,14 +2,15 @@
vn-id="model" vn-id="model"
url="Tickets/filter" url="Tickets/filter"
limit="20" limit="20"
order="shipped DESC, zoneHour ASC, zoneMinute ASC, clientFk"> order="shipped DESC, zoneHour DESC, zoneMinute DESC, clientFk">
</vn-crud-model> </vn-crud-model>
<vn-portal slot="topbar"> <vn-portal slot="topbar">
<vn-searchbar <vn-searchbar
panel="vn-ticket-search-panel" panel="vn-ticket-search-panel"
info="Search ticket by id or alias" info="Search ticket by id or alias"
model="model" model="model"
fetch-params="$ctrl.fetchParams($params)"> fetch-params="$ctrl.fetchParams($params)"
suggested-filter="$ctrl.defaultFilter">
</vn-searchbar> </vn-searchbar>
</vn-portal> </vn-portal>
<vn-portal slot="menu"> <vn-portal slot="menu">

View File

@ -2,6 +2,14 @@ import ngModule from '../module';
import ModuleMain from 'salix/components/module-main'; import ModuleMain from 'salix/components/module-main';
export default class Ticket extends ModuleMain { export default class Ticket extends ModuleMain {
constructor() {
super();
this.defaultFilter = {
scopeDays: 1
};
}
fetchParams($params) { fetchParams($params) {
if (!Object.entries($params).length) if (!Object.entries($params).length)
$params.scopeDays = 1; $params.scopeDays = 1;

View File

@ -29,6 +29,15 @@
{{'of' | translate}} {{$ctrl.calendar.totalHolidays}} {{'days' | translate}} {{'of' | translate}} {{$ctrl.calendar.totalHolidays}} {{'days' | translate}}
</div> </div>
</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;"> <div class="vn-pt-md" style="overflow: hidden;">
<vn-chip ng-repeat="absenceType in absenceTypes" ng-class="::{'selectable': $ctrl.isSubordinate}" <vn-chip ng-repeat="absenceType in absenceTypes" ng-class="::{'selectable': $ctrl.isSubordinate}"
ng-click="$ctrl.pick(absenceType)"> ng-click="$ctrl.pick(absenceType)">

View File

@ -7,6 +7,20 @@ class Controller extends Section {
super($element, $); super($element, $);
this.date = new Date(); this.date = new Date();
this.events = {}; this.events = {};
this.buildYearFilter();
}
get year() {
return this.date.getFullYear();
}
set year(value) {
const newYear = new Date();
newYear.setFullYear(value);
this.date = newYear;
this.refresh().then(() => this.repaint());
} }
get date() { get date() {
@ -50,6 +64,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() { getIsSubordinate() {
this.$http.get(`Workers/${this.worker.id}/isSubordinate`).then(res => this.$http.get(`Workers/${this.worker.id}/isSubordinate`).then(res =>
this.isSubordinate = res.data this.isSubordinate = res.data
@ -117,6 +142,9 @@ class Controller extends Section {
if (!this.absenceType) if (!this.absenceType)
return this.vnApp.showMessage(this.$t('Choose an absence type from the right menu')); 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 day = $days[0];
const stamp = day.getTime(); const stamp = day.getTime();
const event = this.events[stamp]; const event = this.events[stamp];

View File

@ -22,6 +22,25 @@ describe('Worker', () => {
controller._worker = {id: 106}; 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`, () => {
jest.spyOn(controller, 'refresh').mockReturnValue(Promise.resolve());
const previousYear = year - 1;
controller.year = previousYear;
expect(controller.year).toEqual(previousYear);
expect(controller.date.getFullYear()).toEqual(previousYear);
expect(controller.refresh).toHaveBeenCalledWith();
});
});
describe('started property', () => { describe('started property', () => {
it(`should return first day and month of current year`, () => { it(`should return first day and month of current year`, () => {
let started = new Date(year, 0, 1); let started = new Date(year, 0, 1);
@ -141,6 +160,28 @@ describe('Worker', () => {
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('Choose an absence type from the right menu'); 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`, () => { it(`should call to the create() method`, () => {
jest.spyOn(controller, 'create').mockReturnThis(); jest.spyOn(controller, 'create').mockReturnThis();

View File

@ -1,7 +1,9 @@
Calendar: Calendario Calendar: Calendario
Holidays: Vacaciones Holidays: Vacaciones
Used: Utilizados Used: Utilizados
Year: Año
of: de of: de
days: días days: días
Choose an absence type from the right menu: Elige un tipo de ausencia desde el menú de la derecha 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 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

View File

@ -29,7 +29,8 @@ module.exports = Self => {
const options = {transaction: tx}; const options = {transaction: tx};
const filter = { const filter = {
where: { where: {
zoneFk: id zoneFk: id,
shipped: {gte: today}
}, },
include: { include: {
relation: 'ticketState', relation: 'ticketState',
@ -46,10 +47,10 @@ module.exports = Self => {
where: {userFk: userId} where: {userFk: userId}
}, options); }, options);
ticketList.forEach(ticket => { await models.Ticket.rawSql('UPDATE ticket SET zoneFk = NULL WHERE zoneFk = ?', [id], options);
promises.push(ticket.updateAttributes({zoneFk: null}, options));
if (ticket.ticketState().alertLevel == 0 && ticket.shipped >= today) { ticketList.forEach(ticket => {
if (ticket.ticketState().alertLevel == 0) {
promises.push(models.TicketTracking.create({ promises.push(models.TicketTracking.create({
ticketFk: ticket.id, ticketFk: ticket.id,
stateFk: fixingState.id, stateFk: fixingState.id,

View File

@ -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? Do you want to clone this zone?: ¿Quieres clonar esta zona?
All it's properties will be copied: Todas sus propiedades serán copiadas All it's properties will be copied: Todas sus propiedades serán copiadas
Zone deleted: Zona eliminada Zone deleted: Zona eliminada

38
package-lock.json generated
View File

@ -181,9 +181,9 @@
}, },
"dependencies": { "dependencies": {
"lodash": { "lodash": {
"version": "4.17.15", "version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true "dev": true
} }
} }
@ -3001,9 +3001,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.15", "version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true "dev": true
}, },
"ms": { "ms": {
@ -3026,9 +3026,9 @@
}, },
"dependencies": { "dependencies": {
"lodash": { "lodash": {
"version": "4.17.15", "version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true "dev": true
} }
} }
@ -8630,9 +8630,9 @@
"integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug==" "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug=="
}, },
"dot-prop": { "dot-prop": {
"version": "4.2.0", "version": "4.2.1",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz",
"integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==",
"requires": { "requires": {
"is-obj": "^1.0.0" "is-obj": "^1.0.0"
} }
@ -8743,9 +8743,9 @@
"dev": true "dev": true
}, },
"elliptic": { "elliptic": {
"version": "6.5.2", "version": "6.5.3",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
"integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
"dev": true, "dev": true,
"requires": { "requires": {
"bn.js": "^4.4.0", "bn.js": "^4.4.0",
@ -13104,7 +13104,7 @@
}, },
"is-obj": { "is-obj": {
"version": "1.0.1", "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=" "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
}, },
"is-path-cwd": { "is-path-cwd": {
@ -18581,9 +18581,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.15", "version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
}, },
"lodash._basecopy": { "lodash._basecopy": {
"version": "3.0.1", "version": "3.0.1",

View File

@ -24,8 +24,9 @@ p.privacy {
text-align: center text-align: center
} }
.page .pageCount { .pageCount {
text-align: right text-align: right;
float: right
} }
.footer .page > div { .footer .page > div {

View File

@ -33,6 +33,7 @@ class Report extends Component {
args: ['--no-sandbox', '--disable-setuid-sandbox'] args: ['--no-sandbox', '--disable-setuid-sandbox']
}); });
const page = await browser.newPage(); const page = await browser.newPage();
await page.emulateMedia('screen');
await page.setContent(template); await page.setContent(template);
const element = await page.$('#pageFooter'); const element = await page.$('#pageFooter');

278
print/package-lock.json generated
View File

@ -4,20 +4,10 @@
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
"@types/node": { "@types/mime-types": {
"version": "14.0.27", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz", "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.0.tgz",
"integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==", "integrity": "sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM="
"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": "*"
}
}, },
"agent-base": { "agent-base": {
"version": "5.1.1", "version": "5.1.1",
@ -74,6 +64,11 @@
"resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz", "resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz",
"integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ==" "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": { "asynckit": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "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", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" "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": { "bcrypt-pbkdf": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@ -107,23 +97,6 @@
"tweetnacl": "^0.14.3" "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": { "boolbase": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@ -138,25 +111,10 @@
"concat-map": "0.0.1" "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": { "buffer-from": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
"optional": true
}, },
"camelcase": { "camelcase": {
"version": "5.3.1", "version": "5.3.1",
@ -201,11 +159,6 @@
"lodash.some": "^4.4.0" "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": { "cliui": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
@ -266,7 +219,6 @@
"version": "1.6.2", "version": "1.6.2",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
"optional": true,
"requires": { "requires": {
"buffer-from": "^1.0.0", "buffer-from": "^1.0.0",
"inherits": "^2.0.3", "inherits": "^2.0.3",
@ -278,7 +230,6 @@
"version": "2.3.6", "version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"optional": true,
"requires": { "requires": {
"core-util-is": "~1.0.0", "core-util-is": "~1.0.0",
"inherits": "~2.0.3", "inherits": "~2.0.3",
@ -293,7 +244,6 @@
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"optional": true,
"requires": { "requires": {
"safe-buffer": "~5.1.0" "safe-buffer": "~5.1.0"
} }
@ -354,7 +304,6 @@
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"optional": true,
"requires": { "requires": {
"ms": "2.0.0" "ms": "2.0.0"
} }
@ -379,11 +328,6 @@
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
"integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" "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": { "dijkstrajs": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz", "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", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" "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": { "entities": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
@ -472,7 +408,6 @@
"version": "1.6.7", "version": "1.6.7",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
"integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
"optional": true,
"requires": { "requires": {
"concat-stream": "1.6.2", "concat-stream": "1.6.2",
"debug": "2.6.9", "debug": "2.6.9",
@ -499,7 +434,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
"integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
"optional": true,
"requires": { "requires": {
"pend": "~1.2.0" "pend": "~1.2.0"
} }
@ -527,11 +461,6 @@
"mime-types": "^2.1.12" "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": { "fs-extra": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "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", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" "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": { "getpass": {
"version": "0.1.7", "version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@ -704,11 +625,6 @@
"safer-buffer": ">= 2.1.2 < 3" "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": { "image-size": {
"version": "0.7.5", "version": "0.7.5",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz",
@ -757,8 +673,7 @@
"isarray": { "isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
"optional": true
}, },
"isexe": { "isexe": {
"version": "2.0.0", "version": "2.0.0",
@ -1000,28 +915,20 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
"optional": true
}, },
"mkdirp": { "mkdirp": {
"version": "0.5.1", "version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "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": { "ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
"optional": true
}, },
"mysql2": { "mysql2": {
"version": "1.7.0", "version": "1.7.0",
@ -1198,46 +1105,6 @@
"pinkie": "^2.0.0" "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": { "pngjs": {
"version": "3.4.0", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
@ -1246,8 +1113,7 @@
"process-nextick-args": { "process-nextick-args": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
"optional": true
}, },
"progress": { "progress": {
"version": "1.1.8", "version": "1.1.8",
@ -1270,37 +1136,26 @@
"resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
"integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" "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": { "punycode": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
}, },
"puppeteer": { "puppeteer": {
"version": "5.2.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-5.2.1.tgz", "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-2.1.1.tgz",
"integrity": "sha512-PZoZG7u+T6N1GFWBQmGVG162Ak5MAy8nYSVpeeQrwJK2oYUlDWpHEJPcd/zopyuEMTv7DiztS1blgny1txR2qw==", "integrity": "sha512-LWzaDVQkk1EPiuYeTOj+CZRIjda4k2s5w4MK4xoH2+kgWV/SDlkYHmxatDdtYrciHUKSXTsGgPgPP8ILVdBsxg==",
"requires": { "requires": {
"@types/mime-types": "^2.1.0",
"debug": "^4.1.0", "debug": "^4.1.0",
"devtools-protocol": "0.0.781568", "extract-zip": "^1.6.6",
"extract-zip": "^2.0.0",
"https-proxy-agent": "^4.0.0", "https-proxy-agent": "^4.0.0",
"mime": "^2.0.3", "mime": "^2.0.3",
"pkg-dir": "^4.2.0", "mime-types": "^2.1.25",
"progress": "^2.0.1", "progress": "^2.0.1",
"proxy-from-env": "^1.0.0", "proxy-from-env": "^1.0.0",
"rimraf": "^3.0.2", "rimraf": "^2.6.1",
"tar-fs": "^2.0.0", "ws": "^6.1.0"
"unbzip2-stream": "^1.3.3",
"ws": "^7.2.3"
}, },
"dependencies": { "dependencies": {
"debug": { "debug": {
@ -1311,23 +1166,17 @@
"ms": "^2.1.1" "ms": "^2.1.1"
} }
}, },
"extract-zip": { "mime-db": {
"version": "2.0.1", "version": "1.44.0",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
"requires": {
"@types/yauzl": "^2.9.1",
"debug": "^4.1.1",
"get-stream": "^5.1.0",
"yauzl": "^2.10.0"
}
}, },
"fd-slicer": { "mime-types": {
"version": "1.1.0", "version": "2.1.27",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
"requires": { "requires": {
"pend": "~1.2.0" "mime-db": "1.44.0"
} }
}, },
"ms": { "ms": {
@ -1339,15 +1188,6 @@
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" "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": { "rimraf": {
"version": "3.0.2", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"requires": { "requires": {
"glob": "^7.1.3" "glob": "^7.1.3"
} }
@ -1586,40 +1426,12 @@
"has-flag": "^3.0.0" "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": { "throttleit": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
"integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
"optional": true "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": { "tough-cookie": {
"version": "2.4.3", "version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
@ -1652,17 +1464,7 @@
"typedarray": { "typedarray": {
"version": "0.0.6", "version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "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"
}
}, },
"universalify": { "universalify": {
"version": "0.1.2", "version": "0.1.2",
@ -1819,9 +1621,12 @@
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}, },
"ws": { "ws": {
"version": "7.3.1", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
"integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==" "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
"requires": {
"async-limiter": "~1.0.0"
}
}, },
"xtend": { "xtend": {
"version": "4.0.2", "version": "4.0.2",
@ -1868,7 +1673,6 @@
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
"integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
"optional": true,
"requires": { "requires": {
"fd-slicer": "~1.0.1" "fd-slicer": "~1.0.1"
} }

View File

@ -47,3 +47,8 @@ section.text-area {
padding-right: 1em; padding-right: 1em;
background-color: #e5e5e5; background-color: #e5e5e5;
} }
.route-block {
margin-bottom: 100px;
page-break-after: always;
}

View File

@ -8,9 +8,9 @@
<!-- Header block --> <!-- Header block -->
<report-header v-bind="$props"></report-header> <report-header v-bind="$props"></report-header>
<!-- Block --> <!-- Block -->
<div class="grid-row"> <div class="grid-row route-block" v-for="route in routes">
<div class="grid-block"> <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="panel">
<div class="header">{{$t('information')}}</div> <div class="header">{{$t('information')}}</div>
<div class="body"> <div class="body">
@ -80,7 +80,8 @@
</div> </div>
</div> </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> <div>
<table class="column-oriented repeatable"> <table class="column-oriented repeatable">
<thead> <thead>
@ -151,7 +152,7 @@
</div> </div>
<!-- Footer block --> <!-- Footer block -->
<report-footer id="pageFooter" <report-footer id="pageFooter"
v-bind:left-text="$t('routeId', [route.id])" v-bind:left-text="$t('routeId', [routeId])"
v-bind="$props"> v-bind="$props">
</report-footer> </report-footer>
</td> </td>

View File

@ -6,15 +6,26 @@ const reportFooter = new Component('report-footer');
module.exports = { module.exports = {
name: 'driver-route', name: 'driver-route',
async serverPrefetch() { async serverPrefetch() {
this.route = await this.fetchRoute(this.routeId); const routesId = this.routeId.split(',');
this.tickets = await this.fetchTickets(this.routeId); const routes = await this.fetchRoutes(routesId);
const tickets = await this.fetchTickets(routesId);
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'); throw new Error('Something went wrong');
}, },
methods: { methods: {
fetchRoute(id) { fetchRoutes(routesId) {
return db.findOne( return db.rawSql(
`SELECT `SELECT
r.id, r.id,
r.m3, r.m3,
@ -30,9 +41,9 @@ module.exports = {
LEFT JOIN worker w ON w.id = r.workerFk LEFT JOIN worker w ON w.id = r.workerFk
LEFT JOIN account.user u ON u.id = w.userFk LEFT JOIN account.user u ON u.id = w.userFk
LEFT JOIN agencyMode am ON am.id = r.agencyModeFk 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( return db.rawSql(
`SELECT `SELECT
t.nickname addressName, t.nickname addressName,
@ -41,6 +52,7 @@ module.exports = {
t.id, t.id,
t.clientFk, t.clientFk,
t.companyFk, t.companyFk,
t.routeFk,
if(a.phone, a.phone, c.phone) AS phone, if(a.phone, a.phone, c.phone) AS phone,
if(a.mobile, a.mobile, c.mobile) AS mobile, if(a.mobile, a.mobile, c.mobile) AS mobile,
wh.name warehouseName, wh.name warehouseName,
@ -65,8 +77,8 @@ module.exports = {
LEFT JOIN warehouse wh ON wh.id = t.warehouseFk LEFT JOIN warehouse wh ON wh.id = t.warehouseFk
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
LEFT JOIN stowaway s ON s.id = t.id LEFT JOIN stowaway s ON s.id = t.id
WHERE r.id = ? WHERE r.id IN(:routesId)
ORDER BY t.priority, t.id`, [routeId]); ORDER BY t.priority, t.id`, {routesId});
} }
}, },
components: { components: {