Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2595-invoiceIn-index
This commit is contained in:
commit
718021cff8
|
@ -34,4 +34,5 @@ rules:
|
||||||
no-multiple-empty-lines: ["error", { "max": 1, "maxEOF": 1 }]
|
no-multiple-empty-lines: ["error", { "max": 1, "maxEOF": 1 }]
|
||||||
space-in-parens: ["error", "never"]
|
space-in-parens: ["error", "never"]
|
||||||
jasmine/no-focused-tests: 0
|
jasmine/no-focused-tests: 0
|
||||||
jasmine/prefer-toHaveBeenCalledWith: 0
|
jasmine/prefer-toHaveBeenCalledWith: 0
|
||||||
|
arrow-spacing: ["error", { "before": true, "after": true }]
|
|
@ -110,11 +110,10 @@ module.exports = Self => {
|
||||||
async function createDms(ctx, file, myOptions) {
|
async function createDms(ctx, file, myOptions) {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const myUserId = ctx.req.accessToken.userId;
|
const myUserId = ctx.req.accessToken.userId;
|
||||||
const myWorker = await models.Worker.findOne({where: {userFk: myUserId}}, myOptions);
|
|
||||||
const args = ctx.args;
|
const args = ctx.args;
|
||||||
|
|
||||||
const newDms = await Self.create({
|
const newDms = await Self.create({
|
||||||
workerFk: myWorker.id,
|
workerFk: myUserId,
|
||||||
dmsTypeFk: args.dmsTypeId,
|
dmsTypeFk: args.dmsTypeId,
|
||||||
companyFk: args.companyId,
|
companyFk: args.companyId,
|
||||||
warehouseFk: args.warehouseId,
|
warehouseFk: args.warehouseId,
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.validatesPresenceOf('name', {
|
||||||
|
message: 'Name cannot be blank'
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.validatesPresenceOf('bic', {
|
||||||
|
message: 'Swift / BIC cannot be empty'
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.validatesUniquenessOf('bic', {
|
||||||
|
message: 'This BIC already exist.'
|
||||||
|
});
|
||||||
|
};
|
|
@ -1,11 +1,51 @@
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const sharp = require('sharp');
|
const sharp = require('sharp');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const readChunk = require('read-chunk');
|
||||||
|
const imageType = require('image-type');
|
||||||
|
const bmp = require('bmp-js');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/image/download')(Self);
|
require('../methods/image/download')(Self);
|
||||||
require('../methods/image/upload')(Self);
|
require('../methods/image/upload')(Self);
|
||||||
|
|
||||||
|
// Function extracted from jimp package (utils)
|
||||||
|
function scan(image, x, y, w, h, f) {
|
||||||
|
// round input
|
||||||
|
x = Math.round(x);
|
||||||
|
y = Math.round(y);
|
||||||
|
w = Math.round(w);
|
||||||
|
h = Math.round(h);
|
||||||
|
|
||||||
|
for (let _y = y; _y < y + h; _y++) {
|
||||||
|
for (let _x = x; _x < x + w; _x++) {
|
||||||
|
const idx = (image.bitmap.width * _y + _x) << 2;
|
||||||
|
f.call(image, _x, _y, idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function extracted from jimp package (type-bmp)
|
||||||
|
function fromAGBR(bitmap) {
|
||||||
|
return scan({bitmap}, 0, 0, bitmap.width, bitmap.height, function(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
index
|
||||||
|
) {
|
||||||
|
const alpha = this.bitmap.data[index + 0];
|
||||||
|
const blue = this.bitmap.data[index + 1];
|
||||||
|
const green = this.bitmap.data[index + 2];
|
||||||
|
const red = this.bitmap.data[index + 3];
|
||||||
|
|
||||||
|
this.bitmap.data[index + 0] = red;
|
||||||
|
this.bitmap.data[index + 1] = green;
|
||||||
|
this.bitmap.data[index + 2] = blue;
|
||||||
|
this.bitmap.data[index + 3] = bitmap.is_with_alpha ? alpha : 0xff;
|
||||||
|
}).bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
Self.registerImage = async(collectionName, srcFilePath, fileName, entityId) => {
|
Self.registerImage = async(collectionName, srcFilePath, fileName, entityId) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const tx = await Self.beginTransaction({});
|
const tx = await Self.beginTransaction({});
|
||||||
|
@ -48,13 +88,31 @@ module.exports = Self => {
|
||||||
const dstDir = path.join(collectionDir, 'full');
|
const dstDir = path.join(collectionDir, 'full');
|
||||||
const dstFile = path.join(dstDir, file);
|
const dstFile = path.join(dstDir, file);
|
||||||
|
|
||||||
|
const buffer = readChunk.sync(srcFilePath, 0, 12);
|
||||||
|
const type = imageType(buffer);
|
||||||
|
|
||||||
|
let sharpOptions;
|
||||||
|
let imgSrc = srcFilePath;
|
||||||
|
if (type.mime == 'image/bmp') {
|
||||||
|
const bmpBuffer = fs.readFileSync(srcFilePath);
|
||||||
|
const bmpData = fromAGBR(bmp.decode(bmpBuffer));
|
||||||
|
imgSrc = bmpData.data;
|
||||||
|
sharpOptions = {
|
||||||
|
raw: {
|
||||||
|
width: bmpData.width,
|
||||||
|
height: bmpData.height,
|
||||||
|
channels: 4
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const resizeOpts = {
|
const resizeOpts = {
|
||||||
withoutEnlargement: true,
|
withoutEnlargement: true,
|
||||||
fit: 'inside'
|
fit: 'inside'
|
||||||
};
|
};
|
||||||
|
|
||||||
await fs.mkdir(dstDir, {recursive: true});
|
await fs.mkdir(dstDir, {recursive: true});
|
||||||
await sharp(srcFilePath, {failOnError: false})
|
await sharp(imgSrc, sharpOptions)
|
||||||
.resize(collection.maxWidth, collection.maxHeight, resizeOpts)
|
.resize(collection.maxWidth, collection.maxHeight, resizeOpts)
|
||||||
.png()
|
.png()
|
||||||
.toFile(dstFile);
|
.toFile(dstFile);
|
||||||
|
@ -69,7 +127,7 @@ module.exports = Self => {
|
||||||
};
|
};
|
||||||
|
|
||||||
await fs.mkdir(dstDir, {recursive: true});
|
await fs.mkdir(dstDir, {recursive: true});
|
||||||
await sharp(srcFilePath, {failOnError: false})
|
await sharp(imgSrc, sharpOptions)
|
||||||
.resize(size.width, size.height, resizeOpts)
|
.resize(size.width, size.height, resizeOpts)
|
||||||
.png()
|
.png()
|
||||||
.toFile(dstFile);
|
.toFile(dstFile);
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId) VALUES ('InvoiceIn', '*', '*', 'ALLOW', 'ROLE', 'administrative');
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||||
|
VALUES
|
||||||
|
('SupplierAccount', '*', '*', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('Entry', '*', '*', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', '*', '*', 'ALLOW', 'ROLE', 'administrative');
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
DROP PROCEDURE `vn`.`item_getBalance`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
$$
|
||||||
|
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`item_getBalance`(IN vItemId INT, IN vWarehouse INT)
|
||||||
|
BEGIN
|
||||||
|
DECLARE vDateInventory DATETIME;
|
||||||
|
DECLARE vCurdate DATE DEFAULT CURDATE();
|
||||||
|
DECLARE vDayEnd DATETIME DEFAULT util.dayEnd(vCurdate);
|
||||||
|
|
||||||
|
SELECT inventoried INTO vDateInventory FROM config;
|
||||||
|
SET @a = 0;
|
||||||
|
SET @currentLineFk = 0;
|
||||||
|
SET @shipped = '';
|
||||||
|
|
||||||
|
SELECT DATE(@shipped:= shipped) shipped,
|
||||||
|
alertLevel,
|
||||||
|
stateName,
|
||||||
|
origin,
|
||||||
|
reference,
|
||||||
|
clientFk,
|
||||||
|
name,
|
||||||
|
`in`,
|
||||||
|
`out`,
|
||||||
|
@a := @a + IFNULL(`in`,0) - IFNULL(`out`,0) as balance,
|
||||||
|
@currentLineFk := IF (@shipped < CURDATE()
|
||||||
|
OR (@shipped = CURDATE() AND (isPicked OR alertLevel >= 2)),
|
||||||
|
lineFk,@currentLineFk) lastPreparedLineFk,
|
||||||
|
isTicket,
|
||||||
|
lineFk,
|
||||||
|
isPicked,
|
||||||
|
clientType
|
||||||
|
FROM
|
||||||
|
( SELECT tr.landed AS shipped,
|
||||||
|
b.quantity AS `in`,
|
||||||
|
NULL AS `out`,
|
||||||
|
al.alertLevel AS alertLevel,
|
||||||
|
st.name AS stateName,
|
||||||
|
s.name AS name,
|
||||||
|
e.ref AS reference,
|
||||||
|
e.id AS origin,
|
||||||
|
s.id AS clientFk,
|
||||||
|
IF(al.alertLevel = 3, TRUE, FALSE) isPicked,
|
||||||
|
FALSE AS isTicket,
|
||||||
|
b.id lineFk,
|
||||||
|
NULL `order`,
|
||||||
|
NULL AS clientType
|
||||||
|
FROM buy b
|
||||||
|
JOIN entry e ON e.id = b.entryFk
|
||||||
|
JOIN travel tr ON tr.id = e.travelFk
|
||||||
|
JOIN supplier s ON s.id = e.supplierFk
|
||||||
|
JOIN alertLevel al ON al.alertLevel =
|
||||||
|
CASE
|
||||||
|
WHEN tr.shipped < CURDATE() THEN 3
|
||||||
|
WHEN tr.shipped = CURDATE() AND tr.isReceived = TRUE THEN 3
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
JOIN state st ON st.code = al.code
|
||||||
|
WHERE tr.landed >= vDateInventory
|
||||||
|
AND vWarehouse = tr.warehouseInFk
|
||||||
|
AND b.itemFk = vItemId
|
||||||
|
AND e.isInventory = FALSE
|
||||||
|
AND e.isRaid = FALSE
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT tr.shipped,
|
||||||
|
NULL as `in`,
|
||||||
|
b.quantity AS `out`,
|
||||||
|
al.alertLevel AS alertLevel,
|
||||||
|
st.name AS stateName,
|
||||||
|
s.name AS name,
|
||||||
|
e.ref AS reference,
|
||||||
|
e.id AS origin,
|
||||||
|
s.id AS clientFk,
|
||||||
|
IF(al.alertLevel = 3, TRUE, FALSE) isPicked,
|
||||||
|
FALSE AS isTicket,
|
||||||
|
b.id,
|
||||||
|
NULL `order`,
|
||||||
|
NULL AS clientType
|
||||||
|
FROM buy b
|
||||||
|
JOIN entry e ON e.id = b.entryFk
|
||||||
|
JOIN travel tr ON tr.id = e.travelFk
|
||||||
|
JOIN warehouse w ON w.id = tr.warehouseOutFk
|
||||||
|
JOIN supplier s ON s.id = e.supplierFk
|
||||||
|
JOIN alertLevel al ON al.alertLevel =
|
||||||
|
CASE
|
||||||
|
WHEN tr.shipped < CURDATE() THEN 3
|
||||||
|
WHEN tr.shipped = CURDATE() AND tr.isReceived = TRUE THEN 3
|
||||||
|
ELSE 0
|
||||||
|
END
|
||||||
|
JOIN state st ON st.code = al.code
|
||||||
|
WHERE tr.shipped >= vDateInventory
|
||||||
|
AND vWarehouse =tr.warehouseOutFk
|
||||||
|
AND s.id <> 4
|
||||||
|
AND b.itemFk = vItemId
|
||||||
|
AND e.isInventory = FALSE
|
||||||
|
AND w.isFeedStock = FALSE
|
||||||
|
AND e.isRaid = FALSE
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT DATE(t.shipped),
|
||||||
|
NULL as `in`,
|
||||||
|
s.quantity AS `out`,
|
||||||
|
al.alertLevel AS alertLevel,
|
||||||
|
st.name AS stateName,
|
||||||
|
t.nickname AS name,
|
||||||
|
t.refFk AS reference,
|
||||||
|
t.id AS origin,
|
||||||
|
t.clientFk,
|
||||||
|
stk.id AS isPicked,
|
||||||
|
TRUE AS isTicket,
|
||||||
|
s.id,
|
||||||
|
st.`order`,
|
||||||
|
ct.code AS clientType
|
||||||
|
FROM sale s
|
||||||
|
JOIN ticket t ON t.id = s.ticketFk
|
||||||
|
LEFT JOIN ticketState ts ON ts.ticket = t.id
|
||||||
|
LEFT JOIN state st ON st.code = ts.code
|
||||||
|
JOIN client c ON c.id = t.clientFk
|
||||||
|
JOIN clientType ct ON ct.id = c.clientTypeFk
|
||||||
|
JOIN alertLevel al ON al.alertLevel =
|
||||||
|
CASE
|
||||||
|
WHEN t.shipped < curdate() THEN 3
|
||||||
|
WHEN t.shipped > util.dayEnd(curdate()) THEN 0
|
||||||
|
ELSE IFNULL(ts.alertLevel, 0)
|
||||||
|
END
|
||||||
|
LEFT JOIN state stPrep ON stPrep.`code` = 'PREPARED'
|
||||||
|
LEFT JOIN saleTracking stk ON stk.saleFk = s.id AND stk.stateFk = stPrep.id
|
||||||
|
WHERE t.shipped >= vDateInventory
|
||||||
|
AND s.itemFk = vItemId
|
||||||
|
AND vWarehouse =t.warehouseFk
|
||||||
|
ORDER BY shipped, alertLevel DESC, isTicket, `order` DESC, isPicked DESC, `in` DESC, `out` DESC
|
||||||
|
) AS itemDiary;
|
||||||
|
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
|
@ -150,20 +150,20 @@ INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `isPrinted`, `priority`, `park
|
||||||
|
|
||||||
INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`,`code`)
|
INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`,`code`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'CC y Polizas de crédito', NULL, NULL),
|
(1, 'CC y Polizas de crédito', NULL, NULL),
|
||||||
(2, 'Cash', NULL, 'cash'),
|
(2, 'Cash', 'Cash', 'cash'),
|
||||||
(3, 'Credit card', NULL, 'creditCard'),
|
(3, 'Credit card', 'Credit Card', 'creditCard'),
|
||||||
(4, 'Finalcial lines', NULL, NULL),
|
(4, 'Finalcial lines', NULL, NULL),
|
||||||
(5, 'Other products', NULL, NULL),
|
(5, 'Other products', NULL, NULL),
|
||||||
(6, 'Loans', NULL, NULL),
|
(6, 'Loans', NULL, NULL),
|
||||||
(7, 'Leasing', NULL, NULL),
|
(7, 'Leasing', NULL, NULL),
|
||||||
(8, 'Compensations', 'Compensations', 'Compensations');
|
(8, 'Compensations', 'Compensations', 'compensation');
|
||||||
|
|
||||||
INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`)
|
INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'Pay on receipt', '0000000000', 3, 0, 1, 1),
|
(1, 'Pay on receipt', '5720000001', 3, 0, 1, 1),
|
||||||
(2, 'Cash', '1111111111', 2, 0, 1, 1),
|
(2, 'Cash', '5700000001', 2, 0, 1, 1),
|
||||||
(3, 'Compensation', '0000000000', 8, 0, 1, 1);
|
(3, 'Compensation', '4000000000', 8, 0, 1, 1);
|
||||||
|
|
||||||
INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
|
INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
|
||||||
VALUES
|
VALUES
|
||||||
|
|
|
@ -316,7 +316,7 @@ export default {
|
||||||
fourthRelevancy: 'vn-item-tags vn-horizontal:nth-child(4) [ng-model="itemTag.priority"]',
|
fourthRelevancy: 'vn-item-tags vn-horizontal:nth-child(4) [ng-model="itemTag.priority"]',
|
||||||
fourthRemoveTagButton: 'vn-item-tags vn-horizontal:nth-child(4) vn-icon-button[icon="delete"]',
|
fourthRemoveTagButton: 'vn-item-tags vn-horizontal:nth-child(4) vn-icon-button[icon="delete"]',
|
||||||
fifthTag: 'vn-item-tags vn-horizontal:nth-child(5) > vn-autocomplete[ng-model="itemTag.tagFk"]',
|
fifthTag: 'vn-item-tags vn-horizontal:nth-child(5) > vn-autocomplete[ng-model="itemTag.tagFk"]',
|
||||||
fifthValue: 'vn-item-tags vn-horizontal:nth-child(5) vn-textfield[ng-model="itemTag.value"]',
|
fifthValue: 'vn-item-tags vn-horizontal:nth-child(5) vn-autocomplete[ng-model="itemTag.value"]',
|
||||||
fifthRelevancy: 'vn-item-tags vn-horizontal:nth-child(5) vn-input-number[ng-model="itemTag.priority"]',
|
fifthRelevancy: 'vn-item-tags vn-horizontal:nth-child(5) vn-input-number[ng-model="itemTag.priority"]',
|
||||||
sixthTag: 'vn-item-tags vn-horizontal:nth-child(6) > vn-autocomplete[ng-model="itemTag.tagFk"]',
|
sixthTag: 'vn-item-tags vn-horizontal:nth-child(6) > vn-autocomplete[ng-model="itemTag.tagFk"]',
|
||||||
sixthValue: 'vn-item-tags vn-horizontal:nth-child(6) vn-textfield[ng-model="itemTag.value"]',
|
sixthValue: 'vn-item-tags vn-horizontal:nth-child(6) vn-textfield[ng-model="itemTag.value"]',
|
||||||
|
|
|
@ -47,6 +47,7 @@ describe('Client balance path', () => {
|
||||||
await page.closePopup();
|
await page.closePopup();
|
||||||
await page.waitToClick(selectors.clientBalance.newPaymentButton);
|
await page.waitToClick(selectors.clientBalance.newPaymentButton);
|
||||||
await page.autocompleteSearch(selectors.clientBalance.newPaymentBank, 'Cash');
|
await page.autocompleteSearch(selectors.clientBalance.newPaymentBank, 'Cash');
|
||||||
|
await page.clearInput(selectors.clientBalance.newDescription);
|
||||||
await page.write(selectors.clientBalance.newDescription, 'Description');
|
await page.write(selectors.clientBalance.newDescription, 'Description');
|
||||||
await page.waitToClick(selectors.clientBalance.saveButton);
|
await page.waitToClick(selectors.clientBalance.saveButton);
|
||||||
const message = await page.waitForSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
@ -86,6 +87,7 @@ describe('Client balance path', () => {
|
||||||
|
|
||||||
await page.waitToClick(selectors.clientBalance.newPaymentButton);
|
await page.waitToClick(selectors.clientBalance.newPaymentButton);
|
||||||
await page.write(selectors.clientBalance.newPaymentAmount, amountPaid);
|
await page.write(selectors.clientBalance.newPaymentAmount, amountPaid);
|
||||||
|
await page.clearInput(selectors.clientBalance.newDescription);
|
||||||
await page.write(selectors.clientBalance.newDescription, 'Payment');
|
await page.write(selectors.clientBalance.newDescription, 'Payment');
|
||||||
await page.write(selectors.clientBalance.deliveredAmount, cashHanded);
|
await page.write(selectors.clientBalance.deliveredAmount, cashHanded);
|
||||||
const refund = await page.waitToGetProperty(selectors.clientBalance.refundAmount, 'value');
|
const refund = await page.waitToGetProperty(selectors.clientBalance.refundAmount, 'value');
|
||||||
|
@ -107,6 +109,7 @@ describe('Client balance path', () => {
|
||||||
await page.waitToClick(selectors.clientBalance.newPaymentButton);
|
await page.waitToClick(selectors.clientBalance.newPaymentButton);
|
||||||
await page.autocompleteSearch(selectors.clientBalance.newPaymentBank, 'Pay on receipt');
|
await page.autocompleteSearch(selectors.clientBalance.newPaymentBank, 'Pay on receipt');
|
||||||
await page.overwrite(selectors.clientBalance.newPaymentAmount, '-150');
|
await page.overwrite(selectors.clientBalance.newPaymentAmount, '-150');
|
||||||
|
await page.clearInput(selectors.clientBalance.newDescription);
|
||||||
await page.write(selectors.clientBalance.newDescription, 'Description');
|
await page.write(selectors.clientBalance.newDescription, 'Description');
|
||||||
await page.waitToClick(selectors.clientBalance.saveButton);
|
await page.waitToClick(selectors.clientBalance.saveButton);
|
||||||
const message = await page.waitForSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
|
|
@ -16,7 +16,7 @@ describe('Item create tags path', () => {
|
||||||
await browser.close();
|
await browser.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should create a new tag and delete a former one`, async() => {
|
it('should create a new tag and delete a former one', async() => {
|
||||||
await page.waitToClick(selectors.itemTags.fourthRemoveTagButton);
|
await page.waitToClick(selectors.itemTags.fourthRemoveTagButton);
|
||||||
await page.waitToClick(selectors.itemTags.addItemTagButton);
|
await page.waitToClick(selectors.itemTags.addItemTagButton);
|
||||||
await page.autocompleteSearch(selectors.itemTags.seventhTag, 'Ancho de la base');
|
await page.autocompleteSearch(selectors.itemTags.seventhTag, 'Ancho de la base');
|
||||||
|
@ -29,7 +29,7 @@ describe('Item create tags path', () => {
|
||||||
expect(message.text).toContain('Data saved!');
|
expect(message.text).toContain('Data saved!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should confirm the fourth row data is the expected one`, async() => {
|
it('should confirm the fourth row data is the expected one', async() => {
|
||||||
await page.reloadSection('item.card.tags');
|
await page.reloadSection('item.card.tags');
|
||||||
await page.waitForSelector('vn-item-tags');
|
await page.waitForSelector('vn-item-tags');
|
||||||
let result = await page.waitToGetProperty(selectors.itemTags.fourthTag, 'value');
|
let result = await page.waitToGetProperty(selectors.itemTags.fourthTag, 'value');
|
||||||
|
@ -47,7 +47,7 @@ describe('Item create tags path', () => {
|
||||||
expect(result).toEqual('4');
|
expect(result).toEqual('4');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should confirm the fifth row data is the expected one`, async() => {
|
it('should confirm the fifth row data is the expected one', async() => {
|
||||||
let tag = await page
|
let tag = await page
|
||||||
.waitToGetProperty(selectors.itemTags.fifthTag, 'value');
|
.waitToGetProperty(selectors.itemTags.fifthTag, 'value');
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ describe('Item create tags path', () => {
|
||||||
expect(relevancy).toEqual('5');
|
expect(relevancy).toEqual('5');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should confirm the sixth row data is the expected one`, async() => {
|
it('should confirm the sixth row data is the expected one', async() => {
|
||||||
let tag = await page
|
let tag = await page
|
||||||
.waitToGetProperty(selectors.itemTags.sixthTag, 'value');
|
.waitToGetProperty(selectors.itemTags.sixthTag, 'value');
|
||||||
|
|
||||||
|
|
|
@ -174,4 +174,9 @@ vn-table {
|
||||||
.vn-check {
|
.vn-check {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
.empty-rows {
|
||||||
|
color: $color-font-secondary;
|
||||||
|
font-size: 1.375rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<vn-dialog class="edit"
|
||||||
|
vn-id="bankEntityDialog"
|
||||||
|
on-open="$ctrl.resetData()"
|
||||||
|
on-accept="$ctrl.onAccept()"
|
||||||
|
message="New bank entity">
|
||||||
|
<tpl-body>
|
||||||
|
<p translate>Please, ensure you put the correct data!</p>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield
|
||||||
|
vn-one
|
||||||
|
vn-focus
|
||||||
|
vn-id="entityName"
|
||||||
|
label="Name"
|
||||||
|
ng-model="$ctrl.data.name"
|
||||||
|
required="true">
|
||||||
|
</vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield
|
||||||
|
vn-one
|
||||||
|
vn-focus
|
||||||
|
vn-id="bic"
|
||||||
|
label="Swift"
|
||||||
|
ng-model="$ctrl.data.bic"
|
||||||
|
required="true">
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-autocomplete vn-one
|
||||||
|
ng-model="$ctrl.data.countryFk"
|
||||||
|
url="Countries"
|
||||||
|
show-field="country"
|
||||||
|
value-field="id"
|
||||||
|
label="Country">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
</tpl-body>
|
||||||
|
<tpl-buttons>
|
||||||
|
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||||
|
<button id= "saveBankEntity" response="accept" translate>Save</button>
|
||||||
|
</tpl-buttons>
|
||||||
|
</vn-dialog>
|
|
@ -0,0 +1,37 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import Component from 'core/lib/component';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
class Controller extends Component {
|
||||||
|
open() {
|
||||||
|
this.$.bankEntityDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
resetData() {
|
||||||
|
this.data = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccept() {
|
||||||
|
try {
|
||||||
|
if (!this.data.countryFk)
|
||||||
|
throw new Error(`The country can't be empty`);
|
||||||
|
|
||||||
|
this.$http.post(`bankEntities`, this.data).then(res => {
|
||||||
|
this.vnApp.showMessage(this.$t('The bank entity has been created. You can save the data now'));
|
||||||
|
this.emit('response', {$response: res.data});
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
this.vnApp.showError(this.$t(e.message));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngModule.vnComponent('vnNewBankEntity', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller,
|
||||||
|
bindings: {
|
||||||
|
data: '<',
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,53 @@
|
||||||
|
import './index';
|
||||||
|
|
||||||
|
describe('Salix Component vnNewBankEntity', () => {
|
||||||
|
let controller;
|
||||||
|
let $httpBackend;
|
||||||
|
let $scope;
|
||||||
|
let $element;
|
||||||
|
let vnApp;
|
||||||
|
|
||||||
|
beforeEach(ngModule('salix'));
|
||||||
|
|
||||||
|
beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _vnApp_) => {
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
vnApp = _vnApp_;
|
||||||
|
jest.spyOn(vnApp, 'showError');
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
$element = angular.element('<vn-dialog></dialog>');
|
||||||
|
controller = $componentController('vnNewBankEntity', {$element, $scope});
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('resetData()', () => {
|
||||||
|
it('should reset the location in the controller', () => {
|
||||||
|
expect(controller.data).toBeUndefined();
|
||||||
|
|
||||||
|
controller.resetData();
|
||||||
|
|
||||||
|
expect(controller.data).toEqual({});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onAccept()', () => {
|
||||||
|
it('should throw an error if there is no country id in the location', () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showMessage');
|
||||||
|
|
||||||
|
controller.data = {};
|
||||||
|
|
||||||
|
controller.onAccept();
|
||||||
|
|
||||||
|
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The country can't be empty`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should do add the new bank entity', () => {
|
||||||
|
controller.data = {
|
||||||
|
countryFk: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
$httpBackend.expectPOST('bankEntities', controller.data).respond(200, controller.data);
|
||||||
|
|
||||||
|
controller.onAccept();
|
||||||
|
$httpBackend.flush();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,12 @@
|
||||||
|
New postcode: Nuevo código postal
|
||||||
|
New city: Nueva ciudad
|
||||||
|
New province: Nueva provincia
|
||||||
|
Please, ensure you put the correct data!: ¡Por favor, asegúrate de poner los datos correctos!
|
||||||
|
The postcode can't be empty: El código postal no puede quedar vacío
|
||||||
|
The town can't be empty: La población no puede quedar vacía
|
||||||
|
The province can't be empty: La provincia no puede quedar vacía
|
||||||
|
The country can't be empty: El país no puede quedar vacío
|
||||||
|
The postcode has been created. You can save the data now: Se ha creado el código postal. Ahora puedes guardar los datos
|
||||||
|
The city has been created: Se ha creado la ciudad
|
||||||
|
The province has been created: Se ha creado la provincia
|
||||||
|
The bank entity has been created. You can save the data now: Se ha creado la entidad bancaria. Puedes guardar los datos ahora
|
|
@ -0,0 +1,9 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
vn-new-bank-entity {
|
||||||
|
vn-dialog {
|
||||||
|
p {
|
||||||
|
color: $color-alert
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,3 +14,4 @@ import './summary';
|
||||||
import './topbar/topbar';
|
import './topbar/topbar';
|
||||||
import './user-popover';
|
import './user-popover';
|
||||||
import './upload-photo';
|
import './upload-photo';
|
||||||
|
import './bank-entity';
|
||||||
|
|
|
@ -91,5 +91,6 @@
|
||||||
"The observation type can't be repeated": "The observation type can't be repeated",
|
"The observation type can't be repeated": "The observation type can't be repeated",
|
||||||
"New ticket request has been created with price": "New ticket request has been created *'{{description}}'* for day *{{shipped}}*, with a quantity of *{{quantity}}* and a price of *{{price}} €*",
|
"New ticket request has been created with price": "New ticket request has been created *'{{description}}'* for day *{{shipped}}*, with a quantity of *{{quantity}}* and a price of *{{price}} €*",
|
||||||
"New ticket request has been created": "New ticket request has been created *'{{description}}'* for day *{{shipped}}*, with a quantity of *{{quantity}}*",
|
"New ticket request has been created": "New ticket request has been created *'{{description}}'* for day *{{shipped}}*, with a quantity of *{{quantity}}*",
|
||||||
"There's a new urgent ticket": "There's a new urgent ticket: [{{title}}](https://cau.verdnatura.es/WorkOrder.do?woMode=viewWO&woID={{issueId}})"
|
"There's a new urgent ticket": "There's a new urgent ticket: [{{title}}](https://cau.verdnatura.es/WorkOrder.do?woMode=viewWO&woID={{issueId}})",
|
||||||
|
"Swift / BIC cannot be empty": "Swift / BIC cannot be empty"
|
||||||
}
|
}
|
|
@ -167,9 +167,12 @@
|
||||||
"You can't upload images on the test environment": "No puedes subir imágenes en el entorno de pruebas",
|
"You can't upload images on the test environment": "No puedes subir imágenes en el entorno de pruebas",
|
||||||
"The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta",
|
"The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta",
|
||||||
"Sorts whole route": "Reordena ruta entera",
|
"Sorts whole route": "Reordena ruta entera",
|
||||||
"Invalid account": "Cuenta inválida",
|
"New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día <strong>{{shipped}}</strong>, con una cantidad de <strong>{{quantity}}</strong> y un precio de <strong>{{price}} €</strong>",
|
||||||
"New ticket request has been created with price": "Se ha creado una nueva petición de compra *'{{description}}'* para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*",
|
"New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día <strong>{{shipped}}</strong>, con una cantidad de <strong>{{quantity}}</strong>",
|
||||||
"New ticket request has been created": "Se ha creado una nueva petición de compra *'{{description}}'* para el día *{{shipped}}*, con una cantidad de *{{quantity}}*",
|
"Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío",
|
||||||
|
"This BIC already exist.": "Este BIC ya existe.",
|
||||||
"That item doesn't exists": "Ese artículo no existe",
|
"That item doesn't exists": "Ese artículo no existe",
|
||||||
"There's a new urgent ticket": "Hay un nuevo ticket urgente: [{{title}}](https://cau.verdnatura.es/WorkOrder.do?woMode=viewWO&woID={{issueId}})"
|
"There's a new urgent ticket": "Hay un nuevo ticket urgente: [{{title}}](https://cau.verdnatura.es/WorkOrder.do?woMode=viewWO&woID={{issueId}})",
|
||||||
|
"Invalid account": "Cuenta inválida",
|
||||||
|
"Compensation account is empty": "La cuenta para compensar está vacia"
|
||||||
}
|
}
|
|
@ -62,7 +62,10 @@ module.exports = function(Self) {
|
||||||
const bank = await models.Bank.findById(args.bankFk);
|
const bank = await models.Bank.findById(args.bankFk);
|
||||||
const accountingType = await models.AccountingType.findById(bank.accountingTypeFk);
|
const accountingType = await models.AccountingType.findById(bank.accountingTypeFk);
|
||||||
|
|
||||||
if (args.compensationAccount) {
|
if (accountingType.code == 'compensation') {
|
||||||
|
if (!args.compensationAccount)
|
||||||
|
throw new UserError('Compensation account is empty');
|
||||||
|
|
||||||
const supplierCompensation = await models.Supplier.findOne({
|
const supplierCompensation = await models.Supplier.findOne({
|
||||||
where: {
|
where: {
|
||||||
account: args.compensationAccount
|
account: args.compensationAccount
|
||||||
|
@ -92,12 +95,11 @@ module.exports = function(Self) {
|
||||||
],
|
],
|
||||||
options);
|
options);
|
||||||
} else {
|
} else {
|
||||||
const description = `${clientOriginal.id} : ${clientOriginal.nickname} - ${accountingType.receiptDescription}`;
|
const description = `${clientOriginal.id} : ${clientOriginal.socialName} - ${accountingType.receiptDescription}`;
|
||||||
const [xdiarioNew] = await Self.rawSql(
|
const [xdiarioNew] = await Self.rawSql(
|
||||||
`SELECT xdiario_new(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ledger;`,
|
`SELECT xdiario_new(?, CURDATE(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ledger;`,
|
||||||
[
|
[
|
||||||
null,
|
null,
|
||||||
Date(),
|
|
||||||
bank.account,
|
bank.account,
|
||||||
clientOriginal.accountingAccount,
|
clientOriginal.accountingAccount,
|
||||||
description,
|
description,
|
||||||
|
@ -114,10 +116,9 @@ module.exports = function(Self) {
|
||||||
options);
|
options);
|
||||||
|
|
||||||
await Self.rawSql(
|
await Self.rawSql(
|
||||||
`SELECT xdiario_new(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`,
|
`SELECT xdiario_new(?, CURDATE(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`,
|
||||||
[
|
[
|
||||||
xdiarioNew.ledger,
|
xdiarioNew.ledger,
|
||||||
Date(),
|
|
||||||
clientOriginal.accountingAccount,
|
clientOriginal.accountingAccount,
|
||||||
bank.account,
|
bank.account,
|
||||||
description,
|
description,
|
||||||
|
|
|
@ -26,15 +26,25 @@ module.exports = Self => {
|
||||||
Self.lastActiveTickets = async(id, ticketId) => {
|
Self.lastActiveTickets = async(id, ticketId) => {
|
||||||
const ticket = await Self.app.models.Ticket.findById(ticketId);
|
const ticket = await Self.app.models.Ticket.findById(ticketId);
|
||||||
const query = `
|
const query = `
|
||||||
SELECT t.id, t.shipped, a.name AS agencyName, w.name AS warehouseName, ad.city AS address
|
SELECT
|
||||||
FROM vn.ticket t
|
t.id,
|
||||||
JOIN vn.ticketState ts ON t.id = ts.ticketFk
|
t.shipped,
|
||||||
JOIN vn.agencyMode a ON t.agencyModeFk = a.id
|
a.name AS agencyName,
|
||||||
JOIN vn.warehouse w ON t.warehouseFk = w.id
|
w.name AS warehouseName,
|
||||||
JOIN vn.address ad ON t.addressFk = ad.id
|
ad.nickname AS nickname,
|
||||||
WHERE t.shipped >= CURDATE() AND t.clientFk = ? AND ts.alertLevel = 0
|
ad.city AS city,
|
||||||
AND t.id <> ? AND t.warehouseFk = ?
|
ad.postalCode AS postalCode,
|
||||||
ORDER BY t.shipped
|
ad.street AS street,
|
||||||
|
pr.name AS name
|
||||||
|
FROM ticket t
|
||||||
|
JOIN vn.ticketState ts ON t.id = ts.ticketFk
|
||||||
|
JOIN vn.agencyMode a ON t.agencyModeFk = a.id
|
||||||
|
JOIN vn.warehouse w ON t.warehouseFk = w.id
|
||||||
|
JOIN vn.address ad ON t.addressFk = ad.id
|
||||||
|
JOIN vn.province pr ON ad.provinceFk = pr.id
|
||||||
|
WHERE t.shipped >= CURDATE() AND t.clientFk = ? AND ts.alertLevel = 0
|
||||||
|
AND t.id <> ? AND t.warehouseFk = ?
|
||||||
|
ORDER BY t.shipped
|
||||||
LIMIT 10`;
|
LIMIT 10`;
|
||||||
|
|
||||||
return Self.rawSql(query, [id, ticketId, ticket.warehouseFk]);
|
return Self.rawSql(query, [id, ticketId, ticket.warehouseFk]);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('Client createReceipt', () => {
|
describe('Client createReceipt', () => {
|
||||||
const clientFk = 108;
|
const clientFk = 108;
|
||||||
|
@ -6,18 +7,34 @@ describe('Client createReceipt', () => {
|
||||||
const companyFk = 442;
|
const companyFk = 442;
|
||||||
const amountPaid = 12.50;
|
const amountPaid = 12.50;
|
||||||
const description = 'Receipt description';
|
const description = 'Receipt description';
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: 5},
|
||||||
|
http: {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const ctx = {req: activeCtx};
|
||||||
|
activeCtx.http.req.__ = value => {
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should create a new receipt', async() => {
|
it('should create a new receipt', async() => {
|
||||||
const bankFk = 1;
|
const bankFk = 1;
|
||||||
let ctx = {
|
ctx.args = {
|
||||||
args: {
|
clientFk: clientFk,
|
||||||
clientFk: clientFk,
|
payed: payed,
|
||||||
payed: payed,
|
companyFk: companyFk,
|
||||||
companyFk: companyFk,
|
bankFk: bankFk,
|
||||||
bankFk: bankFk,
|
amountPaid: amountPaid,
|
||||||
amountPaid: amountPaid,
|
description: description
|
||||||
description: description
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const receipt = await app.models.Client.createReceipt(ctx);
|
const receipt = await app.models.Client.createReceipt(ctx);
|
||||||
|
@ -38,19 +55,39 @@ describe('Client createReceipt', () => {
|
||||||
await till.destroy();
|
await till.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should throw Compensation account is empty', async() => {
|
||||||
|
const bankFk = 3;
|
||||||
|
|
||||||
|
ctx.args = {
|
||||||
|
clientFk: clientFk,
|
||||||
|
payed: payed,
|
||||||
|
companyFk: companyFk,
|
||||||
|
bankFk: bankFk,
|
||||||
|
amountPaid: amountPaid,
|
||||||
|
description: description
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await app.models.Client.createReceipt(ctx);
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toBeDefined();
|
||||||
|
expect(error.message).toEqual('Compensation account is empty');
|
||||||
|
});
|
||||||
|
|
||||||
it('should throw Invalid account if compensationAccount does not belongs to a client nor a supplier', async() => {
|
it('should throw Invalid account if compensationAccount does not belongs to a client nor a supplier', async() => {
|
||||||
let error;
|
let error;
|
||||||
const bankFk = 3;
|
const bankFk = 3;
|
||||||
const ctx = {
|
ctx.args = {
|
||||||
args: {
|
clientFk: clientFk,
|
||||||
clientFk: clientFk,
|
payed: payed,
|
||||||
payed: payed,
|
companyFk: companyFk,
|
||||||
companyFk: companyFk,
|
bankFk: bankFk,
|
||||||
bankFk: bankFk,
|
amountPaid: amountPaid,
|
||||||
amountPaid: amountPaid,
|
description: description,
|
||||||
description: description,
|
compensationAccount: 'non existing account'
|
||||||
compensationAccount: 'non existing account'
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -65,16 +102,15 @@ describe('Client createReceipt', () => {
|
||||||
|
|
||||||
it('should create a new receipt with a compensation for a client', async() => {
|
it('should create a new receipt with a compensation for a client', async() => {
|
||||||
const bankFk = 3;
|
const bankFk = 3;
|
||||||
const ctx = {
|
|
||||||
args: {
|
ctx.args = {
|
||||||
clientFk: clientFk,
|
clientFk: clientFk,
|
||||||
payed: payed,
|
payed: payed,
|
||||||
companyFk: companyFk,
|
companyFk: companyFk,
|
||||||
bankFk: bankFk,
|
bankFk: bankFk,
|
||||||
amountPaid: amountPaid,
|
amountPaid: amountPaid,
|
||||||
description: description,
|
description: description,
|
||||||
compensationAccount: '4300000001'
|
compensationAccount: '4300000001'
|
||||||
}
|
|
||||||
};
|
};
|
||||||
const receipt = await app.models.Client.createReceipt(ctx);
|
const receipt = await app.models.Client.createReceipt(ctx);
|
||||||
const receiptCompensated = await app.models.Receipt.findOne({
|
const receiptCompensated = await app.models.Receipt.findOne({
|
||||||
|
@ -104,16 +140,16 @@ describe('Client createReceipt', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a new receipt with a compensation for a supplier', async() => {
|
it('should create a new receipt with a compensation for a supplier', async() => {
|
||||||
const ctx = {
|
const bankFk = 3;
|
||||||
args: {
|
|
||||||
clientFk: clientFk,
|
ctx.args = {
|
||||||
payed: payed,
|
clientFk: clientFk,
|
||||||
companyFk: companyFk,
|
payed: payed,
|
||||||
bankFk: 3,
|
companyFk: companyFk,
|
||||||
amountPaid: amountPaid,
|
bankFk: bankFk,
|
||||||
description: description,
|
amountPaid: amountPaid,
|
||||||
compensationAccount: '4100000001'
|
description: description,
|
||||||
}
|
compensationAccount: '4100000001'
|
||||||
};
|
};
|
||||||
const receipt = await app.models.Client.createReceipt(ctx);
|
const receipt = await app.models.Client.createReceipt(ctx);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
describe('Client last active tickets', () => {
|
||||||
|
it('should receive an array of last active tickets of Bruce Wayne', async() => {
|
||||||
|
const ticketId = 22;
|
||||||
|
const clientId = 109;
|
||||||
|
const warehouseId = 5;
|
||||||
|
const result = await app.models.Client.lastActiveTickets(clientId, ticketId, warehouseId);
|
||||||
|
|
||||||
|
const length = result.length;
|
||||||
|
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
|
||||||
|
|
||||||
|
const properties = Object.keys(anyResult);
|
||||||
|
|
||||||
|
expect(properties.length).toEqual(9);
|
||||||
|
expect(result.length).toEqual(3);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,8 +0,0 @@
|
||||||
module.exports = Self => {
|
|
||||||
Self.validatesPresenceOf('name', {
|
|
||||||
message: `Name cannot be blank`
|
|
||||||
});
|
|
||||||
Self.validatesPresenceOf('bic', {
|
|
||||||
message: `Swift / BIC can't be empty`
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
module.exports = function(Self) {
|
module.exports = function(Self) {
|
||||||
require('../methods/receipt/filter')(Self);
|
require('../methods/receipt/filter')(Self);
|
||||||
|
|
||||||
|
@ -23,13 +25,10 @@ module.exports = function(Self) {
|
||||||
|
|
||||||
Self.observe('before save', async function(ctx) {
|
Self.observe('before save', async function(ctx) {
|
||||||
if (ctx.isNewInstance) {
|
if (ctx.isNewInstance) {
|
||||||
let token = ctx.options.accessToken;
|
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||||
let userId = token && token.userId;
|
ctx.instance.workerFk = loopBackContext.active.accessToken.userId;
|
||||||
|
|
||||||
ctx.instance.workerFk = userId;
|
|
||||||
|
|
||||||
await Self.app.models.Till.create({
|
await Self.app.models.Till.create({
|
||||||
workerFk: userId,
|
workerFk: ctx.instance.workerFk,
|
||||||
bankFk: ctx.instance.bankFk,
|
bankFk: ctx.instance.bankFk,
|
||||||
in: ctx.instance.amountPaid,
|
in: ctx.instance.amountPaid,
|
||||||
concept: ctx.instance.description,
|
concept: ctx.instance.description,
|
||||||
|
|
|
@ -78,6 +78,8 @@ module.exports = Self => {
|
||||||
return {'ic.id': value};
|
return {'ic.id': value};
|
||||||
case 'salesPersonFk':
|
case 'salesPersonFk':
|
||||||
return {'it.workerFk': value};
|
return {'it.workerFk': value};
|
||||||
|
case 'code':
|
||||||
|
return {'it.code': value};
|
||||||
case 'typeFk':
|
case 'typeFk':
|
||||||
return {'i.typeFk': value};
|
return {'i.typeFk': value};
|
||||||
case 'active':
|
case 'active':
|
||||||
|
@ -103,6 +105,7 @@ module.exports = Self => {
|
||||||
i.id AS itemFk,
|
i.id AS itemFk,
|
||||||
i.size,
|
i.size,
|
||||||
i.density,
|
i.density,
|
||||||
|
it.code,
|
||||||
i.typeFk,
|
i.typeFk,
|
||||||
i.family,
|
i.family,
|
||||||
i.isActive,
|
i.isActive,
|
||||||
|
|
|
@ -37,8 +37,8 @@
|
||||||
<vn-th field="quantity">Quantity</vn-th>
|
<vn-th field="quantity">Quantity</vn-th>
|
||||||
<vn-th field="description" style="text-align: center">Description</vn-th>
|
<vn-th field="description" style="text-align: center">Description</vn-th>
|
||||||
<vn-th field="size">Size</vn-th>
|
<vn-th field="size">Size</vn-th>
|
||||||
<vn-th field="tags" style="text-align: center">Tags</vn-th>
|
<vn-th field="name" style="text-align: center">Tags</vn-th>
|
||||||
<vn-th field="type">Type</vn-th>
|
<vn-th field="code">Type</vn-th>
|
||||||
<vn-th field="intrastat">Intrastat</vn-th>
|
<vn-th field="intrastat">Intrastat</vn-th>
|
||||||
<vn-th field="origin">Origin</vn-th>
|
<vn-th field="origin">Origin</vn-th>
|
||||||
<vn-th field="density">Density</vn-th>
|
<vn-th field="density">Density</vn-th>
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
</vn-fetched-tags>
|
</vn-fetched-tags>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink title="{{::buy.type}}">
|
<vn-td shrink title="{{::buy.type}}">
|
||||||
{{::buy.type}}
|
{{::buy.code}}
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink title="{{::item.intrastat}}">
|
<vn-td shrink title="{{::item.intrastat}}">
|
||||||
{{::buy.intrastat}}
|
{{::buy.intrastat}}
|
||||||
|
|
|
@ -31,19 +31,19 @@
|
||||||
"state": "entry.index",
|
"state": "entry.index",
|
||||||
"component": "vn-entry-index",
|
"component": "vn-entry-index",
|
||||||
"description": "Entries",
|
"description": "Entries",
|
||||||
"acl": ["buyer"]
|
"acl": ["buyer", "administrative"]
|
||||||
}, {
|
}, {
|
||||||
"url": "/latest-buys?q",
|
"url": "/latest-buys?q",
|
||||||
"state": "entry.latestBuys",
|
"state": "entry.latestBuys",
|
||||||
"component": "vn-entry-latest-buys",
|
"component": "vn-entry-latest-buys",
|
||||||
"description": "Latest buys",
|
"description": "Latest buys",
|
||||||
"acl": ["buyer"]
|
"acl": ["buyer", "administrative"]
|
||||||
}, {
|
}, {
|
||||||
"url": "/create?supplierFk&travelFk&companyFk",
|
"url": "/create?supplierFk&travelFk&companyFk",
|
||||||
"state": "entry.create",
|
"state": "entry.create",
|
||||||
"component": "vn-entry-create",
|
"component": "vn-entry-create",
|
||||||
"description": "New entry",
|
"description": "New entry",
|
||||||
"acl": ["buyer"]
|
"acl": ["buyer", "administrative"]
|
||||||
}, {
|
}, {
|
||||||
"url": "/:id",
|
"url": "/:id",
|
||||||
"state": "entry.card",
|
"state": "entry.card",
|
||||||
|
|
|
@ -41,18 +41,13 @@ module.exports = Self => {
|
||||||
async function download() {
|
async function download() {
|
||||||
const image = await Self.findOne({
|
const image = await Self.findOne({
|
||||||
where: {url: {neq: null}, attempts: {lt: maxAttempts}},
|
where: {url: {neq: null}, attempts: {lt: maxAttempts}},
|
||||||
order: 'attempts, updated'
|
order: 'priority, attempts, updated'
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!image) return;
|
if (!image) return;
|
||||||
|
|
||||||
const srcFile = image.url.split('/').pop();
|
const srcFile = image.url;
|
||||||
const dotIndex = srcFile.lastIndexOf('.');
|
const fileName = srcFile.replace(/\.|\/|:|\?|\\|=|%/g, '');
|
||||||
|
|
||||||
let fileName = srcFile.substring(0, dotIndex);
|
|
||||||
if (dotIndex == -1)
|
|
||||||
fileName = srcFile;
|
|
||||||
|
|
||||||
const file = `${fileName}.png`;
|
const file = `${fileName}.png`;
|
||||||
const filePath = path.join(tempPath, file);
|
const filePath = path.join(tempPath, file);
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,10 @@ module.exports = Self => {
|
||||||
arg: 'description',
|
arg: 'description',
|
||||||
type: 'String',
|
type: 'String',
|
||||||
description: 'The item description',
|
description: 'The item description',
|
||||||
|
}, {
|
||||||
|
arg: 'stemMultiplier',
|
||||||
|
type: 'Integer',
|
||||||
|
description: 'The item multiplier',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
|
@ -80,16 +84,22 @@ module.exports = Self => {
|
||||||
: {or: [{'i.name': {like: `%${value}%`}}, codeWhere]};
|
: {or: [{'i.name': {like: `%${value}%`}}, codeWhere]};
|
||||||
case 'id':
|
case 'id':
|
||||||
return {'i.id': value};
|
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':
|
case 'isActive':
|
||||||
return {'i.isActive': value};
|
return {'i.isActive': value};
|
||||||
|
case 'multiplier':
|
||||||
|
return {'i.stemMultiplier': value};
|
||||||
|
case 'typeFk':
|
||||||
|
return {'i.typeFk': value};
|
||||||
|
case 'category':
|
||||||
|
return {'ic.name': value};
|
||||||
|
case 'salesPersonFk':
|
||||||
|
return {'it.workerFk': value};
|
||||||
|
case 'origin':
|
||||||
|
return {'ori.code': value};
|
||||||
|
case 'niche':
|
||||||
|
return {'ip.code': value};
|
||||||
|
case 'intrastat':
|
||||||
|
return {'intr.description': value};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
filter = mergeFilters(filter, {where});
|
filter = mergeFilters(filter, {where});
|
||||||
|
@ -98,7 +108,8 @@ module.exports = Self => {
|
||||||
let stmt;
|
let stmt;
|
||||||
|
|
||||||
stmt = new ParameterizedSQL(
|
stmt = new ParameterizedSQL(
|
||||||
`SELECT i.id,
|
`SELECT
|
||||||
|
i.id,
|
||||||
i.image,
|
i.image,
|
||||||
i.name,
|
i.name,
|
||||||
i.description,
|
i.description,
|
||||||
|
@ -111,29 +122,30 @@ module.exports = Self => {
|
||||||
i.tag10, i.value10,
|
i.tag10, i.value10,
|
||||||
i.subName,
|
i.subName,
|
||||||
i.isActive,
|
i.isActive,
|
||||||
t.name type,
|
|
||||||
t.workerFk buyerFk,
|
|
||||||
u.name userName,
|
|
||||||
intr.description AS intrastat,
|
|
||||||
i.stems,
|
i.stems,
|
||||||
ori.code AS origin,
|
|
||||||
ic.name AS category,
|
|
||||||
i.density,
|
i.density,
|
||||||
i.stemMultiplier,
|
i.stemMultiplier,
|
||||||
|
i.typeFk,
|
||||||
|
it.name AS typeName,
|
||||||
|
it.workerFk AS buyerFk,
|
||||||
|
u.name AS userName,
|
||||||
|
ori.code AS origin,
|
||||||
|
ic.name AS category,
|
||||||
|
intr.description AS intrastat,
|
||||||
b.grouping,
|
b.grouping,
|
||||||
b.packing,
|
b.packing,
|
||||||
itn.code AS niche, @visibleCalc
|
ip.code AS niche, @visibleCalc
|
||||||
FROM item i
|
FROM item i
|
||||||
LEFT JOIN itemType t ON t.id = i.typeFk
|
LEFT JOIN itemType it ON it.id = i.typeFk
|
||||||
LEFT JOIN itemCategory ic ON ic.id = t.categoryFk
|
LEFT JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||||
LEFT JOIN worker w ON w.id = t.workerFk
|
LEFT JOIN worker w ON w.id = it.workerFk
|
||||||
LEFT JOIN account.user u ON u.id = w.userFk
|
LEFT JOIN account.user u ON u.id = w.userFk
|
||||||
LEFT JOIN intrastat intr ON intr.id = i.intrastatFk
|
LEFT JOIN intrastat intr ON intr.id = i.intrastatFk
|
||||||
LEFT JOIN producer pr ON pr.id = i.producerFk
|
LEFT JOIN producer pr ON pr.id = i.producerFk
|
||||||
LEFT JOIN origin ori ON ori.id = i.originFk
|
LEFT JOIN origin ori ON ori.id = i.originFk
|
||||||
LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = t.warehouseFk
|
LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = it.warehouseFk
|
||||||
LEFT JOIN vn.buy b ON b.id = lb.buy_id
|
LEFT JOIN vn.buy b ON b.id = lb.buy_id
|
||||||
LEFT JOIN itemPlacement itn ON itn.itemFk = i.id AND itn.warehouseFk = t.warehouseFk`
|
LEFT JOIN itemPlacement ip ON ip.itemFk = i.id AND ip.warehouseFk = it.warehouseFk`
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ctx.args.tags) {
|
if (ctx.args.tags) {
|
||||||
|
|
|
@ -20,8 +20,12 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getBalance = async filter => {
|
Self.getBalance = async filter => {
|
||||||
let where = filter.where;
|
const where = filter.where;
|
||||||
let [diary] = await Self.rawSql(`CALL vn.item_getBalance(?, ?)`, [where.itemFk, where.warehouseFk]);
|
let [diary] = await Self.rawSql(`CALL vn.item_getBalance(?, ?)`, [where.itemFk, where.warehouseFk]);
|
||||||
|
|
||||||
|
for (const entry of diary)
|
||||||
|
if (entry.clientType === 'loses') entry.highlighted = true;
|
||||||
|
|
||||||
return diary;
|
return diary;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
|
describe('item getBalance()', () => {
|
||||||
|
it('should return the balance lines of a client type loses in which one has highlighted true', async() => {
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: 9},
|
||||||
|
};
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
|
||||||
|
const losesClientId = 111;
|
||||||
|
const ticket = await app.models.Ticket.findById(7);
|
||||||
|
const originalClientId = ticket.clientFk;
|
||||||
|
await ticket.updateAttribute('clientFk', losesClientId);
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
where: {
|
||||||
|
itemFk: 1,
|
||||||
|
warehouseFk: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const results = await app.models.Item.getBalance(filter);
|
||||||
|
|
||||||
|
const result = results.find(element => element.clientType == 'loses');
|
||||||
|
|
||||||
|
expect(result.highlighted).toBe(true);
|
||||||
|
|
||||||
|
// restores
|
||||||
|
await ticket.updateAttribute('clientFk', originalClientId);
|
||||||
|
});
|
||||||
|
});
|
|
@ -113,6 +113,12 @@
|
||||||
ng-model="$ctrl.item.stems"
|
ng-model="$ctrl.item.stems"
|
||||||
rule>
|
rule>
|
||||||
</vn-input-number>
|
</vn-input-number>
|
||||||
|
<vn-input-number
|
||||||
|
vn-one
|
||||||
|
min="0"
|
||||||
|
label="Multiplier"
|
||||||
|
ng-model="$ctrl.item.stemMultiplier">
|
||||||
|
</vn-input-number>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-input-number
|
<vn-input-number
|
||||||
|
|
|
@ -9,4 +9,5 @@ Price in kg: Precio en kg
|
||||||
New intrastat: Nuevo intrastat
|
New intrastat: Nuevo intrastat
|
||||||
Identifier: Identificador
|
Identifier: Identificador
|
||||||
Fragile: Frágil
|
Fragile: Frágil
|
||||||
Is shown at website, app that this item cannot travel (wreath, palms, ...): Se muestra en la web, app que este artículo no puede viajar (coronas, palmas, ...)
|
Is shown at website, app that this item cannot travel (wreath, palms, ...): Se muestra en la web, app que este artículo no puede viajar (coronas, palmas, ...)
|
||||||
|
Multiplier: Multiplicador
|
|
@ -64,14 +64,16 @@
|
||||||
<vn-td>{{::sale.stateName | dashIfEmpty}}</vn-td>
|
<vn-td>{{::sale.stateName | dashIfEmpty}}</vn-td>
|
||||||
<vn-td>{{::sale.reference | dashIfEmpty}}</vn-td>
|
<vn-td>{{::sale.reference | dashIfEmpty}}</vn-td>
|
||||||
<vn-td class="truncate" expand>
|
<vn-td class="truncate" expand>
|
||||||
<span ng-if="::!sale.isTicket">
|
<span ng-class="::{'warning chip': sale.highlighted}">
|
||||||
{{::sale.name | dashIfEmpty}}
|
<span ng-if="::!sale.isTicket">
|
||||||
</span>
|
{{::sale.name | dashIfEmpty}}
|
||||||
<span
|
</span>
|
||||||
ng-if="::sale.isTicket"
|
<span
|
||||||
vn-click-stop="clientDescriptor.show($event, sale.clientFk)"
|
ng-if="::sale.isTicket"
|
||||||
class="link">
|
vn-click-stop="clientDescriptor.show($event, sale.clientFk)"
|
||||||
{{::sale.name | dashIfEmpty}}
|
class="link">
|
||||||
|
{{::sale.name | dashIfEmpty}}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td number class="in">{{::sale.in | dashIfEmpty}}</vn-td>
|
<vn-td number class="in">{{::sale.in | dashIfEmpty}}</vn-td>
|
||||||
|
|
|
@ -5,107 +5,107 @@
|
||||||
model="model"
|
model="model"
|
||||||
class="vn-w-xl vn-mb-xl">
|
class="vn-w-xl vn-mb-xl">
|
||||||
<vn-card>
|
<vn-card>
|
||||||
<vn-table
|
<vn-table
|
||||||
model="model"
|
model="model"
|
||||||
show-fields="$ctrl.showFields"
|
show-fields="$ctrl.showFields"
|
||||||
vn-smart-table="itemIndex">
|
vn-smart-table="itemIndex">
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th shrink></vn-th>
|
<vn-th shrink></vn-th>
|
||||||
<vn-th field="id" shrink>Id</vn-th>
|
<vn-th field="id" shrink>Id</vn-th>
|
||||||
<vn-th field="grouping" shrink>Grouping</vn-th>
|
<vn-th field="grouping" shrink>Grouping</vn-th>
|
||||||
<vn-th field="packing" shrink>Packing</vn-th>
|
<vn-th field="packing" shrink>Packing</vn-th>
|
||||||
<vn-th field="description">Description</vn-th>
|
<vn-th field="name">Description</vn-th>
|
||||||
<vn-th field="stems" shrink>Stems</vn-th>
|
<vn-th field="stems" shrink>Stems</vn-th>
|
||||||
<vn-th field="size" shrink>Size</vn-th>
|
<vn-th field="size" shrink>Size</vn-th>
|
||||||
<vn-th field="niche" shrink>Niche</vn-th>
|
<vn-th field="niche" shrink>Niche</vn-th>
|
||||||
<vn-th field="type" shrink>Type</vn-th>
|
<vn-th field="typeFk" shrink>Type</vn-th>
|
||||||
<vn-th field="category" shrink>Category</vn-th>
|
<vn-th field="category" shrink>Category</vn-th>
|
||||||
<vn-th field="intrastat" shrink>Intrastat</vn-th>
|
<vn-th field="intrastat" shrink>Intrastat</vn-th>
|
||||||
<vn-th field="origin" shrink>Origin</vn-th>
|
<vn-th field="origin" shrink>Origin</vn-th>
|
||||||
<vn-th field="salesperson" shrink>Buyer</vn-th>
|
<vn-th field="salesperson" shrink>Buyer</vn-th>
|
||||||
<vn-th field="density" shrink>Density</vn-th>
|
<vn-th field="density" shrink>Density</vn-th>
|
||||||
<vn-th field="stemMultiplier" shrink>Multiplier</vn-th>
|
<vn-th field="stemMultiplier" shrink>Multiplier</vn-th>
|
||||||
<vn-th field="active" shrink>Active</vn-th>
|
<vn-th field="active" shrink>Active</vn-th>
|
||||||
<vn-th></vn-th>
|
<vn-th></vn-th>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
<vn-tbody>
|
<vn-tbody>
|
||||||
<a ng-repeat="item in model.data"
|
<a ng-repeat="item in model.data"
|
||||||
class="clickable vn-tr search-result"
|
class="clickable vn-tr search-result"
|
||||||
ui-sref="item.card.summary({id: item.id})">
|
ui-sref="item.card.summary({id: item.id})">
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<img
|
<img
|
||||||
ng-src="{{::$root.imagePath('catalog', '50x50', item.id)}}"
|
ng-src="{{::$root.imagePath('catalog', '50x50', item.id)}}"
|
||||||
zoom-image="{{::$root.imagePath('catalog', '1600x900', item.id)}}"
|
zoom-image="{{::$root.imagePath('catalog', '1600x900', item.id)}}"
|
||||||
vn-click-stop
|
vn-click-stop
|
||||||
on-error-src/>
|
on-error-src/>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<span
|
<span
|
||||||
vn-click-stop="itemDescriptor.show($event, item.id)"
|
vn-click-stop="itemDescriptor.show($event, item.id)"
|
||||||
class="link">
|
class="link">
|
||||||
{{::item.id}}
|
{{::item.id}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>{{::item.grouping | dashIfEmpty}}</vn-td>
|
<vn-td shrink>{{::item.grouping | dashIfEmpty}}</vn-td>
|
||||||
<vn-td shrink>{{::item.packing | dashIfEmpty}}</vn-td>
|
<vn-td shrink>{{::item.packing | dashIfEmpty}}</vn-td>
|
||||||
<vn-td vn-fetched-tags>
|
<vn-td vn-fetched-tags>
|
||||||
<vn-one title="{{::item.name}}">{{::item.name}}</vn-one>
|
<vn-one title="{{::item.name}}">{{::item.name}}</vn-one>
|
||||||
<vn-one ng-if="::item.subName">
|
<vn-one ng-if="::item.subName">
|
||||||
<h3 title="{{::item.subName}}">{{::item.subName}}</h3>
|
<h3 title="{{::item.subName}}">{{::item.subName}}</h3>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
<vn-fetched-tags
|
<vn-fetched-tags
|
||||||
max-length="6"
|
max-length="6"
|
||||||
item="item"
|
item="item"
|
||||||
tabindex="-1">
|
tabindex="-1">
|
||||||
</vn-fetched-tags>
|
</vn-fetched-tags>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>{{::item.stems}}</vn-td>
|
<vn-td shrink>{{::item.stems}}</vn-td>
|
||||||
<vn-td shrink>{{::item.size}}</vn-td>
|
<vn-td shrink>{{::item.size}}</vn-td>
|
||||||
<vn-td shrink>{{::item.niche}}</vn-td>
|
<vn-td shrink>{{::item.niche}}</vn-td>
|
||||||
<vn-td shrink title="{{::item.type}}">
|
<vn-td shrink title="{{::item.typeName}}">
|
||||||
{{::item.type}}
|
{{::item.typeName}}
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink title="{{::item.category}}">
|
<vn-td shrink title="{{::item.category}}">
|
||||||
{{::item.category}}
|
{{::item.category}}
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink title="{{::item.intrastat}}">
|
<vn-td shrink title="{{::item.intrastat}}">
|
||||||
{{::item.intrastat}}
|
{{::item.intrastat}}
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>{{::item.origin}}</vn-td>
|
<vn-td shrink>{{::item.origin}}</vn-td>
|
||||||
<vn-td shrink title="{{::item.userName}}">
|
<vn-td shrink title="{{::item.userName}}">
|
||||||
<span
|
<span
|
||||||
class="link"
|
class="link"
|
||||||
vn-click-stop="workerDescriptor.show($event, item.buyerFk)">
|
vn-click-stop="workerDescriptor.show($event, item.buyerFk)">
|
||||||
{{::item.userName}}
|
{{::item.userName}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>{{::item.density}}</vn-td>
|
<vn-td shrink>{{::item.density}}</vn-td>
|
||||||
<vn-td shrink >{{::item.stemMultiplier}}</vn-td>
|
<vn-td shrink >{{::item.stemMultiplier}}</vn-td>
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<vn-check
|
<vn-check
|
||||||
disabled="true"
|
disabled="true"
|
||||||
ng-model="::item.isActive">
|
ng-model="::item.isActive">
|
||||||
</vn-check>
|
</vn-check>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td shrink>
|
<vn-td shrink>
|
||||||
<vn-horizontal class="buttons">
|
<vn-horizontal class="buttons">
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
vn-click-stop="clone.show(item.id)"
|
vn-click-stop="clone.show(item.id)"
|
||||||
vn-tooltip="Clone"
|
vn-tooltip="Clone"
|
||||||
icon="icon-clone">
|
icon="icon-clone">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
vn-click-stop="$ctrl.preview(item)"
|
vn-click-stop="$ctrl.preview(item)"
|
||||||
vn-tooltip="Preview"
|
vn-tooltip="Preview"
|
||||||
icon="preview">
|
icon="preview">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
</a>
|
</a>
|
||||||
</vn-tbody>
|
</vn-tbody>
|
||||||
</vn-table>
|
</vn-table>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
</vn-data-viewer>
|
</vn-data-viewer>
|
||||||
<a ui-sref="item.create" vn-tooltip="New item" vn-bind="+" fixed-bottom-right>
|
<a ui-sref="item.create" vn-tooltip="New item" vn-bind="+" fixed-bottom-right>
|
||||||
|
@ -127,4 +127,31 @@
|
||||||
<vn-item-summary
|
<vn-item-summary
|
||||||
item="$ctrl.itemSelected">
|
item="$ctrl.itemSelected">
|
||||||
</vn-item-summary>
|
</vn-item-summary>
|
||||||
</vn-popup>
|
</vn-popup>
|
||||||
|
<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>
|
|
@ -11,6 +11,36 @@ class Controller extends Section {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exprBuilder(param, value) {
|
||||||
|
switch (param) {
|
||||||
|
case 'category':
|
||||||
|
return {'ic.name': value};
|
||||||
|
case 'salesPersonFk':
|
||||||
|
return {'it.workerFk': value};
|
||||||
|
case 'grouping':
|
||||||
|
return {'b.grouping': value};
|
||||||
|
case 'packing':
|
||||||
|
return {'b.packing': value};
|
||||||
|
case 'origin':
|
||||||
|
return {'ori.code': value};
|
||||||
|
case 'niche':
|
||||||
|
return {'ip.code': value};
|
||||||
|
case 'typeFk':
|
||||||
|
return {'i.typeFk': value};
|
||||||
|
case 'intrastat':
|
||||||
|
return {'intr.description': value};
|
||||||
|
case 'id':
|
||||||
|
case 'size':
|
||||||
|
case 'name':
|
||||||
|
case 'subname':
|
||||||
|
case 'isActive':
|
||||||
|
case 'density':
|
||||||
|
case 'stemMultiplier':
|
||||||
|
case 'stems':
|
||||||
|
return {[`i.${param}`]: value};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onCloneAccept(itemFk) {
|
onCloneAccept(itemFk) {
|
||||||
return this.$http.post(`Items/${itemFk}/clone`)
|
return this.$http.post(`Items/${itemFk}/clone`)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="search-panel">
|
<div class="search-panel">
|
||||||
<form class="vn-pa-lg" ng-submit="$ctrl.onSearch()">
|
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||||
<vn-horizontal>
|
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
vn-one
|
vn-one
|
||||||
label="General search"
|
label="General search"
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
vn-focus>
|
vn-focus>
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal class="vn-px-lg">
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
vn-one
|
vn-one
|
||||||
label="Ticket id"
|
label="Ticket id"
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
<tpl-item>{{nickname}}</tpl-item>
|
<tpl-item>{{nickname}}</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal class="vn-px-lg">
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
vn-one
|
vn-one
|
||||||
label="Client id"
|
label="Client id"
|
||||||
|
@ -38,19 +38,37 @@
|
||||||
url="Warehouses">
|
url="Warehouses">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<section class="vn-px-md">
|
||||||
|
<vn-horizontal class="manifold-panel vn-pa-md">
|
||||||
<vn-date-picker
|
<vn-date-picker
|
||||||
vn-one
|
vn-one
|
||||||
label="From"
|
label="From"
|
||||||
ng-model="filter.from">
|
ng-model="filter.from"
|
||||||
|
on-change="$ctrl.from = value">
|
||||||
</vn-date-picker>
|
</vn-date-picker>
|
||||||
<vn-date-picker
|
<vn-date-picker
|
||||||
vn-one
|
vn-one
|
||||||
label="To"
|
label="To"
|
||||||
ng-model="filter.to">
|
ng-model="filter.to"
|
||||||
|
on-change="$ctrl.to = value">
|
||||||
</vn-date-picker>
|
</vn-date-picker>
|
||||||
|
<vn-none class="or vn-px-md" translate>Or</vn-none>
|
||||||
|
<vn-input-number
|
||||||
|
vn-one
|
||||||
|
min="0"
|
||||||
|
step="1"
|
||||||
|
label="Days onward"
|
||||||
|
ng-model="filter.scopeDays"
|
||||||
|
on-change="$ctrl.scopeDays = value"
|
||||||
|
display-controls="true">
|
||||||
|
</vn-input-number>
|
||||||
|
<vn-icon color-marginal
|
||||||
|
icon="info"
|
||||||
|
vn-tooltip="Cannot choose a range of dates and days onward at the same time">
|
||||||
|
</vn-icon>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
</section>
|
||||||
|
<vn-horizontal class="vn-px-lg">
|
||||||
<vn-check vn-one
|
<vn-check vn-one
|
||||||
triple-state="true"
|
triple-state="true"
|
||||||
label="For me"
|
label="For me"
|
||||||
|
@ -65,7 +83,7 @@
|
||||||
<tpl-item>{{name}}</tpl-item>
|
<tpl-item>{{name}}</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal class="vn-mt-lg">
|
<vn-horizontal class="vn-px-lg vn-pb-lg vn-mt-lg">
|
||||||
<vn-submit label="Search"></vn-submit>
|
<vn-submit label="Search"></vn-submit>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -11,6 +11,35 @@ class Controller extends SearchPanel {
|
||||||
{code: 'denied', name: this.$t('Denied')}
|
{code: 'denied', name: this.$t('Denied')}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get from() {
|
||||||
|
return this._from;
|
||||||
|
}
|
||||||
|
|
||||||
|
set from(value) {
|
||||||
|
this._from = value;
|
||||||
|
this.filter.scopeDays = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get to() {
|
||||||
|
return this._to;
|
||||||
|
}
|
||||||
|
|
||||||
|
set to(value) {
|
||||||
|
this._to = value;
|
||||||
|
this.filter.scopeDays = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get scopeDays() {
|
||||||
|
return this._scopeDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
set scopeDays(value) {
|
||||||
|
this._scopeDays = value;
|
||||||
|
|
||||||
|
this.filter.from = null;
|
||||||
|
this.filter.to = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnRequestSearchPanel', {
|
ngModule.vnComponent('vnRequestSearchPanel', {
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import './index';
|
||||||
|
|
||||||
|
describe(' Component vnRequestSearchPanel', () => {
|
||||||
|
let controller;
|
||||||
|
|
||||||
|
beforeEach(ngModule('item'));
|
||||||
|
|
||||||
|
beforeEach(inject($componentController => {
|
||||||
|
controller = $componentController('vnRequestSearchPanel', {$element: null});
|
||||||
|
controller.$t = () => {};
|
||||||
|
controller.filter = {};
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('from() setter', () => {
|
||||||
|
it('should clear the scope days when setting the from property', () => {
|
||||||
|
controller.filter.scopeDays = 1;
|
||||||
|
|
||||||
|
controller.from = new Date();
|
||||||
|
|
||||||
|
expect(controller.filter.scopeDays).toBeNull();
|
||||||
|
expect(controller.from).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('to() setter', () => {
|
||||||
|
it('should clear the scope days when setting the to property', () => {
|
||||||
|
controller.filter.scopeDays = 1;
|
||||||
|
|
||||||
|
controller.to = new Date();
|
||||||
|
|
||||||
|
expect(controller.filter.scopeDays).toBeNull();
|
||||||
|
expect(controller.to).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('scopeDays() setter', () => {
|
||||||
|
it('should clear the date range when setting the scopeDays property', () => {
|
||||||
|
controller.filter.from = new Date();
|
||||||
|
controller.filter.to = new Date();
|
||||||
|
|
||||||
|
controller.scopeDays = 1;
|
||||||
|
|
||||||
|
expect(controller.filter.from).toBeNull();
|
||||||
|
expect(controller.filter.to).toBeNull();
|
||||||
|
expect(controller.scopeDays).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -10,9 +10,10 @@
|
||||||
<vn-portal slot="topbar">
|
<vn-portal slot="topbar">
|
||||||
<vn-searchbar
|
<vn-searchbar
|
||||||
panel="vn-request-search-panel"
|
panel="vn-request-search-panel"
|
||||||
suggested-filter="$ctrl.filterParams"
|
|
||||||
info="Search request by id or alias"
|
info="Search request by id or alias"
|
||||||
|
suggested-filter="$ctrl.filterParams"
|
||||||
filter="$ctrl.filterParams"
|
filter="$ctrl.filterParams"
|
||||||
|
fetch-params="$ctrl.fetchParams($params)"
|
||||||
model="model"
|
model="model"
|
||||||
auto-state="false">
|
auto-state="false">
|
||||||
</vn-searchbar>
|
</vn-searchbar>
|
||||||
|
|
|
@ -15,7 +15,6 @@ export default class Controller extends Section {
|
||||||
nextWeek.setDate(nextWeek.getDate() + 7);
|
nextWeek.setDate(nextWeek.getDate() + 7);
|
||||||
|
|
||||||
this.filterParams = {
|
this.filterParams = {
|
||||||
mine: true,
|
|
||||||
from: today,
|
from: today,
|
||||||
to: nextWeek,
|
to: nextWeek,
|
||||||
state: 'pending'
|
state: 'pending'
|
||||||
|
@ -23,6 +22,24 @@ export default class Controller extends Section {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
const to = new Date(from.getTime());
|
||||||
|
to.setDate(to.getDate() + $params.scopeDays);
|
||||||
|
to.setHours(23, 59, 59, 999);
|
||||||
|
|
||||||
|
Object.assign($params, {from, to});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
getState(isOk) {
|
getState(isOk) {
|
||||||
if (isOk === null)
|
if (isOk === null)
|
||||||
return 'Pending';
|
return 'Pending';
|
||||||
|
|
|
@ -162,7 +162,7 @@
|
||||||
"acl": ["buyer"]
|
"acl": ["buyer"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url" : "/fixed-price",
|
"url" : "/fixed-price?q",
|
||||||
"state": "item.fixedPrice",
|
"state": "item.fixedPrice",
|
||||||
"component": "vn-fixed-price",
|
"component": "vn-fixed-price",
|
||||||
"description": "Fixed prices",
|
"description": "Fixed prices",
|
||||||
|
|
|
@ -55,6 +55,9 @@
|
||||||
<vn-label-value label="stems"
|
<vn-label-value label="stems"
|
||||||
value="{{$ctrl.summary.item.stems}}">
|
value="{{$ctrl.summary.item.stems}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
|
<vn-label-value label="Multiplier"
|
||||||
|
value="{{$ctrl.summary.item.stemMultiplier}}">
|
||||||
|
</vn-label-value>
|
||||||
<vn-label-value label="Buyer">
|
<vn-label-value label="Buyer">
|
||||||
<span
|
<span
|
||||||
ng-click="workerDescriptor.show($event, $ctrl.summary.item.itemType.worker.userFk)"
|
ng-click="workerDescriptor.show($event, $ctrl.summary.item.itemType.worker.userFk)"
|
||||||
|
|
|
@ -32,14 +32,14 @@
|
||||||
rule>
|
rule>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-textfield vn-three
|
<vn-textfield vn-three
|
||||||
ng-show="tag.selection.isFree || tag.selection.isFree == undefined"
|
ng-if="tag.selection.isFree || tag.selection.isFree == undefined"
|
||||||
vn-id="text"
|
vn-id="text"
|
||||||
label="Value"
|
label="Value"
|
||||||
ng-model="itemTag.value"
|
ng-model="itemTag.value"
|
||||||
rule>
|
rule>
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
<vn-autocomplete vn-three
|
<vn-autocomplete vn-three
|
||||||
ng-show="tag.selection.isFree === false"
|
ng-if="tag.selection.isFree === false"
|
||||||
url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}"
|
url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}"
|
||||||
search-function="{value: $search}"
|
search-function="{value: $search}"
|
||||||
label="Value"
|
label="Value"
|
||||||
|
|
|
@ -37,7 +37,7 @@ class Controller extends Component {
|
||||||
};
|
};
|
||||||
filter = encodeURIComponent(JSON.stringify(filter));
|
filter = encodeURIComponent(JSON.stringify(filter));
|
||||||
let query = `Clients?filter=${filter}`;
|
let query = `Clients?filter=${filter}`;
|
||||||
this.$http.get(query).then(res => {
|
this.$http.get(query).then(res=> {
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
let client = res.data[0];
|
let client = res.data[0];
|
||||||
let defaultAddress = client.defaultAddress;
|
let defaultAddress = client.defaultAddress;
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
{
|
{
|
||||||
"name": "SupplierAccount",
|
"name": "SupplierAccount",
|
||||||
"base": "VnModel",
|
"base": "Loggable",
|
||||||
|
"log": {
|
||||||
|
"model":"SupplierLog",
|
||||||
|
"relation": "supplier"
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "supplierAccount"
|
"table": "supplierAccount"
|
||||||
|
@ -45,6 +49,11 @@
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Supplier",
|
"model": "Supplier",
|
||||||
"foreignKey": "supplierFk"
|
"foreignKey": "supplierFk"
|
||||||
|
},
|
||||||
|
"bankEntity": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "BankEntity",
|
||||||
|
"foreignKey": "bankEntityFk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
<vn-crud-model
|
||||||
|
vn-id="model"
|
||||||
|
url="SupplierAccounts"
|
||||||
|
fields="['id', 'supplierFk', 'iban', 'bankEntityFk']"
|
||||||
|
link="{supplierFk: $ctrl.$params.id}"
|
||||||
|
include="$ctrl.include"
|
||||||
|
data="$ctrl.supplierAccounts"
|
||||||
|
auto-load="true">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-watcher
|
||||||
|
vn-id="watcher"
|
||||||
|
data="$ctrl.supplierAccounts"
|
||||||
|
form="form">
|
||||||
|
</vn-watcher>
|
||||||
|
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
||||||
|
<vn-card class="vn-pa-lg">
|
||||||
|
<vn-horizontal ng-repeat="supplierAccount in $ctrl.supplierAccounts">
|
||||||
|
<vn-textfield vn-three
|
||||||
|
ng-show="supplierAccount.iban || supplierAccount.iban == undefined"
|
||||||
|
label="Iban"
|
||||||
|
ng-model="supplierAccount.iban"
|
||||||
|
rule>
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-autocomplete vn-two
|
||||||
|
label="Bank entity"
|
||||||
|
ng-model="supplierAccount.bankEntityFk"
|
||||||
|
url="BankEntities"
|
||||||
|
show-field="name"
|
||||||
|
rule>
|
||||||
|
</vn-autocomplete>
|
||||||
|
<append>
|
||||||
|
<vn-icon-button
|
||||||
|
icon="add_circle"
|
||||||
|
vn-tooltip="New bank entity"
|
||||||
|
ng-click="$ctrl.showBankEntity($event, $index)">
|
||||||
|
</vn-icon-button>
|
||||||
|
</append>
|
||||||
|
<vn-none>
|
||||||
|
<vn-icon-button
|
||||||
|
vn-tooltip="Remove account"
|
||||||
|
icon="delete"
|
||||||
|
ng-click="model.remove($index)"
|
||||||
|
tabindex="-1">
|
||||||
|
</vn-icon-button>
|
||||||
|
</vn-none>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-one>
|
||||||
|
<vn-icon-button
|
||||||
|
vn-bind="+"
|
||||||
|
vn-tooltip="Add account"
|
||||||
|
icon="add_circle"
|
||||||
|
ng-click="$ctrl.add()">
|
||||||
|
</vn-icon-button>
|
||||||
|
</vn-one>
|
||||||
|
</vn-card>
|
||||||
|
<vn-button-bar>
|
||||||
|
<vn-submit
|
||||||
|
disabled="!watcher.dataChanged()"
|
||||||
|
label="Save">
|
||||||
|
</vn-submit>
|
||||||
|
</vn-button-bar>
|
||||||
|
</form>
|
||||||
|
<!-- New bankentity dialog -->
|
||||||
|
<vn-new-bank-entity
|
||||||
|
vn-id="bankEntity"
|
||||||
|
on-response="$ctrl.onResponse($response)">
|
||||||
|
</vn-new-bank-entity>
|
|
@ -0,0 +1,56 @@
|
||||||
|
import ngModule from '../module';
|
||||||
|
import Section from 'salix/components/section';
|
||||||
|
|
||||||
|
class Controller extends Section {
|
||||||
|
constructor($element, $) {
|
||||||
|
super($element, $);
|
||||||
|
this.include = {
|
||||||
|
relation: 'bankEntity',
|
||||||
|
scope: {
|
||||||
|
fields: ['countryFk', 'id', 'name', 'bic']
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
add() {
|
||||||
|
this.$.model.insert({
|
||||||
|
supplierFk: this.$params.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onResponse(response) {
|
||||||
|
const data = this.$.model.data;
|
||||||
|
const supplierAccount = data[this.currentRowIndex];
|
||||||
|
supplierAccount.bankEntityFk = response.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
showBankEntity(event, $index) {
|
||||||
|
if (event.defaultPrevented) return;
|
||||||
|
event.preventDefault();
|
||||||
|
this.currentRowIndex = $index;
|
||||||
|
this.$.bankEntity.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
onBankEntityAccept() {
|
||||||
|
const query = `SupplierAccounts/${this.$params.id}/createBankEntity`;
|
||||||
|
return this.$http.patch(query, this.newBankEntity)
|
||||||
|
.then(res => this.supplierAccount.bankEntityFk = res.data.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
this.$.watcher.check();
|
||||||
|
this.$.model.save().then(() => {
|
||||||
|
this.$.watcher.notifySaved();
|
||||||
|
this.$.watcher.updateOriginalData();
|
||||||
|
this.card.reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngModule.vnComponent('vnSupplierAccount', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller,
|
||||||
|
require: {
|
||||||
|
card: '^vnSupplierCard'
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,71 @@
|
||||||
|
import './index.js';
|
||||||
|
|
||||||
|
describe('Supplier Component vnSupplierAccount', () => {
|
||||||
|
let $scope;
|
||||||
|
let $element;
|
||||||
|
let controller;
|
||||||
|
let $httpBackend;
|
||||||
|
beforeEach(ngModule('supplier'));
|
||||||
|
|
||||||
|
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
$scope.bankEntity = {
|
||||||
|
open: () => {}
|
||||||
|
};
|
||||||
|
$element = angular.element('<vn-supplier-accounts></supplier-accounts>');
|
||||||
|
controller = $componentController('vnSupplierAccount', {$element, $scope});
|
||||||
|
controller.supplierAccount = {
|
||||||
|
supplierFk: 442,
|
||||||
|
name: 'Verdnatura'
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('showBankEntity()', () => {
|
||||||
|
it('should do nothing if it default is prevented', () => {
|
||||||
|
const event = {
|
||||||
|
defaultPrevented: true,
|
||||||
|
preventDefault: () => {}
|
||||||
|
};
|
||||||
|
jest.spyOn(event, 'preventDefault');
|
||||||
|
jest.spyOn(controller.$.bankEntity, 'open');
|
||||||
|
|
||||||
|
controller.showBankEntity(event);
|
||||||
|
|
||||||
|
expect(event.preventDefault).not.toHaveBeenCalledWith();
|
||||||
|
expect(controller.$.bankEntity.open).not.toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call preventDefault() and open() when the default is not prevented', () => {
|
||||||
|
const event = {
|
||||||
|
defaultPrevented: false,
|
||||||
|
preventDefault: () => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(event, 'preventDefault');
|
||||||
|
jest.spyOn(controller.$.bankEntity, 'open');
|
||||||
|
|
||||||
|
controller.showBankEntity(event);
|
||||||
|
|
||||||
|
expect(event.preventDefault).toHaveBeenCalledWith();
|
||||||
|
expect(controller.$.bankEntity.open).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should request to create a new bank entity', () => {
|
||||||
|
controller.bankEntity = {
|
||||||
|
name: 'My new bank entity',
|
||||||
|
bic: 'ES1234',
|
||||||
|
countryFk: 1,
|
||||||
|
id: 2200
|
||||||
|
};
|
||||||
|
|
||||||
|
const query = `SupplierAccounts/${controller.$.bankEntity.id}/createBankEntity`;
|
||||||
|
$httpBackend.expectPATCH(query).respond({id: 2200});
|
||||||
|
controller.onBankEntityAccept();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.supplierAccount.bankEntityFk).toEqual(controller.bankEntity.id);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Bank entity: Entidad bancaria
|
||||||
|
swift: Swift BIC
|
||||||
|
Add account: Añadir cuenta
|
|
@ -9,6 +9,7 @@ import './search-panel';
|
||||||
import './summary';
|
import './summary';
|
||||||
import './basic-data';
|
import './basic-data';
|
||||||
import './fiscal-data';
|
import './fiscal-data';
|
||||||
|
import './account';
|
||||||
import './contact';
|
import './contact';
|
||||||
import './log';
|
import './log';
|
||||||
import './consumption';
|
import './consumption';
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
{"state": "supplier.index", "icon": "icon-supplier"}
|
{"state": "supplier.index", "icon": "icon-supplier"}
|
||||||
],
|
],
|
||||||
"card": [
|
"card": [
|
||||||
|
{"state": "supplier.card.account", "icon": "contact_support"},
|
||||||
{"state": "supplier.card.basicData", "icon": "settings"},
|
{"state": "supplier.card.basicData", "icon": "settings"},
|
||||||
{"state": "supplier.card.fiscalData", "icon": "account_balance"},
|
{"state": "supplier.card.fiscalData", "icon": "account_balance"},
|
||||||
{"state": "supplier.card.billingData", "icon": "icon-payment"},
|
{"state": "supplier.card.billingData", "icon": "icon-payment"},
|
||||||
|
@ -99,6 +100,15 @@
|
||||||
"supplier": "$ctrl.supplier"
|
"supplier": "$ctrl.supplier"
|
||||||
},
|
},
|
||||||
"acl": ["administrative"]
|
"acl": ["administrative"]
|
||||||
|
},{
|
||||||
|
"url": "/account",
|
||||||
|
"state": "supplier.card.account",
|
||||||
|
"component": "vn-supplier-account",
|
||||||
|
"description": "Account",
|
||||||
|
"params": {
|
||||||
|
"supplier": "$ctrl.supplier"
|
||||||
|
},
|
||||||
|
"acl": ["administrative"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -101,7 +101,7 @@ module.exports = Self => {
|
||||||
if (!shipped && landed) {
|
if (!shipped && landed) {
|
||||||
const shippedResult = await models.Agency.getShipped(landed,
|
const shippedResult = await models.Agency.getShipped(landed,
|
||||||
address.id, agencyModeId, warehouseId);
|
address.id, agencyModeId, warehouseId);
|
||||||
shipped = shippedResult && shippedResult.shipped;
|
shipped = (shippedResult && shippedResult.shipped) || landed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shipped && !landed) {
|
if (shipped && !landed) {
|
||||||
|
|
|
@ -2,12 +2,13 @@ const app = require('vn-loopback/server/server');
|
||||||
let UserError = require('vn-loopback/util/user-error');
|
let UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
describe('ticket new()', () => {
|
describe('ticket new()', () => {
|
||||||
let ticket;
|
let ticketIdsToDelete = [];
|
||||||
let today = new Date();
|
let today = new Date();
|
||||||
let ctx = {req: {accessToken: {userId: 1}}};
|
let ctx = {req: {accessToken: {userId: 1}}};
|
||||||
|
|
||||||
afterAll(async done => {
|
afterAll(async done => {
|
||||||
await app.models.Ticket.destroyById(ticket.id);
|
for (id of ticketIdsToDelete)
|
||||||
|
await app.models.Ticket.destroyById(id);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -28,7 +29,7 @@ describe('ticket new()', () => {
|
||||||
params.shipped,
|
params.shipped,
|
||||||
params.landed,
|
params.landed,
|
||||||
params.warehouseId,
|
params.warehouseId,
|
||||||
params.companyFk,
|
params.companyId,
|
||||||
params.addressId
|
params.addressId
|
||||||
).catch(e => {
|
).catch(e => {
|
||||||
error = e;
|
error = e;
|
||||||
|
@ -53,7 +54,7 @@ describe('ticket new()', () => {
|
||||||
params.shipped,
|
params.shipped,
|
||||||
params.landed,
|
params.landed,
|
||||||
params.warehouseId,
|
params.warehouseId,
|
||||||
params.companyFk,
|
params.companyId,
|
||||||
params.addressId
|
params.addressId
|
||||||
).catch(response => {
|
).catch(response => {
|
||||||
expect(response.message).toEqual(`This address doesn't exist`);
|
expect(response.message).toEqual(`This address doesn't exist`);
|
||||||
|
@ -74,17 +75,44 @@ describe('ticket new()', () => {
|
||||||
agencyModeId: 1
|
agencyModeId: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
ticket = await app.models.Ticket.new(ctx,
|
const ticket = await app.models.Ticket.new(ctx,
|
||||||
params.clientId,
|
params.clientId,
|
||||||
params.shipped,
|
params.shipped,
|
||||||
params.landed,
|
params.landed,
|
||||||
params.warehouseId,
|
params.warehouseId,
|
||||||
params.companyFk,
|
params.companyId,
|
||||||
params.addressId,
|
params.addressId,
|
||||||
params.agencyModeId);
|
params.agencyModeId);
|
||||||
|
|
||||||
let newestTicketIdInFixtures = 21;
|
let newestTicketIdInFixtures = 21;
|
||||||
|
|
||||||
|
ticketIdsToDelete.push(ticket.id);
|
||||||
|
|
||||||
expect(ticket.id).toBeGreaterThan(newestTicketIdInFixtures);
|
expect(ticket.id).toBeGreaterThan(newestTicketIdInFixtures);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return the set a shipped when the agency is not especified', async() => {
|
||||||
|
let params = {
|
||||||
|
clientId: 104,
|
||||||
|
landed: today,
|
||||||
|
shipped: null,
|
||||||
|
warehouseId: 2,
|
||||||
|
companyId: 442,
|
||||||
|
addressId: 4,
|
||||||
|
agencyModeId: null
|
||||||
|
};
|
||||||
|
|
||||||
|
const ticket = await app.models.Ticket.new(ctx,
|
||||||
|
params.clientId,
|
||||||
|
params.shipped,
|
||||||
|
params.landed,
|
||||||
|
params.warehouseId,
|
||||||
|
params.companyId,
|
||||||
|
params.addressId,
|
||||||
|
params.agencyModeId);
|
||||||
|
|
||||||
|
ticketIdsToDelete.push(ticket.id);
|
||||||
|
|
||||||
|
expect(ticket.shipped).toEqual(jasmine.any(Date));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
disabled="!$ctrl.clientId || !$ctrl.landed || !$ctrl.warehouseId"
|
disabled="!$ctrl.clientId || !$ctrl.landed || !$ctrl.warehouseId"
|
||||||
data="$ctrl._availableAgencies"
|
data="$ctrl.agencies"
|
||||||
label="Agency"
|
label="Agency"
|
||||||
show-field="agencyMode"
|
show-field="agencyMode"
|
||||||
value-field="agencyModeFk"
|
value-field="agencyModeFk"
|
||||||
|
|
|
@ -100,9 +100,12 @@ class Controller extends Component {
|
||||||
ticket.agencyModeFk = null;
|
ticket.agencyModeFk = null;
|
||||||
|
|
||||||
this.$http.get(`Agencies/getAgenciesWithWarehouse`, {params}).then(res => {
|
this.$http.get(`Agencies/getAgenciesWithWarehouse`, {params}).then(res => {
|
||||||
this._availableAgencies = res.data;
|
this.agencies = res.data;
|
||||||
|
const defaultAgency = this.agencies.find(agency=> {
|
||||||
this.agencyModeId = this.defaultAddress.agencyModeFk;
|
return agency.agencyModeFk == this.defaultAddress.agencyModeFk;
|
||||||
|
});
|
||||||
|
if (defaultAgency)
|
||||||
|
this.agencyModeId = defaultAgency.agencyModeFk;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,4 +116,7 @@
|
||||||
</vn-button-menu>
|
</vn-button-menu>
|
||||||
</div>
|
</div>
|
||||||
</slot-body>
|
</slot-body>
|
||||||
</vn-descriptor-content>
|
</vn-descriptor-content>
|
||||||
|
<vn-worker-descriptor-popover
|
||||||
|
vn-id="workerDescriptor">
|
||||||
|
</vn-worker-descriptor-popover>
|
|
@ -326,31 +326,49 @@
|
||||||
icon="info">
|
icon="info">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-table class="destinationTable">
|
<table class="destinationTable vn-table">
|
||||||
<vn-thead>
|
<thead>
|
||||||
<vn-tr>
|
<tr>
|
||||||
<vn-th number>Id</vn-th>
|
<th translate shrink>Id</th>
|
||||||
<vn-th number>Shipped</vn-th>
|
<th translate>Shipped</th>
|
||||||
<vn-th number>Agency</vn-th>
|
<th translate shrink>Agency</th>
|
||||||
<vn-th number>Warehouse</vn-th>
|
<th translate expand>Address</th>
|
||||||
<vn-th number>Address</vn-th>
|
</tr>
|
||||||
</vn-tr>
|
</thead>
|
||||||
</vn-thead>
|
<tbody>
|
||||||
<vn-tbody>
|
<tr
|
||||||
<vn-data-viewer data="$ctrl.transfer.lastActiveTickets">
|
|
||||||
</vn-data-viewer>
|
|
||||||
<vn-tr
|
|
||||||
class="clickable"
|
class="clickable"
|
||||||
ng-repeat="ticket in $ctrl.transfer.lastActiveTickets track by ticket.id"
|
ng-repeat="ticket in $ctrl.transfer.lastActiveTickets track by ticket.id"
|
||||||
ng-click="$ctrl.transferSales(ticket.id)">
|
ng-click="$ctrl.transferSales(ticket.id)">
|
||||||
<vn-td number>{{::ticket.id}}</vn-td>
|
<td shrink>{{::ticket.id}}</td>
|
||||||
<vn-td number>{{::ticket.shipped | date: 'dd/MM/yyyy'}}</vn-td>
|
<td>{{::ticket.shipped | date: 'dd/MM/yyyy'}}</td>
|
||||||
<vn-td number>{{::ticket.agencyName}}</vn-td>
|
<td shrink>{{::ticket.agencyName}}</td>
|
||||||
<vn-td number>{{::ticket.warehouseName}}</vn-td>
|
<td expand>{{::ticket.address}}
|
||||||
<vn-td number>{{::ticket.address}}</vn-td>
|
<span vn-tooltip="
|
||||||
</vn-tr>
|
{{::ticket.nickname}}
|
||||||
</vn-tbody>
|
{{::ticket.name}}
|
||||||
</vn-table>
|
{{::ticket.street}}
|
||||||
|
{{::ticket.postalCode}}
|
||||||
|
{{::ticket.city}}">
|
||||||
|
{{::ticket.nickname}}
|
||||||
|
{{::ticket.name}}
|
||||||
|
{{::ticket.street}}
|
||||||
|
{{::ticket.postalCode}}
|
||||||
|
{{::ticket.city}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
ng-if="!$ctrl.transfer.lastActiveTickets.length"
|
||||||
|
class="empty-rows"
|
||||||
|
colspan="4"
|
||||||
|
translate>
|
||||||
|
No results
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
<form name="form">
|
<form name="form">
|
||||||
<vn-horizontal class="vn-py-md">
|
<vn-horizontal class="vn-py-md">
|
||||||
<vn-input-number vn-one
|
<vn-input-number vn-one
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('getAverageDays', {
|
||||||
|
description: 'Returns the average days duration and the two warehouses of the travel.',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'agencyModeFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/getAverageDays`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getAverageDays = async agencyModeFk => {
|
||||||
|
const conn = Self.dataSource.connector;
|
||||||
|
let stmts = [];
|
||||||
|
|
||||||
|
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.travel');
|
||||||
|
|
||||||
|
stmt = new ParameterizedSQL(`
|
||||||
|
CREATE TEMPORARY TABLE tmp.travel (
|
||||||
|
SELECT
|
||||||
|
t.id,
|
||||||
|
t.warehouseInFk,
|
||||||
|
t.warehouseOutFk,
|
||||||
|
t.landed,
|
||||||
|
t.shipped,
|
||||||
|
t.agencyFk
|
||||||
|
FROM travel t
|
||||||
|
WHERE t.agencyFk = ? LIMIT 50)`, [agencyModeFk]);
|
||||||
|
stmts.push(stmt);
|
||||||
|
|
||||||
|
stmt = new ParameterizedSQL(`
|
||||||
|
SELECT
|
||||||
|
t.id,
|
||||||
|
t.warehouseInFk,
|
||||||
|
t.warehouseOutFk,
|
||||||
|
(SELECT ROUND(AVG(DATEDIFF(t.landed, t.shipped )))
|
||||||
|
FROM tmp.travel t
|
||||||
|
WHERE t.agencyFk
|
||||||
|
ORDER BY id DESC LIMIT 50) AS dayDuration
|
||||||
|
FROM tmp.travel t
|
||||||
|
WHERE t.agencyFk
|
||||||
|
ORDER BY t.id DESC LIMIT 1`);
|
||||||
|
|
||||||
|
const avgDaysIndex = stmts.push(stmt) - 1;
|
||||||
|
|
||||||
|
stmts.push(
|
||||||
|
`DROP TEMPORARY TABLE
|
||||||
|
tmp.travel`);
|
||||||
|
|
||||||
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
|
const result = await conn.executeStmt(sql);
|
||||||
|
|
||||||
|
const [avgDays] = result[avgDaysIndex];
|
||||||
|
|
||||||
|
return avgDays;
|
||||||
|
};
|
||||||
|
};
|
|
@ -8,6 +8,7 @@ module.exports = Self => {
|
||||||
require('../methods/travel/deleteThermograph')(Self);
|
require('../methods/travel/deleteThermograph')(Self);
|
||||||
require('../methods/travel/updateThermograph')(Self);
|
require('../methods/travel/updateThermograph')(Self);
|
||||||
require('../methods/travel/extraCommunityFilter')(Self);
|
require('../methods/travel/extraCommunityFilter')(Self);
|
||||||
|
require('../methods/travel/getAverageDays')(Self);
|
||||||
require('../methods/travel/cloneWithEntries')(Self);
|
require('../methods/travel/cloneWithEntries')(Self);
|
||||||
|
|
||||||
Self.rewriteDbError(function(err) {
|
Self.rewriteDbError(function(err) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-date-picker
|
<vn-date-picker
|
||||||
|
on-change="$ctrl.onShippedChange(value)"
|
||||||
label="Shipped"
|
label="Shipped"
|
||||||
ng-model="$ctrl.travel.shipped">
|
ng-model="$ctrl.travel.shipped">
|
||||||
</vn-date-picker>
|
</vn-date-picker>
|
||||||
|
|
|
@ -7,6 +7,34 @@ class Controller extends Section {
|
||||||
this.travel = JSON.parse(this.$params.q);
|
this.travel = JSON.parse(this.$params.q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onShippedChange(value) {
|
||||||
|
let hasFilledProperties;
|
||||||
|
let hasAgencyMode;
|
||||||
|
if (this.travel) {
|
||||||
|
hasAgencyMode = Boolean(this.travel.agencyModeFk);
|
||||||
|
hasFilledProperties = this.travel.landed || this.travel.warehouseInFk || this.travel.warehouseOutFk;
|
||||||
|
}
|
||||||
|
if (!hasAgencyMode || hasFilledProperties)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const query = `travels/getAverageDays`;
|
||||||
|
const params = {
|
||||||
|
agencyModeFk: this.travel.agencyModeFk
|
||||||
|
};
|
||||||
|
this.$http.get(query, {params}).then(res => {
|
||||||
|
if (!res.data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const landed = new Date(value);
|
||||||
|
const futureDate = landed.getDate() + res.data.dayDuration;
|
||||||
|
landed.setDate(futureDate);
|
||||||
|
|
||||||
|
this.travel.landed = landed;
|
||||||
|
this.travel.warehouseInFk = res.data.warehouseInFk;
|
||||||
|
this.travel.warehouseOutFk = res.data.warehouseOutFk;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
return this.$.watcher.submit().then(
|
return this.$.watcher.submit().then(
|
||||||
res => this.$state.go('travel.card.basicData', {id: res.data.id})
|
res => this.$state.go('travel.card.basicData', {id: res.data.id})
|
||||||
|
|
|
@ -5,10 +5,12 @@ describe('Travel Component vnTravelCreate', () => {
|
||||||
let $scope;
|
let $scope;
|
||||||
let $state;
|
let $state;
|
||||||
let controller;
|
let controller;
|
||||||
|
let $httpBackend;
|
||||||
|
|
||||||
beforeEach(ngModule('travel'));
|
beforeEach(ngModule('travel'));
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$state_) => {
|
beforeEach(inject(($componentController, $rootScope, _$state_, _$httpBackend_) => {
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
$scope = $rootScope.$new();
|
$scope = $rootScope.$new();
|
||||||
$state = _$state_;
|
$state = _$state_;
|
||||||
$scope.watcher = watcher;
|
$scope.watcher = watcher;
|
||||||
|
@ -38,4 +40,49 @@ describe('Travel Component vnTravelCreate', () => {
|
||||||
expect(controller.travel).toEqual(json);
|
expect(controller.travel).toEqual(json);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('onShippedChange()', () => {
|
||||||
|
it(`should do nothing if there's no agencyModeFk in the travel.`, () => {
|
||||||
|
controller.travel = {};
|
||||||
|
controller.onShippedChange();
|
||||||
|
|
||||||
|
expect(controller.travel.landed).toBeUndefined();
|
||||||
|
expect(controller.travel.warehouseInFk).toBeUndefined();
|
||||||
|
expect(controller.travel.warehouseOutFk).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should do nothing if there's no response data.`, () => {
|
||||||
|
controller.travel = {agencyModeFk: 4};
|
||||||
|
const tomorrow = new Date();
|
||||||
|
|
||||||
|
const query = `travels/getAverageDays?agencyModeFk=${controller.travel.agencyModeFk}`;
|
||||||
|
$httpBackend.expectGET(query).respond(undefined);
|
||||||
|
controller.onShippedChange(tomorrow);
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.travel.warehouseInFk).toBeUndefined();
|
||||||
|
expect(controller.travel.warehouseOutFk).toBeUndefined();
|
||||||
|
expect(controller.travel.dayDuration).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should fill the fields when it's selected a date and agency.`, () => {
|
||||||
|
controller.travel = {agencyModeFk: 1};
|
||||||
|
const tomorrow = new Date();
|
||||||
|
tomorrow.setDate(tomorrow.getDate() + 9);
|
||||||
|
const expectedResponse = {
|
||||||
|
id: 8,
|
||||||
|
dayDuration: 9,
|
||||||
|
warehouseInFk: 5,
|
||||||
|
warehouseOutFk: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
const query = `travels/getAverageDays?agencyModeFk=${controller.travel.agencyModeFk}`;
|
||||||
|
$httpBackend.expectGET(query).respond(expectedResponse);
|
||||||
|
controller.onShippedChange(tomorrow);
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.travel.warehouseInFk).toEqual(expectedResponse.warehouseInFk);
|
||||||
|
expect(controller.travel.warehouseOutFk).toEqual(expectedResponse.warehouseOutFk);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -42,6 +42,11 @@
|
||||||
"model": "Account",
|
"model": "Account",
|
||||||
"foreignKey": "userFk"
|
"foreignKey": "userFk"
|
||||||
},
|
},
|
||||||
|
"boss": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Account",
|
||||||
|
"foreignKey": "bossFk"
|
||||||
|
},
|
||||||
"client": {
|
"client": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Client",
|
"model": "Client",
|
||||||
|
|
|
@ -29,6 +29,15 @@
|
||||||
ng-model="$ctrl.worker.phone"
|
ng-model="$ctrl.worker.phone"
|
||||||
rule>
|
rule>
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
|
<vn-autocomplete
|
||||||
|
disabled="false"
|
||||||
|
ng-model="$ctrl.worker.bossFk"
|
||||||
|
url="Clients/activeWorkersWithRole"
|
||||||
|
show-field="nickname"
|
||||||
|
search-function="{firstName: $search}"
|
||||||
|
where="{role: 'employee'}"
|
||||||
|
label="Boss">
|
||||||
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
|
|
@ -7,6 +7,7 @@ Extension: Extensión
|
||||||
Fiscal identifier: NIF
|
Fiscal identifier: NIF
|
||||||
Go to client: Ir al cliente
|
Go to client: Ir al cliente
|
||||||
Last name: Apellidos
|
Last name: Apellidos
|
||||||
|
Boss: Jefe
|
||||||
Log: Historial
|
Log: Historial
|
||||||
Private Branch Exchange: Centralita
|
Private Branch Exchange: Centralita
|
||||||
Role: Rol
|
Role: Rol
|
||||||
|
|
|
@ -30,6 +30,14 @@
|
||||||
<vn-label-value label="Department"
|
<vn-label-value label="Department"
|
||||||
value="{{worker.department.department.name}}">
|
value="{{worker.department.department.name}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
|
<vn-label-value
|
||||||
|
label="Boss">
|
||||||
|
<span
|
||||||
|
ng-click="workerDescriptor.show($event, worker.boss.id)"
|
||||||
|
class="link">
|
||||||
|
{{::worker.boss.nickname}}
|
||||||
|
</span>
|
||||||
|
</vn-label-value>
|
||||||
<vn-label-value label="Phone"
|
<vn-label-value label="Phone"
|
||||||
value="{{worker.phone}}">
|
value="{{worker.phone}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
|
@ -50,4 +58,7 @@
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
<vn-worker-descriptor-popover
|
||||||
|
vn-id="workerDescriptor">
|
||||||
|
</vn-worker-descriptor-popover>
|
|
@ -11,8 +11,8 @@ class Controller extends Summary {
|
||||||
this.$.worker = null;
|
this.$.worker = null;
|
||||||
if (!value) return;
|
if (!value) return;
|
||||||
|
|
||||||
let query = `Workers/${value.id}`;
|
const query = `Workers/${value.id}`;
|
||||||
let filter = {
|
const filter = {
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
relation: 'user',
|
relation: 'user',
|
||||||
|
@ -31,13 +31,20 @@ class Controller extends Summary {
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
relation: 'client',
|
relation: 'client',
|
||||||
scope: {fields: ['fi']}
|
scope: {fields: ['fi']}
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
|
relation: 'boss',
|
||||||
|
scope: {fields: ['id', 'nickname']}
|
||||||
|
},
|
||||||
|
{
|
||||||
relation: 'sip',
|
relation: 'sip',
|
||||||
scope: {fields: ['extension']}
|
scope: {fields: ['extension']}
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
relation: 'department',
|
relation: 'department',
|
||||||
scope: {
|
scope: {
|
||||||
include: {
|
include: {
|
||||||
|
|
|
@ -10606,15 +10606,50 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"minipass": {
|
"bluebird": {
|
||||||
"version": "2.3.5",
|
"version": "3.5.5",
|
||||||
"bundled": true,
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
|
||||||
"dev": true,
|
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w=="
|
||||||
"optional": true,
|
},
|
||||||
"requires": {
|
"bmp-js": {
|
||||||
"safe-buffer": "^5.1.2",
|
"version": "0.1.0",
|
||||||
"yallist": "^3.0.0"
|
"resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
|
||||||
}
|
"integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM="
|
||||||
|
},
|
||||||
|
"bn.js": {
|
||||||
|
"version": "4.11.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
|
||||||
|
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"body-parser": {
|
||||||
|
"version": "1.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||||
|
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||||
|
"requires": {
|
||||||
|
"bytes": "3.1.0",
|
||||||
|
"content-type": "~1.0.4",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"http-errors": "1.7.2",
|
||||||
|
"iconv-lite": "0.4.24",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"qs": "6.7.0",
|
||||||
|
"raw-body": "2.4.0",
|
||||||
|
"type-is": "~1.6.17"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
|
||||||
|
},
|
||||||
|
"depd": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"minizlib": {
|
"minizlib": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
|
@ -11677,11 +11712,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ansi-regex": {
|
"color": {
|
||||||
"version": "4.1.0",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
|
||||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
"integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==",
|
||||||
"dev": true
|
"requires": {
|
||||||
|
"color-convert": "^1.9.1",
|
||||||
|
"color-string": "^1.5.4"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
|
@ -11693,15 +11731,19 @@
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"anymatch": {
|
"color-name": {
|
||||||
"version": "3.1.1",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
|
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||||
"dev": true,
|
},
|
||||||
"requires": {
|
"color-string": {
|
||||||
"normalize-path": "^3.0.0",
|
"version": "1.5.4",
|
||||||
"picomatch": "^2.0.4"
|
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz",
|
||||||
}
|
"integrity": "sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==",
|
||||||
|
"requires": {
|
||||||
|
"color-name": "^1.0.0",
|
||||||
|
"simple-swizzle": "^0.2.2"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"binary-extensions": {
|
"binary-extensions": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
|
@ -14271,15 +14313,18 @@
|
||||||
"@types/yargs-parser": "*"
|
"@types/yargs-parser": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ansi-styles": {
|
"file-type": {
|
||||||
"version": "4.2.1",
|
"version": "10.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz",
|
||||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
"integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw=="
|
||||||
"dev": true,
|
},
|
||||||
"requires": {
|
"filed-mimefix": {
|
||||||
"@types/color-name": "^1.1.1",
|
"version": "0.1.3",
|
||||||
"color-convert": "^2.0.1"
|
"resolved": "https://registry.npmjs.org/filed-mimefix/-/filed-mimefix-0.1.3.tgz",
|
||||||
}
|
"integrity": "sha1-Cwtn0HWmP8dPJv3znH+dQxSWe7U=",
|
||||||
|
"requires": {
|
||||||
|
"mime": "^1.4.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"chalk": {
|
"chalk": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
|
@ -14460,30 +14505,33 @@
|
||||||
"write-file-atomic": "^3.0.0"
|
"write-file-atomic": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@jest/types": {
|
"fs-mkdirp-stream": {
|
||||||
"version": "26.0.1",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
|
||||||
"integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
|
"integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
"graceful-fs": "^4.1.11",
|
||||||
"@types/istanbul-reports": "^1.1.1",
|
"through2": "^2.0.3"
|
||||||
"@types/yargs": "^15.0.0",
|
},
|
||||||
"chalk": "^4.0.0"
|
"dependencies": {
|
||||||
}
|
"through2": {
|
||||||
},
|
"version": "2.0.5",
|
||||||
"@types/babel__core": {
|
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||||
"version": "7.1.8",
|
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz",
|
"dev": true,
|
||||||
"integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==",
|
"requires": {
|
||||||
"dev": true,
|
"readable-stream": "~2.3.6",
|
||||||
"requires": {
|
"xtend": "~4.0.1"
|
||||||
"@babel/parser": "^7.1.0",
|
}
|
||||||
"@babel/types": "^7.0.0",
|
},
|
||||||
"@types/babel__generator": "*",
|
"xtend": {
|
||||||
"@types/babel__template": "*",
|
"version": "4.0.1",
|
||||||
"@types/babel__traverse": "*"
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||||
}
|
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"@types/yargs": {
|
"@types/yargs": {
|
||||||
"version": "15.0.5",
|
"version": "15.0.5",
|
||||||
|
@ -15323,18 +15371,73 @@
|
||||||
"@jest/types": "^26.0.1"
|
"@jest/types": "^26.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jest-util": {
|
"ieee754": {
|
||||||
"version": "26.0.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
"integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==",
|
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||||
"dev": true,
|
},
|
||||||
"requires": {
|
"ienoopen": {
|
||||||
"@jest/types": "^26.0.1",
|
"version": "1.1.0",
|
||||||
"chalk": "^4.0.0",
|
"resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz",
|
||||||
"graceful-fs": "^4.2.4",
|
"integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ=="
|
||||||
"is-ci": "^2.0.0",
|
},
|
||||||
"make-dir": "^3.0.0"
|
"iferr": {
|
||||||
}
|
"version": "0.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
|
||||||
|
"integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ignore": {
|
||||||
|
"version": "4.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||||
|
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ignore-by-default": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"image-type": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/image-type/-/image-type-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-CFJMJ8QK8lJvRlTCEgarL4ro6hfDQKif2HjSvYCdQZESaIPV4v9imrf7BQHK+sQeTeNeMpWciR9hyC/g8ybXEg==",
|
||||||
|
"requires": {
|
||||||
|
"file-type": "^10.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imap": {
|
||||||
|
"version": "0.8.19",
|
||||||
|
"resolved": "https://registry.npmjs.org/imap/-/imap-0.8.19.tgz",
|
||||||
|
"integrity": "sha1-NniHOTSrCc6mukh0HyhNoq9Z2NU=",
|
||||||
|
"requires": {
|
||||||
|
"readable-stream": "1.1.x",
|
||||||
|
"utf7": ">=1.0.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"isarray": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||||
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "1.1.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||||
|
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||||
|
"requires": {
|
||||||
|
"core-util-is": "~1.0.0",
|
||||||
|
"inherits": "~2.0.1",
|
||||||
|
"isarray": "0.0.1",
|
||||||
|
"string_decoder": "~0.10.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "0.10.31",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||||
|
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"make-dir": {
|
"make-dir": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
|
@ -17243,28 +17346,53 @@
|
||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"find-up": {
|
"mississippi": {
|
||||||
"version": "4.1.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
|
||||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
"integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"locate-path": "^5.0.0",
|
"concat-stream": "^1.5.0",
|
||||||
"path-exists": "^4.0.0"
|
"duplexify": "^3.4.2",
|
||||||
}
|
"end-of-stream": "^1.1.0",
|
||||||
},
|
"flush-write-stream": "^1.0.0",
|
||||||
"fsevents": {
|
"from2": "^2.1.0",
|
||||||
"version": "2.1.3",
|
"parallel-transform": "^1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
|
"pump": "^3.0.0",
|
||||||
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
|
"pumpify": "^1.3.3",
|
||||||
"dev": true,
|
"stream-each": "^1.1.0",
|
||||||
"optional": true
|
"through2": "^2.0.0"
|
||||||
},
|
},
|
||||||
"get-caller-file": {
|
"dependencies": {
|
||||||
"version": "2.0.5",
|
"concat-stream": {
|
||||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
"version": "1.6.2",
|
||||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||||
"dev": true
|
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer-from": "^1.0.0",
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"readable-stream": "^2.2.2",
|
||||||
|
"typedarray": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"through2": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"readable-stream": "~2.3.6",
|
||||||
|
"xtend": "~4.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xtend": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"graceful-fs": {
|
"graceful-fs": {
|
||||||
"version": "4.2.4",
|
"version": "4.2.4",
|
||||||
|
@ -17455,20 +17583,23 @@
|
||||||
"picomatch": "^2.0.5"
|
"picomatch": "^2.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"p-locate": {
|
"nocache": {
|
||||||
"version": "4.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz",
|
||||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
"integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q=="
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"p-limit": "^2.2.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"path-exists": {
|
"node-abi": {
|
||||||
"version": "4.0.0",
|
"version": "2.19.3",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.3.tgz",
|
||||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
"integrity": "sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg==",
|
||||||
"dev": true
|
"requires": {
|
||||||
|
"semver": "^5.4.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node-addon-api": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw=="
|
||||||
},
|
},
|
||||||
"pretty-format": {
|
"pretty-format": {
|
||||||
"version": "26.0.1",
|
"version": "26.0.1",
|
||||||
|
@ -17992,11 +18123,10 @@
|
||||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"has-flag": {
|
"p-try": {
|
||||||
"version": "4.0.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"is-ci": {
|
"is-ci": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
|
@ -18455,16 +18585,58 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tough-cookie": {
|
"postcss-value-parser": {
|
||||||
"version": "3.0.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
|
||||||
"integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
|
"integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"requires": {
|
},
|
||||||
"ip-regex": "^2.1.0",
|
"prebuild-install": {
|
||||||
"psl": "^1.1.28",
|
"version": "6.0.1",
|
||||||
"punycode": "^2.1.1"
|
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.0.1.tgz",
|
||||||
}
|
"integrity": "sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ==",
|
||||||
|
"requires": {
|
||||||
|
"detect-libc": "^1.0.3",
|
||||||
|
"expand-template": "^2.0.3",
|
||||||
|
"github-from-package": "0.0.0",
|
||||||
|
"minimist": "^1.2.3",
|
||||||
|
"mkdirp-classic": "^0.5.3",
|
||||||
|
"napi-build-utils": "^1.0.1",
|
||||||
|
"node-abi": "^2.7.0",
|
||||||
|
"noop-logger": "^0.1.1",
|
||||||
|
"npmlog": "^4.0.1",
|
||||||
|
"pump": "^3.0.0",
|
||||||
|
"rc": "^1.2.7",
|
||||||
|
"simple-get": "^3.0.3",
|
||||||
|
"tar-fs": "^2.0.0",
|
||||||
|
"tunnel-agent": "^0.6.0",
|
||||||
|
"which-pm-runs": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"decompress-response": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
|
||||||
|
"requires": {
|
||||||
|
"mimic-response": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mimic-response": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
|
||||||
|
},
|
||||||
|
"simple-get": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
|
||||||
|
"requires": {
|
||||||
|
"decompress-response": "^4.2.0",
|
||||||
|
"once": "^1.3.1",
|
||||||
|
"simple-concat": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"ws": {
|
"ws": {
|
||||||
"version": "7.3.0",
|
"version": "7.3.0",
|
||||||
|
@ -19264,15 +19436,25 @@
|
||||||
"path-key": "^3.0.0"
|
"path-key": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"os-locale": {
|
"read-chunk": {
|
||||||
"version": "5.0.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-3.2.0.tgz",
|
||||||
"integrity": "sha512-tqZcNEDAIZKBEPnHPlVDvKrp7NzgLi7jRmhKiUoa2NUmhl13FtkAGLUVR+ZsYvApBQdBfYm43A4tXXQ4IrYLBA==",
|
"integrity": "sha512-CEjy9LCzhmD7nUpJ1oVOE6s/hBkejlcJEgLQHVnQznOSilOPb+kpKktlLfFDK3/WP43+F80xkUTM2VOkYoSYvQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"execa": "^4.0.0",
|
"pify": "^4.0.1",
|
||||||
"lcid": "^3.0.0",
|
"with-open-file": "^0.1.6"
|
||||||
"mem": "^5.0.0"
|
}
|
||||||
}
|
},
|
||||||
|
"read-pkg": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"load-json-file": "^1.0.0",
|
||||||
|
"normalize-package-data": "^2.3.2",
|
||||||
|
"path-type": "^1.0.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"path-key": {
|
"path-key": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
|
@ -21962,15 +22144,50 @@
|
||||||
"ms": "2.1.2"
|
"ms": "2.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"find-up": {
|
"sharp": {
|
||||||
"version": "4.1.0",
|
"version": "0.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.27.1.tgz",
|
||||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
"integrity": "sha512-IQNXWdspb4nZcJemXa6cfgz+JvKONsuqP8Mwi1Oti23Uo7+J+UF2jihJDf6I1BQbrmhcZ0lagH/1WYG+ReAzyQ==",
|
||||||
"dev": true,
|
"requires": {
|
||||||
"requires": {
|
"array-flatten": "^3.0.0",
|
||||||
"locate-path": "^5.0.0",
|
"color": "^3.1.3",
|
||||||
"path-exists": "^4.0.0"
|
"detect-libc": "^1.0.3",
|
||||||
}
|
"node-addon-api": "^3.1.0",
|
||||||
|
"npmlog": "^4.1.2",
|
||||||
|
"prebuild-install": "^6.0.0",
|
||||||
|
"semver": "^7.3.4",
|
||||||
|
"simple-get": "^4.0.0",
|
||||||
|
"tar-fs": "^2.1.1",
|
||||||
|
"tunnel-agent": "^0.6.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"array-flatten": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA=="
|
||||||
|
},
|
||||||
|
"lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"requires": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "7.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
|
||||||
|
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
|
||||||
|
"requires": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"https-proxy-agent": {
|
"https-proxy-agent": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
@ -24125,74 +24342,64 @@
|
||||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
||||||
},
|
},
|
||||||
"yallist": {
|
"tar-fs": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
|
||||||
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
|
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
|
||||||
}
|
"requires": {
|
||||||
}
|
"chownr": "^1.1.1",
|
||||||
},
|
"mkdirp-classic": "^0.5.2",
|
||||||
"strong-globalize": {
|
"pump": "^3.0.0",
|
||||||
"version": "4.1.3",
|
"tar-stream": "^2.1.4"
|
||||||
"resolved": "https://registry.npmjs.org/strong-globalize/-/strong-globalize-4.1.3.tgz",
|
}
|
||||||
"integrity": "sha512-SJegV7w5D4AodEspZJtJ7rls3fmi+Zc0PdyJCqBsg4RN9B8TC80/uAI2fikC+s1Jp9FLvr2vDX8f0Fqc62M4OA==",
|
|
||||||
"requires": {
|
|
||||||
"accept-language": "^3.0.18",
|
|
||||||
"debug": "^4.1.1",
|
|
||||||
"globalize": "^1.4.2",
|
|
||||||
"lodash": "^4.17.4",
|
|
||||||
"md5": "^2.2.1",
|
|
||||||
"mkdirp": "^0.5.1",
|
|
||||||
"os-locale": "^3.1.0",
|
|
||||||
"yamljs": "^0.3.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "^2.1.1"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"ms": {
|
"tar-stream": {
|
||||||
"version": "2.1.2",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||||
}
|
"requires": {
|
||||||
}
|
"bl": "^4.0.3",
|
||||||
},
|
"end-of-stream": "^1.4.1",
|
||||||
"strong-remoting": {
|
"fs-constants": "^1.0.0",
|
||||||
"version": "3.16.2",
|
"inherits": "^2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/strong-remoting/-/strong-remoting-3.16.2.tgz",
|
"readable-stream": "^3.1.1"
|
||||||
"integrity": "sha512-Kj8dZh6q0F3GQTil2rkEt6WuQoQbXFRZ2AJG36iBPmxcVEE9bVhWXUYxcJIxXaGekCprxp8kfdLLN67yp0J4Hg==",
|
},
|
||||||
"requires": {
|
"dependencies": {
|
||||||
"async": "^3.1.0",
|
"base64-js": {
|
||||||
"body-parser": "^1.12.4",
|
"version": "1.5.1",
|
||||||
"debug": "^4.1.1",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
"depd": "^2.0.0",
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||||
"escape-string-regexp": "^2.0.0",
|
},
|
||||||
"eventemitter2": "^5.0.1",
|
"bl": {
|
||||||
"express": "4.x",
|
"version": "4.1.0",
|
||||||
"inflection": "^1.7.1",
|
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||||
"jayson": "^2.0.5",
|
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||||
"js2xmlparser": "^3.0.0",
|
"requires": {
|
||||||
"loopback-datatype-geopoint": "^1.0.0",
|
"buffer": "^5.5.0",
|
||||||
"loopback-phase": "^3.1.0",
|
"inherits": "^2.0.4",
|
||||||
"mux-demux": "^3.7.9",
|
"readable-stream": "^3.4.0"
|
||||||
"qs": "^6.2.1",
|
}
|
||||||
"request": "^2.83.0",
|
},
|
||||||
"sse": "0.0.8",
|
"buffer": {
|
||||||
"strong-error-handler": "^3.0.0",
|
"version": "5.7.1",
|
||||||
"strong-globalize": "^5.0.2",
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||||
"traverse": "^0.6.6",
|
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||||
"xml2js": "^0.4.8"
|
"requires": {
|
||||||
},
|
"base64-js": "^1.3.1",
|
||||||
"dependencies": {
|
"ieee754": "^1.1.13"
|
||||||
"async": {
|
}
|
||||||
"version": "3.2.0",
|
},
|
||||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
|
"readable-stream": {
|
||||||
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||||
|
"requires": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"cross-spawn": {
|
"cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
|
@ -24609,14 +24816,38 @@
|
||||||
"readable-stream": "^3.4.0"
|
"readable-stream": "^3.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"buffer": {
|
"uid2": {
|
||||||
"version": "5.6.0",
|
"version": "0.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
|
||||||
"integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
|
"integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
|
||||||
"requires": {
|
},
|
||||||
"base64-js": "^1.0.2",
|
"unbzip2-stream": {
|
||||||
"ieee754": "^1.1.4"
|
"version": "1.4.3",
|
||||||
}
|
"resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
|
||||||
|
"integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer": "^5.2.1",
|
||||||
|
"through": "^2.3.8"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"buffer": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.1.13"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
|
@ -26380,14 +26611,41 @@
|
||||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"rimraf": {
|
"with-open-file": {
|
||||||
"version": "2.7.1",
|
"version": "0.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/with-open-file/-/with-open-file-0.1.7.tgz",
|
||||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
"integrity": "sha512-ecJS2/oHtESJ1t3ZfMI3B7KIDKyfN0O16miWxdn30zdh66Yd3LsRFebXZXq6GU4xfxLf6nVxp9kIqElb5fqczA==",
|
||||||
"dev": true,
|
"requires": {
|
||||||
"requires": {
|
"p-finally": "^1.0.0",
|
||||||
"glob": "^7.1.3"
|
"p-try": "^2.1.0",
|
||||||
}
|
"pify": "^4.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"word-count": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/word-count/-/word-count-0.2.2.tgz",
|
||||||
|
"integrity": "sha1-aZGS/KaCn+k21Byw2V25JIxXBFE="
|
||||||
|
},
|
||||||
|
"word-wrap": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"wordwrap": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"worker-farm": {
|
||||||
|
"version": "1.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
|
||||||
|
"integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"errno": "~0.1.7"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0",
|
||||||
|
|
|
@ -12,10 +12,12 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bmp-js": "^0.1.0",
|
||||||
"compression": "^1.7.3",
|
"compression": "^1.7.3",
|
||||||
"fs-extra": "^5.0.0",
|
"fs-extra": "^5.0.0",
|
||||||
"helmet": "^3.21.2",
|
"helmet": "^3.21.2",
|
||||||
"i18n": "^0.8.4",
|
"i18n": "^0.8.4",
|
||||||
|
"image-type": "^4.1.0",
|
||||||
"imap": "^0.8.19",
|
"imap": "^0.8.19",
|
||||||
"ldapjs": "^2.2.0",
|
"ldapjs": "^2.2.0",
|
||||||
"loopback": "^3.26.0",
|
"loopback": "^3.26.0",
|
||||||
|
@ -30,10 +32,11 @@
|
||||||
"node-ssh": "^11.0.0",
|
"node-ssh": "^11.0.0",
|
||||||
"object-diff": "0.0.4",
|
"object-diff": "0.0.4",
|
||||||
"object.pick": "^1.3.0",
|
"object.pick": "^1.3.0",
|
||||||
|
"read-chunk": "^3.2.0",
|
||||||
"request": "^2.88.0",
|
"request": "^2.88.0",
|
||||||
"request-promise-native": "^1.0.8",
|
"request-promise-native": "^1.0.8",
|
||||||
"require-yaml": "0.0.1",
|
"require-yaml": "0.0.1",
|
||||||
"sharp": "^0.25.4",
|
"sharp": "^0.27.1",
|
||||||
"smbhash": "0.0.1",
|
"smbhash": "0.0.1",
|
||||||
"soap": "^0.35.0",
|
"soap": "^0.35.0",
|
||||||
"strong-error-handler": "^2.3.2",
|
"strong-error-handler": "^2.3.2",
|
||||||
|
|
Loading…
Reference in New Issue