Merge branch 'dev' into 5128-client.credit-management
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
ea1035311e
|
@ -0,0 +1,130 @@
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
const path = require('path');
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('scrub', {
|
||||||
|
description: 'Deletes images without database reference',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'collection',
|
||||||
|
type: 'string',
|
||||||
|
description: 'The collection name',
|
||||||
|
required: true
|
||||||
|
}, {
|
||||||
|
arg: 'remove',
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Delete instead of move images to trash'
|
||||||
|
}, {
|
||||||
|
arg: 'limit',
|
||||||
|
type: 'integer',
|
||||||
|
description: 'Maximum number of images to clean'
|
||||||
|
}, {
|
||||||
|
arg: 'dryRun',
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Simulate actions'
|
||||||
|
}, {
|
||||||
|
arg: 'skipLock',
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Wether to skip exclusive lock'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: 'integer',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/scrub`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.scrub = async function(collection, remove, limit, dryRun, skipLock) {
|
||||||
|
const $ = Self.app.models;
|
||||||
|
|
||||||
|
const env = process.env.NODE_ENV;
|
||||||
|
dryRun = dryRun || (env && env !== 'production');
|
||||||
|
|
||||||
|
const instance = await $.ImageCollection.findOne({
|
||||||
|
fields: ['id'],
|
||||||
|
where: {name: collection}
|
||||||
|
});
|
||||||
|
if (!instance)
|
||||||
|
throw new UserError('Collection does not exist');
|
||||||
|
|
||||||
|
const container = await $.ImageContainer.container(collection);
|
||||||
|
const rootPath = container.client.root;
|
||||||
|
|
||||||
|
let tx;
|
||||||
|
let opts;
|
||||||
|
const lockName = 'salix.Image.scrub';
|
||||||
|
|
||||||
|
if (!skipLock) {
|
||||||
|
tx = await Self.beginTransaction({timeout: null});
|
||||||
|
opts = {transaction: tx};
|
||||||
|
|
||||||
|
const [row] = await Self.rawSql(
|
||||||
|
`SELECT GET_LOCK(?, 10) hasLock`, [lockName], opts);
|
||||||
|
if (!row.hasLock)
|
||||||
|
throw new UserError('Cannot obtain exclusive lock');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const now = Date.vnNew().toJSON();
|
||||||
|
const scrubDir = path.join(rootPath, '.scrub', now);
|
||||||
|
|
||||||
|
const collectionDir = path.join(rootPath, collection);
|
||||||
|
const sizes = await fs.readdir(collectionDir);
|
||||||
|
let cleanCount = 0;
|
||||||
|
|
||||||
|
mainLoop: for (const size of sizes) {
|
||||||
|
const sizeDir = path.join(collectionDir, size);
|
||||||
|
const scrubSizeDir = path.join(scrubDir, collection, size);
|
||||||
|
const images = await fs.readdir(sizeDir);
|
||||||
|
for (const image of images) {
|
||||||
|
const imageName = path.parse(image).name;
|
||||||
|
const count = await Self.count({
|
||||||
|
collectionFk: collection,
|
||||||
|
name: imageName
|
||||||
|
}, opts);
|
||||||
|
const exists = count > 0;
|
||||||
|
let scrubDirCreated = false;
|
||||||
|
if (!exists) {
|
||||||
|
const srcFile = path.join(sizeDir, image);
|
||||||
|
if (remove !== true) {
|
||||||
|
if (!scrubDirCreated) {
|
||||||
|
if (!dryRun)
|
||||||
|
await fs.mkdir(scrubSizeDir, {recursive: true});
|
||||||
|
scrubDirCreated = true;
|
||||||
|
}
|
||||||
|
const dstFile = path.join(scrubSizeDir, image);
|
||||||
|
if (!dryRun) await fs.rename(srcFile, dstFile);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (!dryRun) await fs.unlink(srcFile);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanCount++;
|
||||||
|
if (limit && cleanCount == limit)
|
||||||
|
break mainLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cleanCount;
|
||||||
|
} finally {
|
||||||
|
if (!skipLock) {
|
||||||
|
try {
|
||||||
|
await Self.rawSql(`DO RELEASE_LOCK(?)`, [lockName], opts);
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -12,13 +12,13 @@ module.exports = Self => {
|
||||||
type: 'Number',
|
type: 'Number',
|
||||||
description: 'The entity id',
|
description: 'The entity id',
|
||||||
required: true
|
required: true
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
arg: 'collection',
|
arg: 'collection',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'The collection name',
|
description: 'The collection name',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'Object',
|
type: 'Object',
|
||||||
root: true
|
root: true
|
||||||
|
|
|
@ -5,6 +5,7 @@ const gm = require('gm');
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/image/download')(Self);
|
require('../methods/image/download')(Self);
|
||||||
require('../methods/image/upload')(Self);
|
require('../methods/image/upload')(Self);
|
||||||
|
require('../methods/image/scrub')(Self);
|
||||||
|
|
||||||
Self.resize = async function({collectionName, srcFile, fileName, entityId}) {
|
Self.resize = async function({collectionName, srcFile, fileName, entityId}) {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
@ -29,13 +30,14 @@ module.exports = Self => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Insert image row
|
// Insert image row
|
||||||
|
const imageName = path.parse(fileName).name;
|
||||||
await models.Image.upsertWithWhere(
|
await models.Image.upsertWithWhere(
|
||||||
{
|
{
|
||||||
name: fileName,
|
name: imageName,
|
||||||
collectionFk: collectionName
|
collectionFk: collectionName
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: fileName,
|
name: imageName,
|
||||||
collectionFk: collectionName,
|
collectionFk: collectionName,
|
||||||
updated: Date.vnNow() / 1000,
|
updated: Date.vnNow() / 1000,
|
||||||
}
|
}
|
||||||
|
@ -49,7 +51,7 @@ module.exports = Self => {
|
||||||
if (entity) {
|
if (entity) {
|
||||||
await entity.updateAttribute(
|
await entity.updateAttribute(
|
||||||
collection.property,
|
collection.property,
|
||||||
fileName
|
imageName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ async function test() {
|
||||||
const JunitReporter = require('jasmine-reporters');
|
const JunitReporter = require('jasmine-reporters');
|
||||||
jasmine.addReporter(new JunitReporter.JUnitXmlReporter());
|
jasmine.addReporter(new JunitReporter.JUnitXmlReporter());
|
||||||
|
|
||||||
jasmine.jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
|
jasmine.jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000;
|
||||||
jasmine.exitOnCompletion = true;
|
jasmine.exitOnCompletion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `vn`.`printQueueArgs` MODIFY COLUMN value varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL;
|
|
@ -1,12 +1,5 @@
|
||||||
DROP TABLE IF EXISTS `vn`.`dmsRecover`;
|
DROP TABLE IF EXISTS `vn`.`dmsRecover`;
|
||||||
|
DROP PROCEDURE IF EXISTS `vn`.`route_getTickets`;
|
||||||
ALTER TABLE `vn`.`delivery` DROP COLUMN addressFk;
|
|
||||||
ALTER TABLE `vn`.`delivery` DROP CONSTRAINT delivery_ticketFk_FK;
|
|
||||||
ALTER TABLE `vn`.`delivery` DROP COLUMN ticketFk;
|
|
||||||
ALTER TABLE `vn`.`delivery` ADD ticketFk INT DEFAULT NULL;
|
|
||||||
ALTER TABLE `vn`.`delivery` ADD CONSTRAINT delivery_ticketFk_FK FOREIGN KEY (`ticketFk`) REFERENCES `vn`.`ticket`(`id`);
|
|
||||||
|
|
||||||
DROP PROCEDURE IF EXISTS vn.route_getTickets;
|
|
||||||
|
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
$$
|
$$
|
||||||
|
@ -17,54 +10,68 @@ BEGIN
|
||||||
* de sus tickets.
|
* de sus tickets.
|
||||||
*
|
*
|
||||||
* @param vRouteFk
|
* @param vRouteFk
|
||||||
*
|
|
||||||
* @select Información de los tickets
|
* @select Información de los tickets
|
||||||
*/
|
*/
|
||||||
|
SELECT *
|
||||||
SELECT
|
FROM (
|
||||||
t.id Id,
|
SELECT t.id Id,
|
||||||
t.clientFk Client,
|
t.clientFk Client,
|
||||||
a.id Address,
|
a.id Address,
|
||||||
t.packages Packages,
|
a.nickname ClientName,
|
||||||
a.street AddressName,
|
t.packages Packages,
|
||||||
a.postalCode PostalCode,
|
a.street AddressName,
|
||||||
a.city City,
|
a.postalCode PostalCode,
|
||||||
sub2.itemPackingTypeFk PackingType,
|
a.city City,
|
||||||
c.phone ClientPhone,
|
sub2.itemPackingTypeFk PackingType,
|
||||||
c.mobile ClientMobile,
|
c.phone ClientPhone,
|
||||||
a.phone AddressPhone,
|
c.mobile ClientMobile,
|
||||||
a.mobile AddressMobile,
|
a.phone AddressPhone,
|
||||||
d.longitude Longitude,
|
a.mobile AddressMobile,
|
||||||
d.latitude Latitude,
|
d.longitude Longitude,
|
||||||
wm.mediaValue SalePersonPhone,
|
d.latitude Latitude,
|
||||||
tob.Note Note,
|
wm.mediaValue SalePersonPhone,
|
||||||
t.isSigned Signed
|
tob.description Note,
|
||||||
FROM ticket t
|
t.isSigned Signed,
|
||||||
JOIN client c ON t.clientFk = c.id
|
t.priority
|
||||||
JOIN address a ON t.addressFk = a.id
|
FROM ticket t
|
||||||
LEFT JOIN delivery d ON t.id = d.ticketFk
|
JOIN client c ON t.clientFk = c.id
|
||||||
LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk
|
JOIN address a ON t.addressFk = a.id
|
||||||
LEFT JOIN
|
LEFT JOIN delivery d ON d.ticketFk = t.id
|
||||||
(SELECT tob.description Note, t.id
|
LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk
|
||||||
FROM ticketObservation tob
|
LEFT JOIN(
|
||||||
JOIN ticket t ON tob.ticketFk = t.id
|
SELECT tob.description, t.id
|
||||||
JOIN observationType ot ON ot.id = tob.observationTypeFk
|
FROM ticketObservation tob
|
||||||
WHERE t.routeFk = vRouteFk
|
JOIN ticket t ON tob.ticketFk = t.id
|
||||||
AND ot.code = 'delivery'
|
JOIN observationType ot ON ot.id = tob.observationTypeFk
|
||||||
)tob ON tob.id = t.id
|
WHERE t.routeFk = vRouteFk
|
||||||
LEFT JOIN
|
AND ot.code = 'delivery'
|
||||||
(SELECT sub.ticketFk,
|
)tob ON tob.id = t.id
|
||||||
CONCAT('(', GROUP_CONCAT(DISTINCT sub.itemPackingTypeFk ORDER BY sub.items DESC SEPARATOR ','), ') ') itemPackingTypeFk
|
LEFT JOIN(
|
||||||
FROM (SELECT s.ticketFk , i.itemPackingTypeFk, COUNT(*) items
|
SELECT sub.ticketFk,
|
||||||
FROM ticket t
|
CONCAT('(',
|
||||||
JOIN sale s ON s.ticketFk = t.id
|
GROUP_CONCAT(DISTINCT sub.itemPackingTypeFk
|
||||||
JOIN item i ON i.id = s.itemFk
|
ORDER BY sub.items DESC SEPARATOR ','),
|
||||||
WHERE t.routeFk = vRouteFk
|
') ') itemPackingTypeFk
|
||||||
GROUP BY t.id,i.itemPackingTypeFk)sub
|
FROM (
|
||||||
GROUP BY sub.ticketFk
|
SELECT s.ticketFk, i.itemPackingTypeFk, COUNT(*) items
|
||||||
) sub2 ON sub2.ticketFk = t.id
|
FROM ticket t
|
||||||
WHERE t.routeFk = vRouteFk
|
JOIN sale s ON s.ticketFk = t.id
|
||||||
GROUP BY t.id
|
JOIN item i ON i.id = s.itemFk
|
||||||
ORDER BY t.priority;
|
WHERE t.routeFk = vRouteFk
|
||||||
|
GROUP BY t.id, i.itemPackingTypeFk
|
||||||
|
)sub
|
||||||
|
GROUP BY sub.ticketFk
|
||||||
|
)sub2 ON sub2.ticketFk = t.id
|
||||||
|
WHERE t.routeFk = vRouteFk
|
||||||
|
ORDER BY d.id DESC
|
||||||
|
LIMIT 10000000000000000000
|
||||||
|
)sub3
|
||||||
|
GROUP BY sub3.id
|
||||||
|
ORDER BY sub3.priority;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
||||||
|
ALTER TABLE `vn`.`delivery` DROP FOREIGN KEY delivery_ticketFk_FK;
|
||||||
|
ALTER TABLE `vn`.`delivery` DROP COLUMN ticketFk;
|
||||||
|
ALTER TABLE `vn`.`delivery` ADD ticketFk INT DEFAULT NULL;
|
||||||
|
ALTER TABLE `vn`.`delivery` ADD CONSTRAINT delivery_ticketFk_FK FOREIGN KEY (`ticketFk`) REFERENCES `vn`.`ticket`(`id`);
|
||||||
|
|
|
@ -173,10 +173,6 @@ INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `isPreviousPrepare
|
||||||
(1, 'First sector', 1, 1, 'FIRST'),
|
(1, 'First sector', 1, 1, 'FIRST'),
|
||||||
(2, 'Second sector', 2, 0, 'SECOND');
|
(2, 'Second sector', 2, 0, 'SECOND');
|
||||||
|
|
||||||
INSERT INTO `vn`.`operator` (`workerFk`, `numberOfWagons`, `trainFk`, `itemPackingTypeFk`, `warehouseFk`, `sectorFk`, `labelerFk`)
|
|
||||||
VALUES ('1106', '1', '1', 'H', '1', '1', '1'),
|
|
||||||
('1107', '1', '1', 'V', '1', '2', '1');
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`printer` (`id`, `name`, `path`, `isLabeler`, `sectorFk`, `ipAddress`)
|
INSERT INTO `vn`.`printer` (`id`, `name`, `path`, `isLabeler`, `sectorFk`, `ipAddress`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'printer1', 'path1', 0, 1 , NULL),
|
(1, 'printer1', 'path1', 0, 1 , NULL),
|
||||||
|
@ -1200,6 +1196,11 @@ INSERT INTO `vn`.`train`(`id`, `name`)
|
||||||
(1, 'Train1'),
|
(1, 'Train1'),
|
||||||
(2, 'Train2');
|
(2, 'Train2');
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`operator` (`workerFk`, `numberOfWagons`, `trainFk`, `itemPackingTypeFk`, `warehouseFk`, `sectorFk`, `labelerFk`)
|
||||||
|
VALUES
|
||||||
|
('1106', '1', '1', 'H', '1', '1', '1'),
|
||||||
|
('1107', '1', '1', 'V', '1', '1', '1');
|
||||||
|
|
||||||
INSERT INTO `vn`.`collection`(`id`, `workerFk`, `stateFk`, `created`, `trainFk`)
|
INSERT INTO `vn`.`collection`(`id`, `workerFk`, `stateFk`, `created`, `trainFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1106, 5, DATE_ADD(util.VN_CURDATE(),INTERVAL +1 DAY), 1),
|
(1, 1106, 5, DATE_ADD(util.VN_CURDATE(),INTERVAL +1 DAY), 1),
|
||||||
|
|
|
@ -66,7 +66,6 @@
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-tbody>
|
</vn-tbody>
|
||||||
</vn-table>
|
</vn-table>
|
||||||
<vn-pagination model="model"></vn-pagination>
|
|
||||||
</vn-card>
|
</vn-card>
|
||||||
</vn-data-viewer>
|
</vn-data-viewer>
|
||||||
<vn-worker-descriptor-popover vn-id="workerDescriptor">
|
<vn-worker-descriptor-popover vn-id="workerDescriptor">
|
||||||
|
|
|
@ -21,8 +21,8 @@ module.exports = function(Self) {
|
||||||
let orgBeginTransaction = this.beginTransaction;
|
let orgBeginTransaction = this.beginTransaction;
|
||||||
this.beginTransaction = function(options, cb) {
|
this.beginTransaction = function(options, cb) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
if (!options.timeout)
|
if (options.timeout === undefined)
|
||||||
options.timeout = 120000;
|
options.timeout = 120 * 1000;
|
||||||
return orgBeginTransaction.call(this, options, cb);
|
return orgBeginTransaction.call(this, options, cb);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -158,4 +158,4 @@
|
||||||
"Description cannot be blank": "Description cannot be blank",
|
"Description cannot be blank": "Description cannot be blank",
|
||||||
"Added observation": "Added observation",
|
"Added observation": "Added observation",
|
||||||
"Comment added to client": "Comment added to client"
|
"Comment added to client": "Comment added to client"
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,6 +272,8 @@
|
||||||
"Tickets with associated refunds": "No se pueden borrar tickets con abonos asociados. Este ticket está asociado al abono Nº {{id}}",
|
"Tickets with associated refunds": "No se pueden borrar tickets con abonos asociados. Este ticket está asociado al abono Nº {{id}}",
|
||||||
"Not exist this branch": "La rama no existe",
|
"Not exist this branch": "La rama no existe",
|
||||||
"This ticket cannot be signed because it has not been boxed": "Este ticket no puede firmarse porque no ha sido encajado",
|
"This ticket cannot be signed because it has not been boxed": "Este ticket no puede firmarse porque no ha sido encajado",
|
||||||
|
"Collection does not exist": "La colección no existe",
|
||||||
|
"Cannot obtain exclusive lock": "No se puede obtener un bloqueo exclusivo",
|
||||||
"Insert a date range": "Inserte un rango de fechas",
|
"Insert a date range": "Inserte un rango de fechas",
|
||||||
"Added observation": "{{user}} añadió esta observacion: {{text}}",
|
"Added observation": "{{user}} añadió esta observacion: {{text}}",
|
||||||
"Comment added to client": "Observación añadida al cliente {{clientFk}}",
|
"Comment added to client": "Observación añadida al cliente {{clientFk}}",
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"legacyUtcDateProcessing": false,
|
"legacyUtcDateProcessing": false,
|
||||||
"timezone": "local",
|
"timezone": "local",
|
||||||
"connectTimeout": 40000,
|
"connectTimeout": 40000,
|
||||||
"acquireTimeout": 60000,
|
"acquireTimeout": 90000,
|
||||||
"waitForConnections": true
|
"waitForConnections": true
|
||||||
},
|
},
|
||||||
"osticket": {
|
"osticket": {
|
||||||
|
|
|
@ -21,7 +21,7 @@ module.exports = Self => {
|
||||||
id,
|
id,
|
||||||
params
|
params
|
||||||
FROM clientConsumptionQueue
|
FROM clientConsumptionQueue
|
||||||
WHERE status = ''`);
|
WHERE status = '' OR status IS NULL`);
|
||||||
|
|
||||||
for (const queue of queues) {
|
for (const queue of queues) {
|
||||||
try {
|
try {
|
||||||
|
@ -44,16 +44,23 @@ module.exports = Self => {
|
||||||
GROUP BY c.id`, [params.clients, params.from, params.to]);
|
GROUP BY c.id`, [params.clients, params.from, params.to]);
|
||||||
|
|
||||||
for (const client of clients) {
|
for (const client of clients) {
|
||||||
const args = {
|
try {
|
||||||
id: client.clientFk,
|
const args = {
|
||||||
recipient: client.clientEmail,
|
id: client.clientFk,
|
||||||
replyTo: client.salesPersonEmail,
|
recipient: client.clientEmail,
|
||||||
from: params.from,
|
replyTo: client.salesPersonEmail,
|
||||||
to: params.to
|
from: params.from,
|
||||||
};
|
to: params.to
|
||||||
|
};
|
||||||
|
|
||||||
const email = new Email('campaign-metrics', args);
|
const email = new Email('campaign-metrics', args);
|
||||||
await email.send();
|
await email.send();
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code === 'EENVELOPE')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Self.rawSql(`
|
await Self.rawSql(`
|
||||||
|
|
|
@ -98,6 +98,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
stmt.merge(conn.makeWhere(args.filter.where));
|
stmt.merge(conn.makeWhere(args.filter.where));
|
||||||
stmt.merge(conn.makeOrderBy(args.filter.order));
|
stmt.merge(conn.makeOrderBy(args.filter.order));
|
||||||
|
stmt.merge(conn.makeLimit(args.filter));
|
||||||
|
|
||||||
const negativeBasesIndex = stmts.push(stmt) - 1;
|
const negativeBasesIndex = stmts.push(stmt) - 1;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="InvoiceIns/negativeBases"
|
url="InvoiceIns/negativeBases"
|
||||||
auto-load="true"
|
auto-load="true"
|
||||||
params="$ctrl.params">
|
params="$ctrl.params"
|
||||||
|
limit="20">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-portal slot="topbar">
|
<vn-portal slot="topbar">
|
||||||
</vn-portal>
|
</vn-portal>
|
||||||
|
|
|
@ -37,7 +37,7 @@ describe('Item editFixedPrice()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const filter = {'it.categoryFk': 1};
|
const filter = {where: {'it.categoryFk': 1}};
|
||||||
const ctx = {
|
const ctx = {
|
||||||
args: {
|
args: {
|
||||||
filter: filter
|
filter: filter
|
||||||
|
@ -48,7 +48,7 @@ describe('Item editFixedPrice()', () => {
|
||||||
const field = 'rate2';
|
const field = 'rate2';
|
||||||
const newValue = 88;
|
const newValue = 88;
|
||||||
|
|
||||||
await models.FixedPrice.editFixedPrice(ctx, field, newValue, null, filter, options);
|
await models.FixedPrice.editFixedPrice(ctx, field, newValue, null, filter.where, options);
|
||||||
|
|
||||||
const [result] = await models.FixedPrice.filter(ctx, filter, options);
|
const [result] = await models.FixedPrice.filter(ctx, filter, options);
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,9 @@
|
||||||
<th field="stateFk">
|
<th field="stateFk">
|
||||||
<span translate>State</span>
|
<span translate>State</span>
|
||||||
</th>
|
</th>
|
||||||
<th field="isFragile"></th>
|
<th field="isFragile" number>
|
||||||
|
<span translate>Fragile</span>
|
||||||
|
</th>
|
||||||
<th field="zoneFk">
|
<th field="zoneFk">
|
||||||
<span translate>Zone</span>
|
<span translate>Zone</span>
|
||||||
</th>
|
</th>
|
||||||
|
|
|
@ -30,35 +30,47 @@ module.exports = Self => {
|
||||||
const ticketLogs = await models.TicketLog.find(
|
const ticketLogs = await models.TicketLog.find(
|
||||||
{
|
{
|
||||||
where: {
|
where: {
|
||||||
and: [
|
or: [
|
||||||
{originFk: id},
|
{
|
||||||
{action: 'update'},
|
and: [
|
||||||
{changedModel: 'Sale'}
|
{originFk: id},
|
||||||
|
{action: 'update'},
|
||||||
|
{changedModel: 'Sale'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
and: [
|
||||||
|
{originFk: id},
|
||||||
|
{action: 'delete'},
|
||||||
|
{changedModel: 'Sale'}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
'oldInstance',
|
'oldInstance',
|
||||||
'newInstance',
|
'newInstance',
|
||||||
'changedModelId'
|
'changedModelId',
|
||||||
|
'changedModelValue'
|
||||||
],
|
],
|
||||||
}, myOptions);
|
}, myOptions);
|
||||||
|
|
||||||
const changes = [];
|
const changes = [];
|
||||||
for (const ticketLog of ticketLogs) {
|
|
||||||
const oldQuantity = ticketLog.oldInstance.quantity;
|
for (const log of ticketLogs) {
|
||||||
const newQuantity = ticketLog.newInstance.quantity;
|
const oldQuantity = log.oldInstance.quantity;
|
||||||
|
const newQuantity = log.newInstance?.quantity || 0;
|
||||||
|
|
||||||
if (oldQuantity || newQuantity) {
|
if (oldQuantity || newQuantity) {
|
||||||
const sale = await models.Sale.findById(ticketLog.changedModelId, null, myOptions);
|
const changeMessage = $t('Change quantity', {
|
||||||
const message = $t('Change quantity', {
|
concept: log.changedModelValue,
|
||||||
concept: sale.concept,
|
oldQuantity: oldQuantity || 0,
|
||||||
oldQuantity: oldQuantity || 0,
|
newQuantity: newQuantity || 0,
|
||||||
newQuantity: newQuantity || 0,
|
});
|
||||||
});
|
changes.push(changeMessage);
|
||||||
|
|
||||||
changes.push(message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return changes.join('\n');
|
return changes.join('\n');
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,8 +11,7 @@ module.exports = Self => {
|
||||||
http: {source: 'path'}
|
http: {source: 'path'}
|
||||||
}, {
|
}, {
|
||||||
arg: 'userFk',
|
arg: 'userFk',
|
||||||
type: 'number',
|
type: 'any',
|
||||||
required: true,
|
|
||||||
description: 'The user id'
|
description: 'The user id'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,41 +1,46 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<body>
|
|
||||||
<table class="mainTable">
|
<body>
|
||||||
<tbody>
|
<table class="mainTable">
|
||||||
<tr>
|
<tbody>
|
||||||
<td id="truck" class="ellipsize">{{labelData.truck || '---'}}</td>
|
<tr>
|
||||||
</tr>
|
<td id="truck" class="ellipsize">{{labelData.truck || '---'}}</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>
|
<tr>
|
||||||
<div v-html="getBarcode(labelData.palletFk)" id="barcode"></div>
|
<td>
|
||||||
<table v-for="labelData in labelsData" class="zoneTable">
|
<div v-html="getBarcode(labelData.palletFk)" id="barcode"></div>
|
||||||
<thead>
|
<table v-for="labelData in labelsData" class="zoneTable">
|
||||||
<tr v-if="!labelData.isMatch" id="black">
|
<thead>
|
||||||
<td id="routeFk" class="ellipsize">{{labelData.routeFk}}</td>
|
<tr v-if="!labelData.isMatch" id="black">
|
||||||
<td id="zone" class="ellipsize">{{labelData.zone || '---'}}</td>
|
<td id="routeFk" class="ellipsize">{{labelData.routeFk}}</td>
|
||||||
<td id="labels" class="ellipsize">{{labelData.labels}}</td>
|
<td id="zone" class="ellipsize">{{labelData.zone || '---'}}</td>
|
||||||
</tr>
|
<td id="labels" class="ellipsize">{{labelData.labels}}</td>
|
||||||
<tr v-else>
|
</tr>
|
||||||
<td id="routeFk" class="ellipsize">{{labelData.routeFk}}</td>
|
<tr v-else>
|
||||||
<td id="zone" class="ellipsize">{{labelData.zone || '---'}}</td>
|
<td id="routeFk" class="ellipsize">{{labelData.routeFk}}</td>
|
||||||
<td id="labels" class="ellipsize">{{labelData.labels || '--'}}</td>
|
<td id="zone" class="ellipsize">{{labelData.zone || '---'}}</td>
|
||||||
</tr>
|
<td id="labels" class="ellipsize">{{labelData.labels || '--'}}</td>
|
||||||
</thead>
|
</tr>
|
||||||
</table>
|
</thead>
|
||||||
</td>
|
</table>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>
|
<tr>
|
||||||
<img :src="QR" id="QR"/>
|
<td>
|
||||||
<div id="right">
|
<img :src="QR" id="QR" />
|
||||||
<div id="additionalInfo" class="ellipsize"><b>Pallet: </b>{{id}}</div>
|
<div id="right">
|
||||||
<div id="additionalInfo" class="ellipsize"><b>User: </b> {{username.name || '---'}}</div>
|
<div id="additionalInfo" class="ellipsize"><b>Pallet: </b>{{id}}</div>
|
||||||
<div id="additionalInfo" class="ellipsize"><b>Day: </b>{{labelData.dayName.toUpperCase() || '---'}}</div>
|
<div id="additionalInfo" class="ellipsize"><b>User: </b>
|
||||||
|
{{ (username ? username.name : '---')}}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
<div id="additionalInfo" class="ellipsize"><b>Day: </b>{{labelData.dayName.toUpperCase() ||
|
||||||
</tr>
|
'---'}}</div>
|
||||||
</tbody>
|
</div>
|
||||||
</table>
|
</td>
|
||||||
</body>
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -14,13 +14,13 @@ module.exports = {
|
||||||
},
|
},
|
||||||
userFk: {
|
userFk: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
|
||||||
description: 'The user id'
|
description: 'The user id'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async serverPrefetch() {
|
async serverPrefetch() {
|
||||||
|
this.username = null;
|
||||||
this.labelsData = await this.rawSqlFromDef('labelData', this.id);
|
this.labelsData = await this.rawSqlFromDef('labelData', this.id);
|
||||||
this.username = await this.findOneFromDef('username', this.userFk);
|
if (this.userFk) this.username = await this.findOneFromDef('username', this.userFk);
|
||||||
this.labelData = this.labelsData[0];
|
this.labelData = this.labelsData[0];
|
||||||
this.checkMainEntity(this.labelData);
|
this.checkMainEntity(this.labelData);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue