2595 - Added invoiceIn module #545
|
@ -34,4 +34,5 @@ rules:
|
|||
no-multiple-empty-lines: ["error", { "max": 1, "maxEOF": 1 }]
|
||||
space-in-parens: ["error", "never"]
|
||||
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) {
|
||||
const models = Self.app.models;
|
||||
const myUserId = ctx.req.accessToken.userId;
|
||||
const myWorker = await models.Worker.findOne({where: {userFk: myUserId}}, myOptions);
|
||||
const args = ctx.args;
|
||||
|
||||
const newDms = await Self.create({
|
||||
workerFk: myWorker.id,
|
||||
workerFk: myUserId,
|
||||
dmsTypeFk: args.dmsTypeId,
|
||||
companyFk: args.companyId,
|
||||
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 sharp = require('sharp');
|
||||
const path = require('path');
|
||||
const readChunk = require('read-chunk');
|
||||
const imageType = require('image-type');
|
||||
const bmp = require('bmp-js');
|
||||
|
||||
module.exports = Self => {
|
||||
require('../methods/image/download')(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) => {
|
||||
const models = Self.app.models;
|
||||
const tx = await Self.beginTransaction({});
|
||||
|
@ -48,13 +88,31 @@ module.exports = Self => {
|
|||
const dstDir = path.join(collectionDir, 'full');
|
||||
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 = {
|
||||
withoutEnlargement: true,
|
||||
fit: 'inside'
|
||||
};
|
||||
|
||||
await fs.mkdir(dstDir, {recursive: true});
|
||||
await sharp(srcFilePath, {failOnError: false})
|
||||
await sharp(imgSrc, sharpOptions)
|
||||
.resize(collection.maxWidth, collection.maxHeight, resizeOpts)
|
||||
.png()
|
||||
.toFile(dstFile);
|
||||
|
@ -69,7 +127,7 @@ module.exports = Self => {
|
|||
};
|
||||
|
||||
await fs.mkdir(dstDir, {recursive: true});
|
||||
await sharp(srcFilePath, {failOnError: false})
|
||||
await sharp(imgSrc, sharpOptions)
|
||||
.resize(size.width, size.height, resizeOpts)
|
||||
.png()
|
||||
.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`)
|
||||
VALUES
|
||||
(1, 'CC y Polizas de crédito', NULL, NULL),
|
||||
(2, 'Cash', NULL, 'cash'),
|
||||
(3, 'Credit card', NULL, 'creditCard'),
|
||||
(4, 'Finalcial lines', NULL, NULL),
|
||||
(5, 'Other products', NULL, NULL),
|
||||
(6, 'Loans', NULL, NULL),
|
||||
(7, 'Leasing', NULL, NULL),
|
||||
(8, 'Compensations', 'Compensations', 'Compensations');
|
||||
(1, 'CC y Polizas de crédito', NULL, NULL),
|
||||
(2, 'Cash', 'Cash', 'cash'),
|
||||
(3, 'Credit card', 'Credit Card', 'creditCard'),
|
||||
(4, 'Finalcial lines', NULL, NULL),
|
||||
(5, 'Other products', NULL, NULL),
|
||||
(6, 'Loans', NULL, NULL),
|
||||
(7, 'Leasing', NULL, NULL),
|
||||
(8, 'Compensations', 'Compensations', 'compensation');
|
||||
|
||||
INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`)
|
||||
VALUES
|
||||
(1, 'Pay on receipt', '0000000000', 3, 0, 1, 1),
|
||||
(2, 'Cash', '1111111111', 2, 0, 1, 1),
|
||||
(3, 'Compensation', '0000000000', 8, 0, 1, 1);
|
||||
(1, 'Pay on receipt', '5720000001', 3, 0, 1, 1),
|
||||
(2, 'Cash', '5700000001', 2, 0, 1, 1),
|
||||
(3, 'Compensation', '4000000000', 8, 0, 1, 1);
|
||||
|
||||
INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
|
||||
VALUES
|
||||
|
|
|
@ -316,7 +316,7 @@ export default {
|
|||
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"]',
|
||||
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"]',
|
||||
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"]',
|
||||
|
|
|
@ -47,6 +47,7 @@ describe('Client balance path', () => {
|
|||
await page.closePopup();
|
||||
await page.waitToClick(selectors.clientBalance.newPaymentButton);
|
||||
await page.autocompleteSearch(selectors.clientBalance.newPaymentBank, 'Cash');
|
||||
await page.clearInput(selectors.clientBalance.newDescription);
|
||||
await page.write(selectors.clientBalance.newDescription, 'Description');
|
||||
await page.waitToClick(selectors.clientBalance.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
@ -86,6 +87,7 @@ describe('Client balance path', () => {
|
|||
|
||||
await page.waitToClick(selectors.clientBalance.newPaymentButton);
|
||||
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.deliveredAmount, cashHanded);
|
||||
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.autocompleteSearch(selectors.clientBalance.newPaymentBank, 'Pay on receipt');
|
||||
await page.overwrite(selectors.clientBalance.newPaymentAmount, '-150');
|
||||
await page.clearInput(selectors.clientBalance.newDescription);
|
||||
await page.write(selectors.clientBalance.newDescription, 'Description');
|
||||
await page.waitToClick(selectors.clientBalance.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
|
|
@ -16,7 +16,7 @@ describe('Item create tags path', () => {
|
|||
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.addItemTagButton);
|
||||
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!');
|
||||
});
|
||||
|
||||
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.waitForSelector('vn-item-tags');
|
||||
let result = await page.waitToGetProperty(selectors.itemTags.fourthTag, 'value');
|
||||
|
@ -47,7 +47,7 @@ describe('Item create tags path', () => {
|
|||
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
|
||||
.waitToGetProperty(selectors.itemTags.fifthTag, 'value');
|
||||
|
||||
|
@ -62,7 +62,7 @@ describe('Item create tags path', () => {
|
|||
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
|
||||
.waitToGetProperty(selectors.itemTags.sixthTag, 'value');
|
||||
|
||||
|
|
|
@ -174,4 +174,9 @@ vn-table {
|
|||
.vn-check {
|
||||
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 './user-popover';
|
||||
import './upload-photo';
|
||||
import './bank-entity';
|
||||
|
|
|
@ -91,5 +91,6 @@
|
|||
"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": "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",
|
||||
"The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta",
|
||||
"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 *{{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 *{{shipped}}*, con una cantidad de *{{quantity}}*",
|
||||
"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": "Se ha creado una nueva petición de compra '{{description}}' para el día <strong>{{shipped}}</strong>, con una cantidad de <strong>{{quantity}}</strong>",
|
||||
"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",
|
||||
"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 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({
|
||||
where: {
|
||||
account: args.compensationAccount
|
||||
|
@ -92,12 +95,11 @@ module.exports = function(Self) {
|
|||
],
|
||||
options);
|
||||
} else {
|
||||
const description = `${clientOriginal.id} : ${clientOriginal.nickname} - ${accountingType.receiptDescription}`;
|
||||
const description = `${clientOriginal.id} : ${clientOriginal.socialName} - ${accountingType.receiptDescription}`;
|
||||
const [xdiarioNew] = await Self.rawSql(
|
||||
`SELECT xdiario_new(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ledger;`,
|
||||
`SELECT xdiario_new(?, CURDATE(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ledger;`,
|
||||
[
|
||||
null,
|
||||
Date(),
|
||||
bank.account,
|
||||
clientOriginal.accountingAccount,
|
||||
description,
|
||||
|
@ -114,10 +116,9 @@ module.exports = function(Self) {
|
|||
options);
|
||||
|
||||
await Self.rawSql(
|
||||
`SELECT xdiario_new(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`,
|
||||
`SELECT xdiario_new(?, CURDATE(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`,
|
||||
[
|
||||
xdiarioNew.ledger,
|
||||
Date(),
|
||||
clientOriginal.accountingAccount,
|
||||
bank.account,
|
||||
description,
|
||||
|
|
|
@ -26,15 +26,25 @@ module.exports = Self => {
|
|||
Self.lastActiveTickets = async(id, ticketId) => {
|
||||
const ticket = await Self.app.models.Ticket.findById(ticketId);
|
||||
const query = `
|
||||
SELECT t.id, t.shipped, a.name AS agencyName, w.name AS warehouseName, ad.city AS address
|
||||
FROM vn.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
|
||||
WHERE t.shipped >= CURDATE() AND t.clientFk = ? AND ts.alertLevel = 0
|
||||
AND t.id <> ? AND t.warehouseFk = ?
|
||||
ORDER BY t.shipped
|
||||
SELECT
|
||||
t.id,
|
||||
t.shipped,
|
||||
a.name AS agencyName,
|
||||
w.name AS warehouseName,
|
||||
ad.nickname AS nickname,
|
||||
ad.city AS city,
|
||||
ad.postalCode AS postalCode,
|
||||
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`;
|
||||
|
||||
return Self.rawSql(query, [id, ticketId, ticket.warehouseFk]);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
describe('Client createReceipt', () => {
|
||||
const clientFk = 108;
|
||||
|
@ -6,18 +7,34 @@ describe('Client createReceipt', () => {
|
|||
const companyFk = 442;
|
||||
const amountPaid = 12.50;
|
||||
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() => {
|
||||
const bankFk = 1;
|
||||
let ctx = {
|
||||
args: {
|
||||
clientFk: clientFk,
|
||||
payed: payed,
|
||||
companyFk: companyFk,
|
||||
bankFk: bankFk,
|
||||
amountPaid: amountPaid,
|
||||
description: description
|
||||
}
|
||||
ctx.args = {
|
||||
clientFk: clientFk,
|
||||
payed: payed,
|
||||
companyFk: companyFk,
|
||||
bankFk: bankFk,
|
||||
amountPaid: amountPaid,
|
||||
description: description
|
||||
};
|
||||
|
||||
const receipt = await app.models.Client.createReceipt(ctx);
|
||||
|
@ -38,19 +55,39 @@ describe('Client createReceipt', () => {
|
|||
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() => {
|
||||
let error;
|
||||
const bankFk = 3;
|
||||
const ctx = {
|
||||
args: {
|
||||
clientFk: clientFk,
|
||||
payed: payed,
|
||||
companyFk: companyFk,
|
||||
bankFk: bankFk,
|
||||
amountPaid: amountPaid,
|
||||
description: description,
|
||||
compensationAccount: 'non existing account'
|
||||
}
|
||||
ctx.args = {
|
||||
clientFk: clientFk,
|
||||
payed: payed,
|
||||
companyFk: companyFk,
|
||||
bankFk: bankFk,
|
||||
amountPaid: amountPaid,
|
||||
description: description,
|
||||
compensationAccount: 'non existing account'
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -65,16 +102,15 @@ describe('Client createReceipt', () => {
|
|||
|
||||
it('should create a new receipt with a compensation for a client', async() => {
|
||||
const bankFk = 3;
|
||||
const ctx = {
|
||||
args: {
|
||||
clientFk: clientFk,
|
||||
payed: payed,
|
||||
companyFk: companyFk,
|
||||
bankFk: bankFk,
|
||||
amountPaid: amountPaid,
|
||||
description: description,
|
||||
compensationAccount: '4300000001'
|
||||
}
|
||||
|
||||
ctx.args = {
|
||||
clientFk: clientFk,
|
||||
payed: payed,
|
||||
companyFk: companyFk,
|
||||
bankFk: bankFk,
|
||||
amountPaid: amountPaid,
|
||||
description: description,
|
||||
compensationAccount: '4300000001'
|
||||
};
|
||||
const receipt = await app.models.Client.createReceipt(ctx);
|
||||
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() => {
|
||||
const ctx = {
|
||||
args: {
|
||||
clientFk: clientFk,
|
||||
payed: payed,
|
||||
companyFk: companyFk,
|
||||
bankFk: 3,
|
||||
amountPaid: amountPaid,
|
||||
description: description,
|
||||
compensationAccount: '4100000001'
|
||||
}
|
||||
const bankFk = 3;
|
||||
|
||||
ctx.args = {
|
||||
clientFk: clientFk,
|
||||
payed: payed,
|
||||
companyFk: companyFk,
|
||||
bankFk: bankFk,
|
||||
amountPaid: amountPaid,
|
||||
description: description,
|
||||
compensationAccount: '4100000001'
|
||||
};
|
||||
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) {
|
||||
require('../methods/receipt/filter')(Self);
|
||||
|
||||
|
@ -23,13 +25,10 @@ module.exports = function(Self) {
|
|||
|
||||
Self.observe('before save', async function(ctx) {
|
||||
if (ctx.isNewInstance) {
|
||||
let token = ctx.options.accessToken;
|
||||
let userId = token && token.userId;
|
||||
|
||||
ctx.instance.workerFk = userId;
|
||||
|
||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||
ctx.instance.workerFk = loopBackContext.active.accessToken.userId;
|
||||
await Self.app.models.Till.create({
|
||||
workerFk: userId,
|
||||
workerFk: ctx.instance.workerFk,
|
||||
bankFk: ctx.instance.bankFk,
|
||||
in: ctx.instance.amountPaid,
|
||||
concept: ctx.instance.description,
|
||||
|
|
|
@ -78,6 +78,8 @@ module.exports = Self => {
|
|||
return {'ic.id': value};
|
||||
case 'salesPersonFk':
|
||||
return {'it.workerFk': value};
|
||||
case 'code':
|
||||
return {'it.code': value};
|
||||
case 'typeFk':
|
||||
return {'i.typeFk': value};
|
||||
case 'active':
|
||||
|
@ -103,6 +105,7 @@ module.exports = Self => {
|
|||
i.id AS itemFk,
|
||||
i.size,
|
||||
i.density,
|
||||
it.code,
|
||||
i.typeFk,
|
||||
i.family,
|
||||
i.isActive,
|
||||
|
|
|
@ -37,8 +37,8 @@
|
|||
<vn-th field="quantity">Quantity</vn-th>
|
||||
<vn-th field="description" style="text-align: center">Description</vn-th>
|
||||
<vn-th field="size">Size</vn-th>
|
||||
<vn-th field="tags" style="text-align: center">Tags</vn-th>
|
||||
<vn-th field="type">Type</vn-th>
|
||||
<vn-th field="name" style="text-align: center">Tags</vn-th>
|
||||
<vn-th field="code">Type</vn-th>
|
||||
<vn-th field="intrastat">Intrastat</vn-th>
|
||||
<vn-th field="origin">Origin</vn-th>
|
||||
<vn-th field="density">Density</vn-th>
|
||||
|
@ -109,7 +109,7 @@
|
|||
</vn-fetched-tags>
|
||||
</vn-td>
|
||||
<vn-td shrink title="{{::buy.type}}">
|
||||
{{::buy.type}}
|
||||
{{::buy.code}}
|
||||
</vn-td>
|
||||
<vn-td shrink title="{{::item.intrastat}}">
|
||||
{{::buy.intrastat}}
|
||||
|
|
|
@ -31,19 +31,19 @@
|
|||
"state": "entry.index",
|
||||
"component": "vn-entry-index",
|
||||
"description": "Entries",
|
||||
"acl": ["buyer"]
|
||||
"acl": ["buyer", "administrative"]
|
||||
}, {
|
||||
"url": "/latest-buys?q",
|
||||
"state": "entry.latestBuys",
|
||||
"component": "vn-entry-latest-buys",
|
||||
"description": "Latest buys",
|
||||
"acl": ["buyer"]
|
||||
"acl": ["buyer", "administrative"]
|
||||
}, {
|
||||
"url": "/create?supplierFk&travelFk&companyFk",
|
||||
"state": "entry.create",
|
||||
"component": "vn-entry-create",
|
||||
"description": "New entry",
|
||||
"acl": ["buyer"]
|
||||
"acl": ["buyer", "administrative"]
|
||||
}, {
|
||||
"url": "/:id",
|
||||
"state": "entry.card",
|
||||
|
|
|
@ -41,18 +41,13 @@ module.exports = Self => {
|
|||
async function download() {
|
||||
const image = await Self.findOne({
|
||||
where: {url: {neq: null}, attempts: {lt: maxAttempts}},
|
||||
order: 'attempts, updated'
|
||||
order: 'priority, attempts, updated'
|
||||
});
|
||||
|
||||
if (!image) return;
|
||||
|
||||
const srcFile = image.url.split('/').pop();
|
||||
const dotIndex = srcFile.lastIndexOf('.');
|
||||
|
||||
let fileName = srcFile.substring(0, dotIndex);
|
||||
if (dotIndex == -1)
|
||||
fileName = srcFile;
|
||||
|
||||
const srcFile = image.url;
|
||||
const fileName = srcFile.replace(/\.|\/|:|\?|\\|=|%/g, '');
|
||||
const file = `${fileName}.png`;
|
||||
const filePath = path.join(tempPath, file);
|
||||
|
||||
|
|
|
@ -44,6 +44,10 @@ module.exports = Self => {
|
|||
arg: 'description',
|
||||
type: 'String',
|
||||
description: 'The item description',
|
||||
}, {
|
||||
arg: 'stemMultiplier',
|
||||
type: 'Integer',
|
||||
description: 'The item multiplier',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
|
@ -80,16 +84,22 @@ module.exports = Self => {
|
|||
: {or: [{'i.name': {like: `%${value}%`}}, codeWhere]};
|
||||
case 'id':
|
||||
return {'i.id': value};
|
||||
case 'description':
|
||||
return {'i.description': {like: `%${value}%`}};
|
||||
case 'categoryFk':
|
||||
return {'ic.id': value};
|
||||
case 'salesPersonFk':
|
||||
return {'t.workerFk': value};
|
||||
case 'typeFk':
|
||||
return {'i.typeFk': value};
|
||||
case 'isActive':
|
||||
return {'i.isActive': value};
|
||||
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});
|
||||
|
@ -98,7 +108,8 @@ module.exports = Self => {
|
|||
let stmt;
|
||||
|
||||
stmt = new ParameterizedSQL(
|
||||
`SELECT i.id,
|
||||
`SELECT
|
||||
i.id,
|
||||
i.image,
|
||||
i.name,
|
||||
i.description,
|
||||
|
@ -111,29 +122,30 @@ module.exports = Self => {
|
|||
i.tag10, i.value10,
|
||||
i.subName,
|
||||
i.isActive,
|
||||
t.name type,
|
||||
t.workerFk buyerFk,
|
||||
u.name userName,
|
||||
intr.description AS intrastat,
|
||||
i.stems,
|
||||
ori.code AS origin,
|
||||
ic.name AS category,
|
||||
i.density,
|
||||
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.packing,
|
||||
itn.code AS niche, @visibleCalc
|
||||
ip.code AS niche, @visibleCalc
|
||||
FROM item i
|
||||
LEFT JOIN itemType t ON t.id = i.typeFk
|
||||
LEFT JOIN itemCategory ic ON ic.id = t.categoryFk
|
||||
LEFT JOIN worker w ON w.id = t.workerFk
|
||||
LEFT JOIN itemType it ON it.id = i.typeFk
|
||||
LEFT JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||
LEFT JOIN worker w ON w.id = it.workerFk
|
||||
LEFT JOIN account.user u ON u.id = w.userFk
|
||||
LEFT JOIN intrastat intr ON intr.id = i.intrastatFk
|
||||
LEFT JOIN producer pr ON pr.id = i.producerFk
|
||||
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 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) {
|
||||
|
|
|
@ -20,8 +20,12 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
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]);
|
||||
|
||||
for (const entry of diary)
|
||||
if (entry.clientType === 'loses') entry.highlighted = true;
|
||||
|
||||
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"
|
||||
rule>
|
||||
</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-input-number
|
||||
|
|
|
@ -9,4 +9,5 @@ Price in kg: Precio en kg
|
|||
New intrastat: Nuevo intrastat
|
||||
Identifier: Identificador
|
||||
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.reference | dashIfEmpty}}</vn-td>
|
||||
<vn-td class="truncate" expand>
|
||||
<span ng-if="::!sale.isTicket">
|
||||
{{::sale.name | dashIfEmpty}}
|
||||
</span>
|
||||
<span
|
||||
ng-if="::sale.isTicket"
|
||||
vn-click-stop="clientDescriptor.show($event, sale.clientFk)"
|
||||
class="link">
|
||||
{{::sale.name | dashIfEmpty}}
|
||||
<span ng-class="::{'warning chip': sale.highlighted}">
|
||||
<span ng-if="::!sale.isTicket">
|
||||
{{::sale.name | dashIfEmpty}}
|
||||
</span>
|
||||
<span
|
||||
ng-if="::sale.isTicket"
|
||||
vn-click-stop="clientDescriptor.show($event, sale.clientFk)"
|
||||
class="link">
|
||||
{{::sale.name | dashIfEmpty}}
|
||||
</span>
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number class="in">{{::sale.in | dashIfEmpty}}</vn-td>
|
||||
|
|
|
@ -5,107 +5,107 @@
|
|||
model="model"
|
||||
class="vn-w-xl vn-mb-xl">
|
||||
<vn-card>
|
||||
<vn-table
|
||||
model="model"
|
||||
show-fields="$ctrl.showFields"
|
||||
vn-smart-table="itemIndex">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th shrink></vn-th>
|
||||
<vn-th field="id" shrink>Id</vn-th>
|
||||
<vn-th field="grouping" shrink>Grouping</vn-th>
|
||||
<vn-th field="packing" shrink>Packing</vn-th>
|
||||
<vn-th field="description">Description</vn-th>
|
||||
<vn-th field="stems" shrink>Stems</vn-th>
|
||||
<vn-th field="size" shrink>Size</vn-th>
|
||||
<vn-th field="niche" shrink>Niche</vn-th>
|
||||
<vn-th field="type" shrink>Type</vn-th>
|
||||
<vn-th field="category" shrink>Category</vn-th>
|
||||
<vn-th field="intrastat" shrink>Intrastat</vn-th>
|
||||
<vn-th field="origin" shrink>Origin</vn-th>
|
||||
<vn-th field="salesperson" shrink>Buyer</vn-th>
|
||||
<vn-th field="density" shrink>Density</vn-th>
|
||||
<vn-th field="stemMultiplier" shrink>Multiplier</vn-th>
|
||||
<vn-th field="active" shrink>Active</vn-th>
|
||||
<vn-th></vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<a ng-repeat="item in model.data"
|
||||
class="clickable vn-tr search-result"
|
||||
ui-sref="item.card.summary({id: item.id})">
|
||||
<vn-td shrink>
|
||||
<img
|
||||
ng-src="{{::$root.imagePath('catalog', '50x50', item.id)}}"
|
||||
zoom-image="{{::$root.imagePath('catalog', '1600x900', item.id)}}"
|
||||
vn-click-stop
|
||||
on-error-src/>
|
||||
</vn-td>
|
||||
<vn-td shrink>
|
||||
<span
|
||||
vn-click-stop="itemDescriptor.show($event, item.id)"
|
||||
class="link">
|
||||
{{::item.id}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::item.grouping | dashIfEmpty}}</vn-td>
|
||||
<vn-td shrink>{{::item.packing | dashIfEmpty}}</vn-td>
|
||||
<vn-td vn-fetched-tags>
|
||||
<vn-one title="{{::item.name}}">{{::item.name}}</vn-one>
|
||||
<vn-one ng-if="::item.subName">
|
||||
<h3 title="{{::item.subName}}">{{::item.subName}}</h3>
|
||||
</vn-one>
|
||||
<vn-fetched-tags
|
||||
max-length="6"
|
||||
item="item"
|
||||
tabindex="-1">
|
||||
</vn-fetched-tags>
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::item.stems}}</vn-td>
|
||||
<vn-td shrink>{{::item.size}}</vn-td>
|
||||
<vn-td shrink>{{::item.niche}}</vn-td>
|
||||
<vn-td shrink title="{{::item.type}}">
|
||||
{{::item.type}}
|
||||
</vn-td>
|
||||
<vn-td shrink title="{{::item.category}}">
|
||||
{{::item.category}}
|
||||
</vn-td>
|
||||
<vn-td shrink title="{{::item.intrastat}}">
|
||||
{{::item.intrastat}}
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::item.origin}}</vn-td>
|
||||
<vn-td shrink title="{{::item.userName}}">
|
||||
<span
|
||||
class="link"
|
||||
vn-click-stop="workerDescriptor.show($event, item.buyerFk)">
|
||||
{{::item.userName}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::item.density}}</vn-td>
|
||||
<vn-td shrink >{{::item.stemMultiplier}}</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::item.isActive">
|
||||
</vn-check>
|
||||
</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-horizontal class="buttons">
|
||||
<vn-icon-button
|
||||
vn-click-stop="clone.show(item.id)"
|
||||
vn-tooltip="Clone"
|
||||
icon="icon-clone">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button
|
||||
vn-click-stop="$ctrl.preview(item)"
|
||||
vn-tooltip="Preview"
|
||||
icon="preview">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
</vn-td>
|
||||
</a>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
<vn-table
|
||||
model="model"
|
||||
show-fields="$ctrl.showFields"
|
||||
vn-smart-table="itemIndex">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th shrink></vn-th>
|
||||
<vn-th field="id" shrink>Id</vn-th>
|
||||
<vn-th field="grouping" shrink>Grouping</vn-th>
|
||||
<vn-th field="packing" shrink>Packing</vn-th>
|
||||
<vn-th field="name">Description</vn-th>
|
||||
<vn-th field="stems" shrink>Stems</vn-th>
|
||||
<vn-th field="size" shrink>Size</vn-th>
|
||||
<vn-th field="niche" shrink>Niche</vn-th>
|
||||
<vn-th field="typeFk" shrink>Type</vn-th>
|
||||
<vn-th field="category" shrink>Category</vn-th>
|
||||
<vn-th field="intrastat" shrink>Intrastat</vn-th>
|
||||
<vn-th field="origin" shrink>Origin</vn-th>
|
||||
<vn-th field="salesperson" shrink>Buyer</vn-th>
|
||||
<vn-th field="density" shrink>Density</vn-th>
|
||||
<vn-th field="stemMultiplier" shrink>Multiplier</vn-th>
|
||||
<vn-th field="active" shrink>Active</vn-th>
|
||||
<vn-th></vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<a ng-repeat="item in model.data"
|
||||
class="clickable vn-tr search-result"
|
||||
ui-sref="item.card.summary({id: item.id})">
|
||||
<vn-td shrink>
|
||||
<img
|
||||
ng-src="{{::$root.imagePath('catalog', '50x50', item.id)}}"
|
||||
zoom-image="{{::$root.imagePath('catalog', '1600x900', item.id)}}"
|
||||
vn-click-stop
|
||||
on-error-src/>
|
||||
</vn-td>
|
||||
<vn-td shrink>
|
||||
<span
|
||||
vn-click-stop="itemDescriptor.show($event, item.id)"
|
||||
class="link">
|
||||
{{::item.id}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::item.grouping | dashIfEmpty}}</vn-td>
|
||||
<vn-td shrink>{{::item.packing | dashIfEmpty}}</vn-td>
|
||||
<vn-td vn-fetched-tags>
|
||||
<vn-one title="{{::item.name}}">{{::item.name}}</vn-one>
|
||||
<vn-one ng-if="::item.subName">
|
||||
<h3 title="{{::item.subName}}">{{::item.subName}}</h3>
|
||||
</vn-one>
|
||||
<vn-fetched-tags
|
||||
max-length="6"
|
||||
item="item"
|
||||
tabindex="-1">
|
||||
</vn-fetched-tags>
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::item.stems}}</vn-td>
|
||||
<vn-td shrink>{{::item.size}}</vn-td>
|
||||
<vn-td shrink>{{::item.niche}}</vn-td>
|
||||
<vn-td shrink title="{{::item.typeName}}">
|
||||
{{::item.typeName}}
|
||||
</vn-td>
|
||||
<vn-td shrink title="{{::item.category}}">
|
||||
{{::item.category}}
|
||||
</vn-td>
|
||||
<vn-td shrink title="{{::item.intrastat}}">
|
||||
{{::item.intrastat}}
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::item.origin}}</vn-td>
|
||||
<vn-td shrink title="{{::item.userName}}">
|
||||
<span
|
||||
class="link"
|
||||
vn-click-stop="workerDescriptor.show($event, item.buyerFk)">
|
||||
{{::item.userName}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::item.density}}</vn-td>
|
||||
<vn-td shrink >{{::item.stemMultiplier}}</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::item.isActive">
|
||||
</vn-check>
|
||||
</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-horizontal class="buttons">
|
||||
<vn-icon-button
|
||||
vn-click-stop="clone.show(item.id)"
|
||||
vn-tooltip="Clone"
|
||||
icon="icon-clone">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button
|
||||
vn-click-stop="$ctrl.preview(item)"
|
||||
vn-tooltip="Preview"
|
||||
icon="preview">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
</vn-td>
|
||||
</a>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<a ui-sref="item.create" vn-tooltip="New item" vn-bind="+" fixed-bottom-right>
|
||||
|
@ -127,4 +127,31 @@
|
|||
<vn-item-summary
|
||||
item="$ctrl.itemSelected">
|
||||
</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) {
|
||||
return this.$http.post(`Items/${itemFk}/clone`)
|
||||
.then(res => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="search-panel">
|
||||
<form class="vn-pa-lg" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="General search"
|
||||
|
@ -8,7 +8,7 @@
|
|||
vn-focus>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Ticket id"
|
||||
|
@ -25,7 +25,7 @@
|
|||
<tpl-item>{{nickname}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Client id"
|
||||
|
@ -38,19 +38,37 @@
|
|||
url="Warehouses">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<section class="vn-px-md">
|
||||
<vn-horizontal class="manifold-panel vn-pa-md">
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="From"
|
||||
ng-model="filter.from">
|
||||
ng-model="filter.from"
|
||||
on-change="$ctrl.from = value">
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="To"
|
||||
ng-model="filter.to">
|
||||
ng-model="filter.to"
|
||||
on-change="$ctrl.to = value">
|
||||
</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>
|
||||
</section>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-check vn-one
|
||||
triple-state="true"
|
||||
label="For me"
|
||||
|
@ -65,7 +83,7 @@
|
|||
<tpl-item>{{name}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</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-horizontal>
|
||||
</form>
|
||||
|
|
|
@ -11,6 +11,35 @@ class Controller extends SearchPanel {
|
|||
{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', {
|
||||
|
|
|
@ -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-searchbar
|
||||
panel="vn-request-search-panel"
|
||||
suggested-filter="$ctrl.filterParams"
|
||||
info="Search request by id or alias"
|
||||
suggested-filter="$ctrl.filterParams"
|
||||
filter="$ctrl.filterParams"
|
||||
fetch-params="$ctrl.fetchParams($params)"
|
||||
model="model"
|
||||
auto-state="false">
|
||||
</vn-searchbar>
|
||||
|
|
|
@ -15,7 +15,6 @@ export default class Controller extends Section {
|
|||
nextWeek.setDate(nextWeek.getDate() + 7);
|
||||
|
||||
this.filterParams = {
|
||||
mine: true,
|
||||
from: today,
|
||||
to: nextWeek,
|
||||
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) {
|
||||
if (isOk === null)
|
||||
return 'Pending';
|
||||
|
|
|
@ -162,7 +162,7 @@
|
|||
"acl": ["buyer"]
|
||||
},
|
||||
{
|
||||
"url" : "/fixed-price",
|
||||
"url" : "/fixed-price?q",
|
||||
"state": "item.fixedPrice",
|
||||
"component": "vn-fixed-price",
|
||||
"description": "Fixed prices",
|
||||
|
|
|
@ -55,6 +55,9 @@
|
|||
<vn-label-value label="stems"
|
||||
value="{{$ctrl.summary.item.stems}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Multiplier"
|
||||
value="{{$ctrl.summary.item.stemMultiplier}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Buyer">
|
||||
<span
|
||||
ng-click="workerDescriptor.show($event, $ctrl.summary.item.itemType.worker.userFk)"
|
||||
|
|
|
@ -32,14 +32,14 @@
|
|||
rule>
|
||||
</vn-autocomplete>
|
||||
<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"
|
||||
label="Value"
|
||||
ng-model="itemTag.value"
|
||||
rule>
|
||||
</vn-textfield>
|
||||
<vn-autocomplete vn-three
|
||||
ng-show="tag.selection.isFree === false"
|
||||
ng-if="tag.selection.isFree === false"
|
||||
url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}"
|
||||
search-function="{value: $search}"
|
||||
label="Value"
|
||||
|
|
|
@ -37,7 +37,7 @@ class Controller extends Component {
|
|||
};
|
||||
filter = encodeURIComponent(JSON.stringify(filter));
|
||||
let query = `Clients?filter=${filter}`;
|
||||
this.$http.get(query).then(res => {
|
||||
this.$http.get(query).then(res=> {
|
||||
if (res.data) {
|
||||
let client = res.data[0];
|
||||
let defaultAddress = client.defaultAddress;
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
{
|
||||
"name": "SupplierAccount",
|
||||
"base": "VnModel",
|
||||
"base": "Loggable",
|
||||
"log": {
|
||||
"model":"SupplierLog",
|
||||
"relation": "supplier"
|
||||
},
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "supplierAccount"
|
||||
|
@ -45,6 +49,11 @@
|
|||
"type": "belongsTo",
|
||||
"model": "Supplier",
|
||||
"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 './basic-data';
|
||||
import './fiscal-data';
|
||||
import './account';
|
||||
import './contact';
|
||||
import './log';
|
||||
import './consumption';
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
{"state": "supplier.index", "icon": "icon-supplier"}
|
||||
],
|
||||
"card": [
|
||||
{"state": "supplier.card.account", "icon": "contact_support"},
|
||||
{"state": "supplier.card.basicData", "icon": "settings"},
|
||||
{"state": "supplier.card.fiscalData", "icon": "account_balance"},
|
||||
{"state": "supplier.card.billingData", "icon": "icon-payment"},
|
||||
|
@ -99,6 +100,15 @@
|
|||
"supplier": "$ctrl.supplier"
|
||||
},
|
||||
"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) {
|
||||
const shippedResult = await models.Agency.getShipped(landed,
|
||||
address.id, agencyModeId, warehouseId);
|
||||
shipped = shippedResult && shippedResult.shipped;
|
||||
shipped = (shippedResult && shippedResult.shipped) || landed;
|
||||
}
|
||||
|
||||
if (shipped && !landed) {
|
||||
|
|
|
@ -2,12 +2,13 @@ const app = require('vn-loopback/server/server');
|
|||
let UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
describe('ticket new()', () => {
|
||||
let ticket;
|
||||
let ticketIdsToDelete = [];
|
||||
let today = new Date();
|
||||
let ctx = {req: {accessToken: {userId: 1}}};
|
||||
|
||||
afterAll(async done => {
|
||||
await app.models.Ticket.destroyById(ticket.id);
|
||||
for (id of ticketIdsToDelete)
|
||||
await app.models.Ticket.destroyById(id);
|
||||
|
||||
done();
|
||||
});
|
||||
|
@ -28,7 +29,7 @@ describe('ticket new()', () => {
|
|||
params.shipped,
|
||||
params.landed,
|
||||
params.warehouseId,
|
||||
params.companyFk,
|
||||
params.companyId,
|
||||
params.addressId
|
||||
).catch(e => {
|
||||
error = e;
|
||||
|
@ -53,7 +54,7 @@ describe('ticket new()', () => {
|
|||
params.shipped,
|
||||
params.landed,
|
||||
params.warehouseId,
|
||||
params.companyFk,
|
||||
params.companyId,
|
||||
params.addressId
|
||||
).catch(response => {
|
||||
expect(response.message).toEqual(`This address doesn't exist`);
|
||||
|
@ -74,17 +75,44 @@ describe('ticket new()', () => {
|
|||
agencyModeId: 1
|
||||
};
|
||||
|
||||
ticket = await app.models.Ticket.new(ctx,
|
||||
const ticket = await app.models.Ticket.new(ctx,
|
||||
params.clientId,
|
||||
params.shipped,
|
||||
params.landed,
|
||||
params.warehouseId,
|
||||
params.companyFk,
|
||||
params.companyId,
|
||||
params.addressId,
|
||||
params.agencyModeId);
|
||||
|
||||
let newestTicketIdInFixtures = 21;
|
||||
|
||||
ticketIdsToDelete.push(ticket.id);
|
||||
|
||||
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
|
||||
disabled="!$ctrl.clientId || !$ctrl.landed || !$ctrl.warehouseId"
|
||||
data="$ctrl._availableAgencies"
|
||||
data="$ctrl.agencies"
|
||||
label="Agency"
|
||||
show-field="agencyMode"
|
||||
value-field="agencyModeFk"
|
||||
|
|
|
@ -100,9 +100,12 @@ class Controller extends Component {
|
|||
ticket.agencyModeFk = null;
|
||||
|
||||
this.$http.get(`Agencies/getAgenciesWithWarehouse`, {params}).then(res => {
|
||||
this._availableAgencies = res.data;
|
||||
|
||||
this.agencyModeId = this.defaultAddress.agencyModeFk;
|
||||
this.agencies = res.data;
|
||||
const defaultAgency = this.agencies.find(agency=> {
|
||||
return agency.agencyModeFk == this.defaultAddress.agencyModeFk;
|
||||
});
|
||||
if (defaultAgency)
|
||||
this.agencyModeId = defaultAgency.agencyModeFk;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,4 +116,7 @@
|
|||
</vn-button-menu>
|
||||
</div>
|
||||
</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">
|
||||
</vn-icon>
|
||||
</vn-horizontal>
|
||||
<vn-table class="destinationTable">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number>Id</vn-th>
|
||||
<vn-th number>Shipped</vn-th>
|
||||
<vn-th number>Agency</vn-th>
|
||||
<vn-th number>Warehouse</vn-th>
|
||||
<vn-th number>Address</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-data-viewer data="$ctrl.transfer.lastActiveTickets">
|
||||
</vn-data-viewer>
|
||||
<vn-tr
|
||||
<table class="destinationTable vn-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th translate shrink>Id</th>
|
||||
<th translate>Shipped</th>
|
||||
<th translate shrink>Agency</th>
|
||||
<th translate expand>Address</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
class="clickable"
|
||||
ng-repeat="ticket in $ctrl.transfer.lastActiveTickets track by ticket.id"
|
||||
ng-click="$ctrl.transferSales(ticket.id)">
|
||||
<vn-td number>{{::ticket.id}}</vn-td>
|
||||
<vn-td number>{{::ticket.shipped | date: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{::ticket.agencyName}}</vn-td>
|
||||
<vn-td number>{{::ticket.warehouseName}}</vn-td>
|
||||
<vn-td number>{{::ticket.address}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
<td shrink>{{::ticket.id}}</td>
|
||||
<td>{{::ticket.shipped | date: 'dd/MM/yyyy'}}</td>
|
||||
<td shrink>{{::ticket.agencyName}}</td>
|
||||
<td expand>{{::ticket.address}}
|
||||
<span vn-tooltip="
|
||||
{{::ticket.nickname}}
|
||||
{{::ticket.name}}
|
||||
{{::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">
|
||||
<vn-horizontal class="vn-py-md">
|
||||
<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/updateThermograph')(Self);
|
||||
require('../methods/travel/extraCommunityFilter')(Self);
|
||||
require('../methods/travel/getAverageDays')(Self);
|
||||
require('../methods/travel/cloneWithEntries')(Self);
|
||||
|
||||
Self.rewriteDbError(function(err) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-date-picker
|
||||
on-change="$ctrl.onShippedChange(value)"
|
||||
label="Shipped"
|
||||
ng-model="$ctrl.travel.shipped">
|
||||
</vn-date-picker>
|
||||
|
|
|
@ -7,6 +7,34 @@ class Controller extends Section {
|
|||
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() {
|
||||
return this.$.watcher.submit().then(
|
||||
res => this.$state.go('travel.card.basicData', {id: res.data.id})
|
||||
|
|
|
@ -5,10 +5,12 @@ describe('Travel Component vnTravelCreate', () => {
|
|||
let $scope;
|
||||
let $state;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('travel'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope, _$state_) => {
|
||||
beforeEach(inject(($componentController, $rootScope, _$state_, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = $rootScope.$new();
|
||||
$state = _$state_;
|
||||
$scope.watcher = watcher;
|
||||
|
@ -38,4 +40,49 @@ describe('Travel Component vnTravelCreate', () => {
|
|||
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",
|
||||
"foreignKey": "userFk"
|
||||
},
|
||||
"boss": {
|
||||
"type": "belongsTo",
|
||||
"model": "Account",
|
||||
"foreignKey": "bossFk"
|
||||
},
|
||||
"client": {
|
||||
"type": "belongsTo",
|
||||
"model": "Client",
|
||||
|
|
|
@ -29,6 +29,15 @@
|
|||
ng-model="$ctrl.worker.phone"
|
||||
rule>
|
||||
</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-vertical>
|
||||
</vn-card>
|
||||
|
|
|
@ -7,6 +7,7 @@ Extension: Extensión
|
|||
Fiscal identifier: NIF
|
||||
Go to client: Ir al cliente
|
||||
Last name: Apellidos
|
||||
Boss: Jefe
|
||||
Log: Historial
|
||||
Private Branch Exchange: Centralita
|
||||
Role: Rol
|
||||
|
|
|
@ -30,6 +30,14 @@
|
|||
<vn-label-value label="Department"
|
||||
value="{{worker.department.department.name}}">
|
||||
</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"
|
||||
value="{{worker.phone}}">
|
||||
</vn-label-value>
|
||||
|
@ -50,4 +58,7 @@
|
|||
</vn-label-value>
|
||||
</vn-one>
|
||||
</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;
|
||||
if (!value) return;
|
||||
|
||||
let query = `Workers/${value.id}`;
|
||||
let filter = {
|
||||
const query = `Workers/${value.id}`;
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'user',
|
||||
|
@ -31,13 +31,20 @@ class Controller extends Summary {
|
|||
}
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {fields: ['fi']}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
relation: 'boss',
|
||||
scope: {fields: ['id', 'nickname']}
|
||||
},
|
||||
{
|
||||
relation: 'sip',
|
||||
scope: {fields: ['extension']}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
relation: 'department',
|
||||
scope: {
|
||||
include: {
|
||||
|
|
|
@ -10606,15 +10606,50 @@
|
|||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
}
|
||||
"bluebird": {
|
||||
"version": "3.5.5",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
|
||||
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w=="
|
||||
},
|
||||
"bmp-js": {
|
||||
"version": "0.1.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": {
|
||||
"version": "1.2.1",
|
||||
|
@ -11677,11 +11712,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
"color": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
|
||||
"integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.1",
|
||||
"color-string": "^1.5.4"
|
||||
}
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
|
@ -11693,15 +11731,19 @@
|
|||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"anymatch": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
|
||||
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
}
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"color-string": {
|
||||
"version": "1.5.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": {
|
||||
"version": "2.0.0",
|
||||
|
@ -14271,15 +14313,18 @@
|
|||
"@types/yargs-parser": "*"
|
||||
}
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/color-name": "^1.1.1",
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
"file-type": {
|
||||
"version": "10.11.0",
|
||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz",
|
||||
"integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw=="
|
||||
},
|
||||
"filed-mimefix": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/filed-mimefix/-/filed-mimefix-0.1.3.tgz",
|
||||
"integrity": "sha1-Cwtn0HWmP8dPJv3znH+dQxSWe7U=",
|
||||
"requires": {
|
||||
"mime": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.0",
|
||||
|
@ -14460,30 +14505,33 @@
|
|||
"write-file-atomic": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"@jest/types": {
|
||||
"version": "26.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
|
||||
"integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||
"@types/istanbul-reports": "^1.1.1",
|
||||
"@types/yargs": "^15.0.0",
|
||||
"chalk": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@types/babel__core": {
|
||||
"version": "7.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz",
|
||||
"integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/parser": "^7.1.0",
|
||||
"@babel/types": "^7.0.0",
|
||||
"@types/babel__generator": "*",
|
||||
"@types/babel__template": "*",
|
||||
"@types/babel__traverse": "*"
|
||||
}
|
||||
"fs-mkdirp-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.11",
|
||||
"through2": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"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.1",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/yargs": {
|
||||
"version": "15.0.5",
|
||||
|
@ -15323,18 +15371,73 @@
|
|||
"@jest/types": "^26.0.1"
|
||||
}
|
||||
},
|
||||
"jest-util": {
|
||||
"version": "26.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz",
|
||||
"integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jest/types": "^26.0.1",
|
||||
"chalk": "^4.0.0",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"is-ci": "^2.0.0",
|
||||
"make-dir": "^3.0.0"
|
||||
}
|
||||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||
},
|
||||
"ienoopen": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz",
|
||||
"integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ=="
|
||||
},
|
||||
"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": {
|
||||
"version": "3.1.0",
|
||||
|
@ -17243,28 +17346,53 @@
|
|||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
|
||||
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"dev": true
|
||||
"mississippi": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
|
||||
"integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"concat-stream": "^1.5.0",
|
||||
"duplexify": "^3.4.2",
|
||||
"end-of-stream": "^1.1.0",
|
||||
"flush-write-stream": "^1.0.0",
|
||||
"from2": "^2.1.0",
|
||||
"parallel-transform": "^1.1.0",
|
||||
"pump": "^3.0.0",
|
||||
"pumpify": "^1.3.3",
|
||||
"stream-each": "^1.1.0",
|
||||
"through2": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"concat-stream": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||
"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": {
|
||||
"version": "4.2.4",
|
||||
|
@ -17455,20 +17583,23 @@
|
|||
"picomatch": "^2.0.5"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-limit": "^2.2.0"
|
||||
}
|
||||
"nocache": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz",
|
||||
"integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q=="
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||
"dev": true
|
||||
"node-abi": {
|
||||
"version": "2.19.3",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.3.tgz",
|
||||
"integrity": "sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg==",
|
||||
"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": {
|
||||
"version": "26.0.1",
|
||||
|
@ -17992,11 +18123,10 @@
|
|||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
"p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
|
||||
},
|
||||
"is-ci": {
|
||||
"version": "2.0.0",
|
||||
|
@ -18455,16 +18585,58 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
|
||||
"integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ip-regex": "^2.1.0",
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
}
|
||||
"postcss-value-parser": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
|
||||
"integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
|
||||
"dev": true
|
||||
},
|
||||
"prebuild-install": {
|
||||
"version": "6.0.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": {
|
||||
"version": "7.3.0",
|
||||
|
@ -19264,15 +19436,25 @@
|
|||
"path-key": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"os-locale": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-5.0.0.tgz",
|
||||
"integrity": "sha512-tqZcNEDAIZKBEPnHPlVDvKrp7NzgLi7jRmhKiUoa2NUmhl13FtkAGLUVR+ZsYvApBQdBfYm43A4tXXQ4IrYLBA==",
|
||||
"requires": {
|
||||
"execa": "^4.0.0",
|
||||
"lcid": "^3.0.0",
|
||||
"mem": "^5.0.0"
|
||||
}
|
||||
"read-chunk": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-3.2.0.tgz",
|
||||
"integrity": "sha512-CEjy9LCzhmD7nUpJ1oVOE6s/hBkejlcJEgLQHVnQznOSilOPb+kpKktlLfFDK3/WP43+F80xkUTM2VOkYoSYvQ==",
|
||||
"requires": {
|
||||
"pify": "^4.0.1",
|
||||
"with-open-file": "^0.1.6"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"version": "3.1.1",
|
||||
|
@ -21962,15 +22144,50 @@
|
|||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
}
|
||||
"sharp": {
|
||||
"version": "0.27.1",
|
||||
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.27.1.tgz",
|
||||
"integrity": "sha512-IQNXWdspb4nZcJemXa6cfgz+JvKONsuqP8Mwi1Oti23Uo7+J+UF2jihJDf6I1BQbrmhcZ0lagH/1WYG+ReAzyQ==",
|
||||
"requires": {
|
||||
"array-flatten": "^3.0.0",
|
||||
"color": "^3.1.3",
|
||||
"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": {
|
||||
"version": "4.0.0",
|
||||
|
@ -24125,74 +24342,64 @@
|
|||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
|
||||
}
|
||||
}
|
||||
},
|
||||
"strong-globalize": {
|
||||
"version": "4.1.3",
|
||||
"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"
|
||||
}
|
||||
"tar-fs": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
|
||||
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
"pump": "^3.0.0",
|
||||
"tar-stream": "^2.1.4"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"strong-remoting": {
|
||||
"version": "3.16.2",
|
||||
"resolved": "https://registry.npmjs.org/strong-remoting/-/strong-remoting-3.16.2.tgz",
|
||||
"integrity": "sha512-Kj8dZh6q0F3GQTil2rkEt6WuQoQbXFRZ2AJG36iBPmxcVEE9bVhWXUYxcJIxXaGekCprxp8kfdLLN67yp0J4Hg==",
|
||||
"requires": {
|
||||
"async": "^3.1.0",
|
||||
"body-parser": "^1.12.4",
|
||||
"debug": "^4.1.1",
|
||||
"depd": "^2.0.0",
|
||||
"escape-string-regexp": "^2.0.0",
|
||||
"eventemitter2": "^5.0.1",
|
||||
"express": "4.x",
|
||||
"inflection": "^1.7.1",
|
||||
"jayson": "^2.0.5",
|
||||
"js2xmlparser": "^3.0.0",
|
||||
"loopback-datatype-geopoint": "^1.0.0",
|
||||
"loopback-phase": "^3.1.0",
|
||||
"mux-demux": "^3.7.9",
|
||||
"qs": "^6.2.1",
|
||||
"request": "^2.83.0",
|
||||
"sse": "0.0.8",
|
||||
"strong-error-handler": "^3.0.0",
|
||||
"strong-globalize": "^5.0.2",
|
||||
"traverse": "^0.6.6",
|
||||
"xml2js": "^0.4.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
|
||||
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
|
||||
"tar-stream": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||
"requires": {
|
||||
"bl": "^4.0.3",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"fs-constants": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.1.1"
|
||||
},
|
||||
"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=="
|
||||
},
|
||||
"bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"requires": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"requires": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"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": {
|
||||
"version": "7.0.3",
|
||||
|
@ -24609,14 +24816,38 @@
|
|||
"readable-stream": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
|
||||
"integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4"
|
||||
}
|
||||
"uid2": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
|
||||
"integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
|
||||
},
|
||||
"unbzip2-stream": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
|
||||
"integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
|
||||
"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": {
|
||||
"version": "3.6.0",
|
||||
|
@ -26380,14 +26611,41 @@
|
|||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||
"dev": true
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
"with-open-file": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/with-open-file/-/with-open-file-0.1.7.tgz",
|
||||
"integrity": "sha512-ecJS2/oHtESJ1t3ZfMI3B7KIDKyfN0O16miWxdn30zdh66Yd3LsRFebXZXq6GU4xfxLf6nVxp9kIqElb5fqczA==",
|
||||
"requires": {
|
||||
"p-finally": "^1.0.0",
|
||||
"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": {
|
||||
"version": "6.3.0",
|
||||
|
|
|
@ -12,10 +12,12 @@
|
|||
"node": ">=12"
|
||||
},
|
||||
"dependencies": {
|
||||
"bmp-js": "^0.1.0",
|
||||
"compression": "^1.7.3",
|
||||
"fs-extra": "^5.0.0",
|
||||
"helmet": "^3.21.2",
|
||||
"i18n": "^0.8.4",
|
||||
"image-type": "^4.1.0",
|
||||
"imap": "^0.8.19",
|
||||
"ldapjs": "^2.2.0",
|
||||
"loopback": "^3.26.0",
|
||||
|
@ -30,10 +32,11 @@
|
|||
"node-ssh": "^11.0.0",
|
||||
"object-diff": "0.0.4",
|
||||
"object.pick": "^1.3.0",
|
||||
"read-chunk": "^3.2.0",
|
||||
"request": "^2.88.0",
|
||||
"request-promise-native": "^1.0.8",
|
||||
"require-yaml": "0.0.1",
|
||||
"sharp": "^0.25.4",
|
||||
"sharp": "^0.27.1",
|
||||
"smbhash": "0.0.1",
|
||||
"soap": "^0.35.0",
|
||||
"strong-error-handler": "^2.3.2",
|
||||
|
|
Loading…
Reference in New Issue