Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 3498-staticDate
gitea/salix/pipeline/head This commit is unstable Details

This commit is contained in:
Alex Moreno 2022-06-09 07:47:03 +02:00
commit 7eec9de0aa
432 changed files with 8821 additions and 5284 deletions

14
Jenkinsfile vendored
View File

@ -62,13 +62,13 @@ pipeline {
} }
} }
} }
// stage('Backend') { stage('Backend') {
// steps { steps {
// nodejs('node-v14') { nodejs('node-v14') {
// sh 'gulp launchBackTest --ci' sh 'npm run test:back:ci'
// } }
// } }
// } }
} }
} }
stage('Build') { stage('Build') {

View File

@ -54,17 +54,17 @@ $ gulp docker
For client-side unit tests run from project's root. For client-side unit tests run from project's root.
``` ```
$ jest $ npm run test:front
``` ```
For server-side unit tests run from project's root. For server-side unit tests run from project's root.
``` ```
$ gulp backTest $ npm run test:back
``` ```
For end-to-end tests run from project's root. For end-to-end tests run from project's root.
``` ```
$ gulp e2e $ npm run test:e2e
``` ```
## Visual Studio Code extensions ## Visual Studio Code extensions

View File

@ -23,7 +23,13 @@ module.exports = Self => {
let models = Self.app.models; let models = Self.app.models;
let user = await models.Account.findById(userId, { let user = await models.Account.findById(userId, {
fields: ['id', 'name', 'nickname', 'email'] fields: ['id', 'name', 'nickname', 'email', 'lang'],
include: {
relation: 'userConfig',
scope: {
fields: ['darkMode']
}
}
}); });
let roles = await models.RoleMapping.find({ let roles = await models.RoleMapping.find({

View File

@ -5,17 +5,17 @@ module.exports = Self => {
accepts: [ accepts: [
{ {
arg: 'id', arg: 'id',
type: 'Number', type: 'number',
description: 'The user id', description: 'The user id',
http: {source: 'path'} http: {source: 'path'}
}, { }, {
arg: 'oldPassword', arg: 'oldPassword',
type: 'String', type: 'string',
description: 'The old password', description: 'The old password',
required: true required: true
}, { }, {
arg: 'newPassword', arg: 'newPassword',
type: 'String', type: 'string',
description: 'The new password', description: 'The new password',
required: true required: true
} }

View File

@ -1,9 +1,12 @@
const app = require('vn-loopback/server/server'); const {models} = require('vn-loopback/server/server');
describe('account changePassword()', () => { describe('account changePassword()', () => {
it('should throw an error when old password is wrong', async() => { it('should throw an error when old password is wrong', async() => {
let req = app.models.Account.changePassword(null, 1, 'wrongOldPass', 'newPass'); let err;
await models.Account.changePassword(1, 'wrongPassword', 'nightmare.9999')
.catch(error => err = error.sqlMessage);
await expectAsync(req).toBeRejected(); expect(err).toBeDefined();
expect(err).toEqual('Invalid password');
}); });
}); });

View File

@ -46,7 +46,7 @@ module.exports = Self => {
const {data} = await Self.getUserStatus(recipient.name); const {data} = await Self.getUserStatus(recipient.name);
if (data) { if (data) {
if (data.status === 'offline') { if (data.status === 'offline' || data.status === 'busy') {
// Send message to department room // Send message to department room
const workerDepartment = await models.WorkerDepartment.findById(recipientId, { const workerDepartment = await models.WorkerDepartment.findById(recipientId, {
include: { include: {
@ -58,6 +58,8 @@ module.exports = Self => {
if (channelName) if (channelName)
return Self.send(ctx, `#${channelName}`, `@${recipient.name}${message}`); return Self.send(ctx, `#${channelName}`, `@${recipient.name}${message}`);
else
return Self.send(ctx, `@${recipient.name}`, message);
} else } else
return Self.send(ctx, `@${recipient.name}`, message); return Self.send(ctx, `@${recipient.name}`, message);
} }

View File

@ -1,35 +0,0 @@
module.exports = Self => {
Self.remoteMethod('collectionFaults', {
description: 'Update sale of a collection',
accessType: 'WRITE',
accepts: [{
arg: 'shelvingFk',
type: 'String',
required: true,
description: 'The shalving id'
}, {
arg: 'quantity',
type: 'Number',
required: true,
description: 'The quantity to sale'
}, {
arg: 'itemFk',
type: 'Number',
required: true,
description: 'The ticket id'
}],
returns: {
type: 'Object',
root: true
},
http: {
path: `/collectionFaults`,
verb: 'POST'
}
});
Self.collectionFaults = async(shelvingFk, quantity, itemFk) => {
query = `CALL vn.collection_faults(?,?,?)`;
return await Self.rawSql(query, [shelvingFk, quantity, itemFk]);
};
};

View File

@ -1,5 +1,5 @@
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('setSaleQuantity', { Self.remoteMethod('setSaleQuantity', {
description: 'Update sale quantity', description: 'Update sale quantity',
accessType: 'WRITE', accessType: 'WRITE',
accepts: [{ accepts: [{
@ -24,11 +24,13 @@ module.exports = Self => {
} }
}); });
Self.setSaleQuantity = async ctx => { Self.setSaleQuantity = async(saleId, quantity) => {
const args = ctx.args;
const models = Self.app.models; const models = Self.app.models;
const sale = await models.Sale.findById(args.saleId,); const sale = await models.Sale.findById(saleId);
return await sale.updateAttribute('quantity', args.quantity); return await sale.updateAttributes({
originalQuantity: sale.quantity,
quantity: quantity
});
}; };
}; };

View File

@ -1,9 +0,0 @@
const app = require('vn-loopback/server/server');
describe('collectionFaults()', () => {
it('return shelving afected', async() => {
let response = await app.models.Collection.collectionFaults('UXN', 0, 1);
expect(response.length).toBeGreaterThan(0);
expect(response[0][0].shelvingFk).toEqual('UXN');
});
});

View File

@ -1,8 +1,8 @@
const app = require('vn-loopback/server/server'); const app = require('vn-loopback/server/server');
// #3400 analizar que hacer con rutas de back colletion describe('newCollection()', () => {
xdescribe('newCollection()', () => { it('should return a new collection', async() => {
it('return a new collection', async() => { pending('#3400 analizar que hacer con rutas de back collection');
let ctx = {req: {accessToken: {userId: 1106}}}; let ctx = {req: {accessToken: {userId: 1106}}};
let response = await app.models.Collection.newCollection(ctx, 1, 1, 1); let response = await app.models.Collection.newCollection(ctx, 1, 1, 1);

View File

@ -5,19 +5,12 @@ describe('setSaleQuantity()', () => {
const saleId = 30; const saleId = 30;
const newQuantity = 10; const newQuantity = 10;
const ctx = {
args: {
saleId: saleId,
quantity: newQuantity
}
};
const originalSale = await models.Sale.findById(saleId); const originalSale = await models.Sale.findById(saleId);
await models.Collection.setSaleQuantity(ctx); await models.Collection.setSaleQuantity(saleId, newQuantity);
const updateSale = await models.Sale.findById(saleId); const updateSale = await models.Sale.findById(saleId);
expect(updateSale.quantity).toBeLessThan(originalSale.quantity); expect(updateSale.originalQuantity).toEqual(originalSale.quantity);
expect(updateSale.quantity).toEqual(newQuantity); expect(updateSale.quantity).toEqual(newQuantity);
}); });
}); });

View File

@ -0,0 +1,57 @@
const fs = require('fs-extra');
const path = require('path');
module.exports = Self => {
Self.remoteMethod('deleteTrashFiles', {
description: 'Deletes files that have trash type',
accessType: 'WRITE',
returns: {
type: 'object',
root: true
},
http: {
path: `/deleteTrashFiles`,
verb: 'POST'
}
});
Self.deleteTrashFiles = async(options) => {
const tx = await Self.beginTransaction({});
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction)
myOptions.transaction = tx;
try {
const models = Self.app.models;
const DmsContainer = models.DmsContainer;
const trashDmsType = await models.DmsType.findOne({
where: {code: 'trash'}
}, myOptions);
const dmsToDelete = await models.Dms.find({
where: {
dmsTypeFk: trashDmsType.id
}
}, myOptions);
for (let dms of dmsToDelete) {
const pathHash = DmsContainer.getHash(dms.id);
const dmsContainer = await DmsContainer.container(pathHash);
const dstFile = path.join(dmsContainer.client.root, pathHash, dms.file);
await fs.unlink(dstFile);
await dms.destroy(myOptions);
}
if (tx) await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -12,9 +12,9 @@ describe('docuware download()', () => {
} }
}; };
const fileCabinetName = 'deliveryClientTest'; const fileCabinetName = 'deliveryClient';
const dialogDisplayName = 'find'; const dialogDisplayName = 'find';
const dialogName = 'findTest'; const dialogName = 'findTicket';
const gotGetResponse = { const gotGetResponse = {
body: JSON.stringify( body: JSON.stringify(

View File

@ -14,9 +14,9 @@ describe('docuware download()', () => {
}; };
it('should return the downloaded file name', async() => { it('should return the downloaded file name', async() => {
const fileCabinetName = 'deliveryClientTest'; const fileCabinetName = 'deliveryClient';
const dialogDisplayName = 'find'; const dialogDisplayName = 'find';
const dialogName = 'findTest'; const dialogName = 'findTicket';
const gotGetResponse = { const gotGetResponse = {
body: JSON.stringify( body: JSON.stringify(
{ {

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE bucket INTO TABLE `edi`.`bucket`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9, @col10, @col11, @col12) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9, @col10, @col11, @col12)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE bucket_type INTO TABLE `edi`.`bucket_type`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE `feature` INTO TABLE `edi`.`feature`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE genus INTO TABLE `edi`.`genus`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE item INTO TABLE `edi`.`item`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9, @col10, @col11, @col12) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9, @col10, @col11, @col12)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE `item_feature` INTO TABLE `edi`.`item_feature`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE item_group INTO TABLE `edi`.`item_group`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE plant INTO TABLE `edi`.`plant`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE specie INTO TABLE `edi`.`specie`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE edi.supplier INTO TABLE `edi`.`supplier`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9, @col10, @col11, @col12, @col13, @col14, @col15, @col16, @col17, @col18, @col19, @col20) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9, @col10, @col11, @col12, @col13, @col14, @col15, @col16, @col17, @col18, @col19, @col20)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE `type` INTO TABLE `edi`.`type`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7)
SET SET

View File

@ -1,5 +1,5 @@
LOAD DATA LOCAL INFILE ? LOAD DATA LOCAL INFILE ?
INTO TABLE `value` INTO TABLE `edi`.`value`
FIELDS TERMINATED BY ';' FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7) LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7)
SET SET

View File

@ -22,6 +22,9 @@ module.exports = Self => {
const container = await models.TempContainer.container('edi'); const container = await models.TempContainer.container('edi');
const tempPath = path.join(container.client.root, container.name); const tempPath = path.join(container.client.root, container.name);
// Temporary file clean
await fs.rmdir(`${tempPath}/*`, {recursive: true});
const [ftpConfig] = await Self.rawSql('SELECT host, user, password FROM edi.ftpConfig'); const [ftpConfig] = await Self.rawSql('SELECT host, user, password FROM edi.ftpConfig');
console.debug(`Openning FTP connection to ${ftpConfig.host}...\n`); console.debug(`Openning FTP connection to ${ftpConfig.host}...\n`);
@ -48,6 +51,12 @@ module.exports = Self => {
tempDir = `${tempPath}/${fileName}`; tempDir = `${tempPath}/${fileName}`;
tempFile = `${tempPath}/${fileName}.zip`; tempFile = `${tempPath}/${fileName}.zip`;
// if (fs.existsSync(tempFile))
// await fs.unlink(tempFile);
// if (fs.existsSync(tempDir))
// await fs.rmdir(tempDir, {recursive: true});
await extractFile({ await extractFile({
ftpClient: ftpClient, ftpClient: ftpClient,
file: file, file: file,
@ -61,7 +70,6 @@ module.exports = Self => {
if (fs.existsSync(tempFile)) if (fs.existsSync(tempFile))
await fs.unlink(tempFile); await fs.unlink(tempFile);
await fs.rmdir(tempDir, {recursive: true});
console.error(error); console.error(error);
} }
} }
@ -86,9 +94,6 @@ module.exports = Self => {
zip.extractAllTo(paths.tempDir, false); zip.extractAllTo(paths.tempDir, false);
if (fs.existsSync(paths.tempFile))
await fs.unlink(paths.tempFile);
await dumpData({file, entries, paths}); await dumpData({file, entries, paths});
await fs.rmdir(paths.tempDir, {recursive: true}); await fs.rmdir(paths.tempDir, {recursive: true});
@ -99,57 +104,59 @@ module.exports = Self => {
const toTable = file.toTable; const toTable = file.toTable;
const baseName = file.fileName; const baseName = file.fileName;
for (const zipEntry of entries) { const tx = await Self.beginTransaction({});
const entryName = zipEntry.entryName;
console.log(`Reading file ${entryName}...`);
const startIndex = (entryName.length - 10); try {
const endIndex = (entryName.length - 4); const options = {transaction: tx};
const dateString = entryName.substring(startIndex, endIndex);
const lastUpdated = new Date();
// Format string date to a date object const tableName = `edi.${toTable}`;
let updated = null; await Self.rawSql(`DELETE FROM ??`, [tableName], options);
if (file.updated) {
updated = new Date(file.updated);
updated.setHours(0, 0, 0, 0);
}
lastUpdated.setFullYear(`20${dateString.substring(4, 6)}`); for (const zipEntry of entries) {
lastUpdated.setMonth(parseInt(dateString.substring(2, 4)) - 1); const entryName = zipEntry.entryName;
lastUpdated.setDate(dateString.substring(0, 2)); console.log(`Reading file ${entryName}...`);
lastUpdated.setHours(0, 0, 0, 0);
if (updated && lastUpdated <= updated) { const startIndex = (entryName.length - 10);
console.debug(`Table ${toTable} already updated, skipping...`); const endIndex = (entryName.length - 4);
continue; const dateString = entryName.substring(startIndex, endIndex);
} const lastUpdated = new Date();
console.log('Dumping data...'); // Format string date to a date object
const templatePath = path.join(__dirname, `./sql/${toTable}.sql`); let updated = null;
const sqlTemplate = fs.readFileSync(templatePath, 'utf8'); if (file.updated) {
updated = new Date(file.updated);
updated.setHours(0, 0, 0, 0);
}
const rawPath = path.join(paths.tempDir, entryName); lastUpdated.setFullYear(`20${dateString.substring(4, 6)}`);
lastUpdated.setMonth(parseInt(dateString.substring(2, 4)) - 1);
lastUpdated.setDate(dateString.substring(0, 2));
lastUpdated.setHours(0, 0, 0, 0);
try { if (updated && lastUpdated <= updated) {
const tx = await Self.beginTransaction({}); console.debug(`Table ${toTable} already updated, skipping...`);
const options = {transaction: tx}; continue;
}
console.log('Dumping data...');
const templatePath = path.join(__dirname, `./sql/${toTable}.sql`);
const sqlTemplate = fs.readFileSync(templatePath, 'utf8');
const rawPath = path.join(paths.tempDir, entryName);
await Self.rawSql(`DELETE FROM edi.${toTable}`, null, options);
await Self.rawSql(sqlTemplate, [rawPath], options); await Self.rawSql(sqlTemplate, [rawPath], options);
await Self.rawSql(` await Self.rawSql(`
UPDATE edi.fileConfig UPDATE edi.fileConfig
SET updated = ? SET updated = ?
WHERE fileName = ? WHERE fileName = ?
`, [lastUpdated, baseName], options); `, [lastUpdated, baseName], options);
tx.commit();
} catch (error) {
tx.rollback();
throw error;
} }
console.log(`Updated table ${toTable}\n`); tx.commit();
} catch (error) {
tx.rollback();
throw error;
} }
console.log(`Updated table ${toTable}\n`);
} }
}; };

View File

@ -68,6 +68,12 @@
"Language": { "Language": {
"dataSource": "vn" "dataSource": "vn"
}, },
"MachineWorker": {
"dataSource": "vn"
},
"MobileAppVersionControl": {
"dataSource": "vn"
},
"Module": { "Module": {
"dataSource": "vn" "dataSource": "vn"
}, },

View File

@ -47,7 +47,7 @@
"type": "date" "type": "date"
}, },
"image": { "image": {
"type": "String" "type": "string"
} }
}, },
"relations": { "relations": {
@ -71,6 +71,11 @@
"type": "hasOne", "type": "hasOne",
"model": "Worker", "model": "Worker",
"foreignKey": "userFk" "foreignKey": "userFk"
},
"userConfig": {
"type": "hasOne",
"model": "UserConfig",
"foreignKey": "userFk"
} }
}, },
"acls": [ "acls": [

View File

@ -28,6 +28,9 @@
}, },
"maxAmount": { "maxAmount": {
"type": "number" "type": "number"
},
"daysInFuture": {
"type": "number"
} }
}, },
"acls": [{ "acls": [{

View File

@ -0,0 +1,24 @@
{
"name": "MobileAppVersionControl",
"base": "VnModel",
"options": {
"mysql": {
"table": "vn.mobileAppVersionControl"
}
},
"properties": {
"id": {
"type": "number",
"id": true
},
"appName": {
"type": "string"
},
"version": {
"type": "string"
},
"isVersionCritical": {
"type": "boolean"
}
}
}

View File

@ -9,7 +9,7 @@
}, },
"properties": { "properties": {
"id": { "id": {
"type": "Number", "type": "number",
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
}, },

View File

@ -8,15 +8,15 @@
}, },
"properties": { "properties": {
"id": { "id": {
"type": "Number", "type": "number",
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
}, },
"bic": { "bic": {
"type": "String" "type": "string"
}, },
"name": { "name": {
"type": "String" "type": "string"
} }
}, },
"relations": { "relations": {

View File

@ -8,35 +8,35 @@
}, },
"properties": { "properties": {
"id": { "id": {
"type": "Number", "type": "number",
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
}, },
"bank": { "bank": {
"type": "String", "type": "string",
"required": true "required": true
}, },
"account": { "account": {
"type": "String", "type": "string",
"required": true "required": true
}, },
"accountingTypeFk": { "accountingTypeFk": {
"type": "Number", "type": "number",
"required": true, "required": true,
"mysql": { "mysql": {
"columnName": "cash" "columnName": "cash"
} }
}, },
"entityFk": { "entityFk": {
"type": "Number", "type": "number",
"required": true "required": true
}, },
"isActive": { "isActive": {
"type": "Boolean", "type": "boolean",
"required": true "required": true
}, },
"currencyFk": { "currencyFk": {
"type": "Number", "type": "number",
"required": true "required": true
} }
}, },

View File

@ -10,20 +10,20 @@
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,
"type": "Number", "type": "number",
"description": "Identifier" "description": "Identifier"
}, },
"host": { "host": {
"type": "String" "type": "string"
}, },
"api": { "api": {
"type": "String" "type": "string"
}, },
"user": { "user": {
"type": "String" "type": "string"
}, },
"password": { "password": {
"type": "String" "type": "string"
} }
}, },
"acls": [{ "acls": [{

View File

@ -3,5 +3,4 @@ module.exports = Self => {
require('../methods/collection/newCollection')(Self); require('../methods/collection/newCollection')(Self);
require('../methods/collection/getSectors')(Self); require('../methods/collection/getSectors')(Self);
require('../methods/collection/setSaleQuantity')(Self); require('../methods/collection/setSaleQuantity')(Self);
require('../methods/collection/collectionFaults')(Self);
}; };

View File

@ -10,11 +10,11 @@
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,
"type": "Number", "type": "number",
"description": "Identifier" "description": "Identifier"
}, },
"code": { "code": {
"type": "String" "type": "string"
}, },
"expired": { "expired": {
"type": "date" "type": "date"

View File

@ -9,7 +9,7 @@
}, },
"properties": { "properties": {
"id": { "id": {
"type": "Number", "type": "number",
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
}, },
@ -21,7 +21,7 @@
"type": "string" "type": "string"
}, },
"isUeeMember": { "isUeeMember": {
"type": "Boolean" "type": "boolean"
} }
}, },
"relations": { "relations": {

View File

@ -9,17 +9,17 @@
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,
"type": "Number", "type": "number",
"forceId": false "forceId": false
}, },
"date": { "date": {
"type": "Date" "type": "date"
}, },
"m3":{ "m3":{
"type": "Number" "type": "number"
}, },
"warehouseFk":{ "warehouseFk":{
"type": "Number" "type": "number"
} }
} }
} }

View File

@ -9,7 +9,7 @@
}, },
"properties": { "properties": {
"id": { "id": {
"type": "Number", "type": "number",
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
}, },

View File

@ -5,6 +5,7 @@ module.exports = Self => {
require('../methods/dms/uploadFile')(Self); require('../methods/dms/uploadFile')(Self);
require('../methods/dms/removeFile')(Self); require('../methods/dms/removeFile')(Self);
require('../methods/dms/updateFile')(Self); require('../methods/dms/updateFile')(Self);
require('../methods/dms/deleteTrashFiles')(Self);
Self.checkRole = async function(ctx, id) { Self.checkRole = async function(ctx, id) {
const models = Self.app.models; const models = Self.app.models;

View File

@ -13,7 +13,7 @@
}, },
"properties": { "properties": {
"id": { "id": {
"type": "Number", "type": "number",
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
}, },
@ -36,7 +36,7 @@
"type": "boolean" "type": "boolean"
}, },
"created": { "created": {
"type": "Date" "type": "date"
} }
}, },
"relations": { "relations": {

View File

@ -9,7 +9,7 @@
"properties": { "properties": {
"userFk": { "userFk": {
"id": true, "id": true,
"type": "Number", "type": "number",
"required": true "required": true
}, },
"email": { "email": {

View File

@ -8,20 +8,20 @@
}, },
"properties": { "properties": {
"id": { "id": {
"type": "Number", "type": "number",
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
}, },
"width": { "width": {
"type": "Number", "type": "number",
"required": true "required": true
}, },
"height": { "height": {
"type": "Number", "type": "number",
"required": true "required": true
}, },
"crop": { "crop": {
"type": "Boolean", "type": "boolean",
"required": true "required": true
} }
}, },

View File

@ -8,32 +8,32 @@
}, },
"properties": { "properties": {
"id": { "id": {
"type": "Number", "type": "number",
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
}, },
"name": { "name": {
"type": "String", "type": "string",
"required": true "required": true
}, },
"desc": { "desc": {
"type": "String", "type": "string",
"required": true "required": true
}, },
"maxWidth": { "maxWidth": {
"type": "Number", "type": "number",
"required": true "required": true
}, },
"maxHeight": { "maxHeight": {
"type": "Number", "type": "number",
"required": true "required": true
}, },
"model": { "model": {
"type": "String", "type": "string",
"required": true "required": true
}, },
"property": { "property": {
"type": "String", "type": "string",
"required": true "required": true
} }
}, },

View File

@ -0,0 +1,33 @@
{
"name": "MachineWorker",
"base": "VnModel",
"options": {
"mysql": {
"table": "vn.machineWorker"
}
},
"properties": {
"id": {
"type": "number",
"id": true
},
"workerFk": {
"type": "number"
},
"machineFk": {
"type": "number"
},
"inTime": {
"type": "date",
"mysql": {
"columnName": "inTimed"
}
},
"outTime": {
"type": "date",
"mysql": {
"columnName": "outTimed"
}
}
}
}

View File

@ -9,7 +9,7 @@
"properties": { "properties": {
"code": { "code": {
"id": true, "id": true,
"type": "String" "type": "string"
} }
}, },
"relations": { "relations": {

View File

@ -11,7 +11,7 @@
}, },
"properties": { "properties": {
"id": { "id": {
"type": "Number", "type": "number",
"id": true, "id": true,
"description": "Identifier", "description": "Identifier",
"mysql": { "mysql": {

View File

@ -9,10 +9,10 @@
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,
"type": "Number" "type": "number"
}, },
"name": { "name": {
"type": "String" "type": "string"
} }
}, },
"relations": { "relations": {

View File

@ -9,18 +9,18 @@
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,
"type": "Number" "type": "number"
}, },
"userFk": { "userFk": {
"type": "String", "type": "string",
"required": true "required": true
}, },
"tableCode": { "tableCode": {
"type": "String", "type": "string",
"required": true "required": true
}, },
"configuration": { "configuration": {
"type": "Object" "type": "object"
} }
}, },
"relations": { "relations": {

View File

@ -9,20 +9,23 @@
"properties": { "properties": {
"userFk": { "userFk": {
"id": true, "id": true,
"type": "Number", "type": "number",
"required": true "required": true
}, },
"warehouseFk": { "warehouseFk": {
"type": "Number" "type": "number"
}, },
"companyFk": { "companyFk": {
"type": "Number" "type": "number"
}, },
"created": { "created": {
"type": "Date" "type": "date"
}, },
"updated": { "updated": {
"type": "Date" "type": "date"
},
"darkMode": {
"type": "boolean"
} }
}, },
"relations": { "relations": {

View File

@ -9,40 +9,40 @@
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,
"type": "Number", "type": "number",
"forceId": false "forceId": false
}, },
"originFk": { "originFk": {
"type": "Number", "type": "number",
"required": true "required": true
}, },
"userFk": { "userFk": {
"type": "Number" "type": "number"
}, },
"action": { "action": {
"type": "String", "type": "string",
"required": true "required": true
}, },
"changedModel": { "changedModel": {
"type": "String" "type": "string"
}, },
"oldInstance": { "oldInstance": {
"type": "Object" "type": "object"
}, },
"newInstance": { "newInstance": {
"type": "Object" "type": "object"
}, },
"creationDate": { "creationDate": {
"type": "Date" "type": "date"
}, },
"changedModelId": { "changedModelId": {
"type": "Number" "type": "number"
}, },
"changedModelValue": { "changedModelValue": {
"type": "String" "type": "string"
}, },
"description": { "description": {
"type": "String" "type": "string"
} }
}, },
"relations": { "relations": {

View File

@ -9,7 +9,7 @@
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,
"type": "Number", "type": "number",
"forceId": false "forceId": false
}, },
"username":{ "username":{

View File

@ -10,17 +10,17 @@
"properties": { "properties": {
"id": { "id": {
"id": true, "id": true,
"type": "Number", "type": "number",
"forceId": false "forceId": false
}, },
"name": { "name": {
"type": "String" "type": "string"
}, },
"code": { "code": {
"type": "String" "type": "string"
}, },
"isInventory": { "isInventory": {
"type": "Number" "type": "number"
}, },
"isManaged":{ "isManaged":{
"type": "boolean" "type": "boolean"

24
back/nodemonConfig.json Normal file
View File

@ -0,0 +1,24 @@
{
"verbose": true,
"watch": [
"back/**/*.js",
"modules/**/*.js"
],
"ignore": [
"modules/account/front/**/*",
"modules/claim/front/**/*",
"modules/client/front/**/*",
"modules/entry/front/**/*",
"modules/invoiceIn/front/**/*",
"modules/invoiceOut/front/**/*",
"modules/item/front/**/*",
"modules/monitor/front/**/*",
"modules/order/front/**/*",
"modules/route/front/**/*",
"modules/supplier/front/**/*",
"modules/ticket/front/**/*",
"modules/travel/front/**/*",
"modules/worker/front/**/*",
"modules/zone/front/**/*"
]
}

View File

@ -1,4 +1,5 @@
require('require-yaml'); const Docker = require('../db/docker.js');
let dataSources = require('../loopback/server/datasources.json');
process.on('warning', warning => { process.on('warning', warning => {
console.log(warning.name); console.log(warning.name);
@ -6,34 +7,64 @@ process.on('warning', warning => {
console.log(warning.stack); console.log(warning.stack);
}); });
let verbose = false; async function test() {
let isCI = false;
if (process.argv[2] === '--v') if (process.argv[2] === 'ci')
verbose = true; isCI = true;
let Jasmine = require('jasmine'); const container = new Docker();
let jasmine = new Jasmine();
let SpecReporter = require('jasmine-spec-reporter').SpecReporter;
let serviceSpecs = [ await container.run(isCI);
`${__dirname}/**/*[sS]pec.js`, dataSources = JSON.parse(JSON.stringify(dataSources));
`${__dirname}/../loopback/**/*[sS]pec.js`,
`${__dirname}/../modules/*/back/**/*.[sS]pec.js`
];
jasmine.loadConfig({ Object.assign(dataSources.vn, {
spec_dir: '.', host: container.dbConf.host,
spec_files: serviceSpecs, port: container.dbConf.port
helpers: [] });
});
jasmine.addReporter(new SpecReporter({ const bootOptions = {dataSources};
spec: { const app = require('vn-loopback/server/server');
// displayStacktrace: 'summary', app.boot(bootOptions);
displaySuccessful: verbose,
displayFailedSpec: true, const Jasmine = require('jasmine');
displaySpecDuration: true const jasmine = new Jasmine();
const SpecReporter = require('jasmine-spec-reporter').SpecReporter;
jasmine.addReporter(new SpecReporter({
spec: {
displaySuccessful: isCI,
displayPending: isCI
},
summary: {
displayPending: false,
}
}));
if (isCI) {
const JunitReporter = require('jasmine-reporters');
jasmine.addReporter(new JunitReporter.JUnitXmlReporter());
jasmine.jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
} }
}));
jasmine.execute(); const backSpecs = [
'./back/**/*[sS]pec.js',
'./loopback/**/*[sS]pec.js',
'./modules/*/back/**/*.[sS]pec.js'
];
jasmine.loadConfig({
spec_dir: '.',
spec_files: backSpecs,
helpers: [],
});
jasmine.exitOnCompletion = false;
await jasmine.execute();
if (app) await app.disconnect();
if (container) await container.rm();
console.log('app disconnected & container removed');
}
test();

View File

@ -0,0 +1 @@
ALTER TABLE `vn`.`userConfig` ADD darkMode tinyint(1) DEFAULT 1 NOT NULL COMMENT 'Salix interface dark mode';

View File

@ -0,0 +1,2 @@
INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES('ExpeditionState', '*', 'READ', 'ALLOW', 'ROLE', 'employee');

View File

@ -0,0 +1,5 @@
INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES('Expense', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES('Expense', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');

View File

@ -0,0 +1,5 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES('SupplierActivity', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES('SupplierActivity', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');

View File

@ -1,113 +0,0 @@
DROP PROCEDURE IF EXISTS vn.ticket_doRefund;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_doRefund`(IN vOriginTicket INT, OUT vNewTicket INT)
BEGIN
DECLARE vDone BIT DEFAULT 0;
DECLARE vCustomer MEDIUMINT;
DECLARE vWarehouse TINYINT;
DECLARE vCompany MEDIUMINT;
DECLARE vAddress MEDIUMINT;
DECLARE vRefundAgencyMode INT;
DECLARE vItemFk INT;
DECLARE vQuantity DECIMAL (10,2);
DECLARE vConcept VARCHAR(50);
DECLARE vPrice DECIMAL (10,2);
DECLARE vDiscount TINYINT;
DECLARE vSaleNew INT;
DECLARE vSaleMain INT;
DECLARE vZoneFk INT;
DECLARE vDescription VARCHAR(50);
DECLARE vTaxClassFk INT;
DECLARE vTicketServiceTypeFk INT;
DECLARE cSales CURSOR FOR
SELECT *
FROM tmp.sale;
DECLARE cTicketServices CURSOR FOR
SELECT *
FROM tmp.ticketService;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1;
SELECT id INTO vRefundAgencyMode
FROM agencyMode WHERE `name` = 'ABONO';
SELECT clientFk, warehouseFk, companyFk, addressFk
INTO vCustomer, vWarehouse, vCompany, vAddress
FROM ticket
WHERE id = vOriginTicket;
SELECT id INTO vZoneFk
FROM zone WHERE agencyModeFk = vRefundAgencyMode
LIMIT 1;
INSERT INTO vn.ticket (
clientFk,
shipped,
addressFk,
agencyModeFk,
nickname,
warehouseFk,
companyFk,
landed,
zoneFk
)
SELECT
vCustomer,
vn.VN_CURDATE(),
vAddress,
vRefundAgencyMode,
a.nickname,
vWarehouse,
vCompany,
vn.VN_CURDATE(),
vZoneFk
FROM address a
WHERE a.id = vAddress;
SET vNewTicket = LAST_INSERT_ID();
SET vDone := 0;
OPEN cSales;
FETCH cSales INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount;
WHILE NOT vDone DO
INSERT INTO vn.sale(ticketFk, itemFk, quantity, concept, price, discount)
VALUES( vNewTicket, vItemFk, vQuantity, vConcept, vPrice, vDiscount );
SET vSaleNew = LAST_INSERT_ID();
INSERT INTO vn.saleComponent(saleFk,componentFk,`value`)
SELECT vSaleNew,componentFk,`value`
FROM vn.saleComponent
WHERE saleFk = vSaleMain;
FETCH cSales INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount;
END WHILE;
CLOSE cSales;
SET vDone := 0;
OPEN cTicketServices;
FETCH cTicketServices INTO vDescription, vQuantity, vPrice, vTaxClassFk, vTicketServiceTypeFk;
WHILE NOT vDone DO
INSERT INTO vn.ticketService(description, quantity, price, taxClassFk, ticketFk, ticketServiceTypeFk)
VALUES(vDescription, vQuantity, vPrice, vTaxClassFk, vNewTicket, vTicketServiceTypeFk);
FETCH cTicketServices INTO vDescription, vQuantity, vPrice, vTaxClassFk, vTicketServiceTypeFk;
END WHILE;
CLOSE cTicketServices;
INSERT INTO vn.ticketRefund(refundTicketFk, originalTicketFk)
VALUES(vNewTicket, vOriginTicket);
END$$
DELIMITER ;

View File

@ -0,0 +1,5 @@
ALTER TABLE `vn`.`clientConfig` ADD `maxCreditRows` int(11) NULL COMMENT 'Máximo número de registros a mantener en la tabla clientCredit';
UPDATE `vn`.`clientConfig`
SET `maxCreditRows` = 10
WHERE `id` = 1;

View File

@ -0,0 +1,8 @@
ALTER TABLE `vn`.`propertyDms` DROP FOREIGN KEY propertyDms_FK;
ALTER TABLE `vn`.`propertyDms` ADD CONSTRAINT propertyDms_FK FOREIGN KEY (dmsFk) REFERENCES `vn`.`dms`(id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `vn`.`clientDms` DROP FOREIGN KEY clientDms_ibfk_2;
ALTER TABLE `vn`.`clientDms` ADD CONSTRAINT clientDms_ibfk_2 FOREIGN KEY (dmsFk) REFERENCES `vn`.`dms`(id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `vn`.`workerDocument` DROP FOREIGN KEY workerDocument_ibfk_2;
ALTER TABLE `vn`.`workerDocument` ADD CONSTRAINT workerDocument_ibfk_2 FOREIGN KEY (document) REFERENCES `vn`.`dms`(id) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,5 @@
ALTER TABLE `vn`.`dmsType` ADD monthToDelete INT UNSIGNED DEFAULT NULL NULL;
ALTER TABLE `vn`.`dmsType` MODIFY COLUMN monthToDelete int(10) unsigned DEFAULT NULL NULL COMMENT 'Meses en el pasado para ir borrando registros, dejar a null para no borrarlos nunca';
UPDATE `vn`.`dmsType`
SET monthToDelete=6
WHERE id=20;

View File

@ -0,0 +1,18 @@
DELIMITER $$
$$
CREATE TRIGGER `vn`.`dms_beforeDelete`
BEFORE DELETE
ON dms FOR EACH ROW
BEGIN
DECLARE vCanNotBeDeleted INT;
SELECT COUNT(*) INTO vCanNotBeDeleted
FROM dmsType dt
WHERE NOT (code <=> 'trash')
AND dt.id = OLD.dmsTypeFk;
IF vCanNotBeDeleted THEN
CALL util.throw('A dms can not be deleted');
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,175 @@
DROP PROCEDURE IF EXISTS vn.clean;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`clean`()
BEGIN
DECLARE vDateShort DATETIME;
DECLARE vOneYearAgo DATE;
DECLARE vFourYearsAgo DATE;
DECLARE v18Month DATE;
DECLARE v26Month DATE;
DECLARE v3Month DATE;
DECLARE vTrashId varchar(15);
SET vDateShort = TIMESTAMPADD(MONTH, -2, CURDATE());
SET vOneYearAgo = TIMESTAMPADD(YEAR,-1,CURDATE());
SET vFourYearsAgo = TIMESTAMPADD(YEAR,-4,CURDATE());
SET v18Month = TIMESTAMPADD(MONTH, -18,CURDATE());
SET v26Month = TIMESTAMPADD(MONTH, -26,CURDATE());
SET v3Month = TIMESTAMPADD(MONTH, -3, CURDATE());
DELETE FROM ticketParking WHERE created < vDateShort;
DELETE FROM routesMonitor WHERE dated < vDateShort;
DELETE FROM workerTimeControlLog WHERE created < vDateShort;
DELETE FROM `message` WHERE sendDate < vDateShort;
DELETE FROM messageInbox WHERE sendDate < vDateShort;
DELETE FROM messageInbox WHERE sendDate < vDateShort;
DELETE FROM workerTimeControl WHERE timed < vFourYearsAgo;
DELETE FROM itemShelving WHERE created < CURDATE() AND visible = 0;
DELETE FROM ticketDown WHERE created < TIMESTAMPADD(DAY,-1,CURDATE());
DELETE FROM entryLog WHERE creationDate < vDateShort;
DELETE IGNORE FROM expedition WHERE created < v26Month;
DELETE FROM sms WHERE created < v18Month;
DELETE FROM saleTracking WHERE created < vOneYearAgo;
DELETE tobs FROM ticketObservation tobs
JOIN ticket t ON tobs.ticketFk = t.id WHERE t.shipped < TIMESTAMPADD(YEAR,-2,CURDATE());
DELETE sc.* FROM saleCloned sc JOIN sale s ON s.id = sc.saleClonedFk JOIN ticket t ON t.id = s.ticketFk WHERE t.shipped < vOneYearAgo;
DELETE FROM sharingCart where ended < vDateShort;
DELETE FROM sharingClient where ended < vDateShort;
DELETE tw.* FROM ticketWeekly tw
LEFT JOIN sale s ON s.ticketFk = tw.ticketFk WHERE s.itemFk IS NULL;
DELETE FROM claim WHERE ticketCreated < vFourYearsAgo;
DELETE FROM message WHERE sendDate < vDateShort;
-- Robert ubicacion anterior de trevelLog comentario para debug
DELETE sc FROM saleChecked sc
JOIN sale s ON sc.saleFk = s.id WHERE s.created < vDateShort;
DELETE FROM zoneEvent WHERE `type` = 'day' AND dated < v3Month;
DELETE bm
FROM buyMark bm
JOIN buy b ON b.id = bm.id
JOIN entry e ON e.id = b.entryFk
JOIN travel t ON t.id = e.travelFk
WHERE t.landed <= vDateShort;
DELETE FROM stowaway WHERE created < v3Month;
DELETE FROM vn.buy WHERE created < vDateShort AND entryFk = 9200;
DELETE FROM vn.itemShelvingLog WHERE created < vDateShort;
DELETE FROM vn.stockBuyed WHERE creationDate < vDateShort;
-- Equipos duplicados
DELETE w.*
FROM workerTeam w
JOIN (SELECT id, team, workerFk, COUNT(*) - 1 as duplicated
FROM workerTeam
GROUP BY team,workerFk
HAVING duplicated
) d ON d.team = w.team AND d.workerFk = w.workerFk AND d.id != w.id;
DELETE sc
FROM saleComponent sc
JOIN sale s ON s.id= sc.saleFk
JOIN ticket t ON t.id= s.ticketFk
WHERE t.shipped < v18Month;
DELETE c
FROM vn.claim c
JOIN vn.claimState cs ON cs.id = c.claimStateFk
WHERE cs.description = "Anulado" AND
c.created < vDateShort;
DELETE
FROM vn.expeditionTruck
WHERE ETD < v3Month;
-- borrar travels sin entradas
DROP TEMPORARY TABLE IF EXISTS tmp.thermographToDelete;
CREATE TEMPORARY TABLE tmp.thermographToDelete
SELECT th.id,th.dmsFk
FROM vn.travel t
LEFT JOIN vn.entry e ON e.travelFk = t.id
JOIN vn.travelThermograph th ON th.travelFk = t.id
WHERE t.shipped < TIMESTAMPADD(MONTH, -3, CURDATE()) AND e.travelFk IS NULL;
SELECT dt.id into vTrashId
FROM vn.dmsType dt
WHERE dt.code = 'trash';
UPDATE tmp.thermographToDelete th
JOIN vn.dms d ON d.id = th.dmsFk
SET d.dmsTypeFk = vTrashId;
DELETE th
FROM tmp.thermographToDelete tmp
JOIN vn.travelThermograph th ON th.id = tmp.id;
DELETE t
FROM vn.travel t
LEFT JOIN vn.entry e ON e.travelFk = t.id
WHERE t.shipped < TIMESTAMPADD(MONTH, -3, CURDATE()) AND e.travelFk IS NULL;
UPDATE dms d
JOIN dmsType dt ON dt.id = d.dmsTypeFk
SET d.dmsTypeFk = vTrashId
WHERE created < TIMESTAMPADD(MONTH, -dt.monthToDelete, CURDATE());
-- borrar entradas sin compras
DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete;
CREATE TEMPORARY TABLE tmp.entryToDelete
SELECT e.*
FROM vn.entry e
LEFT JOIN vn.buy b ON b.entryFk = e.id
JOIN vn.entryConfig ec ON e.id != ec.defaultEntry
WHERE e.dated < TIMESTAMPADD(MONTH, -3, CURDATE()) AND b.entryFK IS NULL;
DELETE e
FROM vn.entry e
JOIN tmp.entryToDelete tmp ON tmp.id = e.id;
-- borrar de route registros menores a 4 años
DROP TEMPORARY TABLE IF EXISTS tmp.routeToDelete;
CREATE TEMPORARY TABLE tmp.routeToDelete
SELECT *
FROM vn.route r
WHERE created < TIMESTAMPADD(YEAR,-4,CURDATE());
UPDATE tmp.routeToDelete tmp
JOIN vn.dms d ON d.id = tmp.gestdocFk
SET d.dmsTypeFk = vTrashId;
DELETE r
FROM tmp.routeToDelete tmp
JOIN vn.route r ON r.id = tmp.id;
-- borrar registros de dua y awb menores a 2 años
DROP TEMPORARY TABLE IF EXISTS tmp.duaToDelete;
CREATE TEMPORARY TABLE tmp.duaToDelete
SELECT *
FROM vn.dua
WHERE operated < TIMESTAMPADD(YEAR,-2,CURDATE());
UPDATE tmp.duaToDelete tm
JOIN vn.dms d ON d.id = tm.gestdocFk
SET d.dmsTypeFk = vTrashId;
DELETE d
FROM tmp.duaToDelete tmp
JOIN vn.dua d ON d.id = tmp.id;
DELETE FROM vn.awb WHERE created < TIMESTAMPADD(YEAR,-2,CURDATE());
-- Borra los ficheros gestDoc
INSERT INTO vn.printServerQueue(priorityFk, labelReportFk)VALUES(1,11);
-- Borra los registros de collection y ticketcollection
DELETE FROM vn.collection WHERE created < vDateShort;
DROP TEMPORARY TABLE IF EXISTS tmp.thermographToDelete;
DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete;
DROP TEMPORARY TABLE IF EXISTS tmp.duaToDelete;
DELETE FROM travelLog WHERE creationDate < v3Month;
CALL shelving_clean;
END$$
DELIMITER ;

View File

@ -0,0 +1,2 @@
INSERT INTO `salix`.`ACL` (model,property,accessType,permission,principalType,principalId)
VALUES ('Dms','deleteTrashFiles','WRITE','ALLOW','ROLE','employee')

View File

@ -3,8 +3,8 @@ CREATE TABLE `vn`.`clientUnpaid` (
`dated` date NOT NULL, `dated` date NOT NULL,
`amount` double DEFAULT 0, `amount` double DEFAULT 0,
PRIMARY KEY (`clientFk`), PRIMARY KEY (`clientFk`),
CONSTRAINT `clientUnpaid_clientFk` FOREIGN KEY (`clientFk`) REFERENCES `client` (`id`) ON UPDATE CASCADE CONSTRAINT `clientUnpaid_clientFk` FOREIGN KEY (`clientFk`) REFERENCES `vn`.`client` (`id`) ON UPDATE CASCADE
); );
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES('ClientUnpaid', '*', '*', 'ALLOW', 'ROLE', 'administrative'); VALUES('ClientUnpaid', '*', '*', 'ALLOW', 'ROLE', 'administrative');

View File

@ -0,0 +1,8 @@
CREATE TABLE `vn`.`invoiceOut_queue` (
`invoiceFk` int(10) unsigned not null,
`queued` datetime default now() not null,
`printed` datetime null,
`status` VARCHAR(50) DEFAULT '' NULL,
CONSTRAINT `invoiceOut_queue_pk` PRIMARY KEY (`invoiceFk`),
CONSTRAINT `invoiceOut_queue_invoiceOut_id_fk` FOREIGN KEY (`invoiceFk`) REFERENCES `vn`.`invoiceOut` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
) comment 'Queue for PDF invoicing';

View File

@ -0,0 +1,2 @@
ALTER TABLE `vn`.`accountingType` ADD daysInFuture INT NULL;
ALTER TABLE `vn`.`accountingType` MODIFY COLUMN daysInFuture int(11) DEFAULT 0 NULL;

View File

@ -0,0 +1,4 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES
('ItemType', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
('ItemType', '*', 'WRITE', 'ALLOW', 'ROLE', 'buyer');

View File

@ -0,0 +1,14 @@
CREATE TABLE `vn`.`mdbBranch` (
`name` VARCHAR(255),
PRIMARY KEY(`name`)
);
CREATE TABLE `vn`.`mdbVersion` (
`app` VARCHAR(255) NOT NULL,
`branchFk` VARCHAR(255) NOT NULL,
`version` INT,
CONSTRAINT `mdbVersion_branchFk` FOREIGN KEY (`branchFk`) REFERENCES `vn`.`mdbBranch` (`name`) ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES('MdbVersion', '*', '*', 'ALLOW', 'ROLE', 'developer');

View File

@ -0,0 +1,3 @@
INSERT INTO `salix`.`defaultViewConfig` (tableCode, columns)
VALUES ('clientsDetail', '{"id":true,"phone":true,"city":true,"socialName":true,"salesPersonFk":true,"email":true,"name":false,"fi":false,"credit":false,"creditInsurance":false,"mobile":false,"street":false,"countryFk":false,"provinceFk":false,"postcode":false,"created":false,"businessTypeFk":false,"payMethodFk":false,"sageTaxTypeFk":false,"sageTransactionTypeFk":false,"isActive":false,"isVies":false,"isTaxDataChecked":false,"isEqualizated":false,"isFreezed":false,"hasToInvoice":false,"hasToInvoiceByAddress":false,"isToBeMailed":false,"hasLcr":false,"hasCoreVnl":false,"hasSepaVnl":false}');

View File

@ -0,0 +1,127 @@
DROP PROCEDURE IF EXISTS `vn`.`ticket_doRefund`;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_doRefund`(OUT vNewTicket INT)
BEGIN
/**
* Crea un ticket de abono a partir de tmp.sale y/o tmp.ticketService
*
* @return vNewTicket
*/
DECLARE vDone BIT DEFAULT 0;
DECLARE vClientFk MEDIUMINT;
DECLARE vWarehouse TINYINT;
DECLARE vCompany MEDIUMINT;
DECLARE vAddress MEDIUMINT;
DECLARE vRefundAgencyMode INT;
DECLARE vItemFk INT;
DECLARE vQuantity DECIMAL (10,2);
DECLARE vConcept VARCHAR(50);
DECLARE vPrice DECIMAL (10,2);
DECLARE vDiscount TINYINT;
DECLARE vSaleNew INT;
DECLARE vSaleMain INT;
DECLARE vZoneFk INT;
DECLARE vDescription VARCHAR(50);
DECLARE vTaxClassFk INT;
DECLARE vTicketServiceTypeFk INT;
DECLARE vOriginTicket INT;
DECLARE cSales CURSOR FOR
SELECT s.id, s.itemFk, - s.quantity, s.concept, s.price, s.discount
FROM tmp.sale s;
DECLARE cTicketServices CURSOR FOR
SELECT ts.description, - ts.quantity, ts.price, ts.taxClassFk, ts.ticketServiceTypeFk
FROM tmp.ticketService ts;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
SELECT sub.ticketFk INTO vOriginTicket
FROM (
SELECT s.ticketFk
FROM tmp.sale s
UNION ALL
SELECT ts.ticketFk
FROM tmp.ticketService ts
) sub
LIMIT 1;
SELECT id INTO vRefundAgencyMode
FROM agencyMode WHERE `name` = 'ABONO';
SELECT clientFk, warehouseFk, companyFk, addressFk
INTO vClientFk, vWarehouse, vCompany, vAddress
FROM ticket
WHERE id = vOriginTicket;
SELECT id INTO vZoneFk
FROM zone WHERE agencyModeFk = vRefundAgencyMode
LIMIT 1;
INSERT INTO vn.ticket (
clientFk,
shipped,
addressFk,
agencyModeFk,
nickname,
warehouseFk,
companyFk,
landed,
zoneFk
)
SELECT
vClientFk,
CURDATE(),
vAddress,
vRefundAgencyMode,
a.nickname,
vWarehouse,
vCompany,
CURDATE(),
vZoneFk
FROM address a
WHERE a.id = vAddress;
SET vNewTicket = LAST_INSERT_ID();
SET vDone := FALSE;
OPEN cSales;
FETCH cSales INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount;
WHILE NOT vDone DO
INSERT INTO vn.sale(ticketFk, itemFk, quantity, concept, price, discount)
VALUES( vNewTicket, vItemFk, vQuantity, vConcept, vPrice, vDiscount );
SET vSaleNew = LAST_INSERT_ID();
INSERT INTO vn.saleComponent(saleFk,componentFk,`value`)
SELECT vSaleNew,componentFk,`value`
FROM vn.saleComponent
WHERE saleFk = vSaleMain;
FETCH cSales INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount;
END WHILE;
CLOSE cSales;
SET vDone := FALSE;
OPEN cTicketServices;
FETCH cTicketServices INTO vDescription, vQuantity, vPrice, vTaxClassFk, vTicketServiceTypeFk;
WHILE NOT vDone DO
INSERT INTO vn.ticketService(description, quantity, price, taxClassFk, ticketFk, ticketServiceTypeFk)
VALUES(vDescription, vQuantity, vPrice, vTaxClassFk, vNewTicket, vTicketServiceTypeFk);
FETCH cTicketServices INTO vDescription, vQuantity, vPrice, vTaxClassFk, vTicketServiceTypeFk;
END WHILE;
CLOSE cTicketServices;
INSERT INTO vn.ticketRefund(refundTicketFk, originalTicketFk)
VALUES(vNewTicket, vOriginTicket);
END$$
DELIMITER ;

View File

@ -24,7 +24,10 @@ module.exports = class Docker {
let d = new Date(); let d = new Date();
let pad = v => v < 10 ? '0' + v : v; let pad = v => v < 10 ? '0' + v : v;
let stamp = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; let stamp = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
log('Building container image...');
await this.execP(`docker build --build-arg STAMP=${stamp} -t salix-db ./db`); await this.execP(`docker build --build-arg STAMP=${stamp} -t salix-db ./db`);
log('Image built.');
let dockerArgs; let dockerArgs;
@ -39,6 +42,7 @@ module.exports = class Docker {
let runChown = process.platform != 'linux'; let runChown = process.platform != 'linux';
log('Starting container...');
const container = await this.execP(`docker run --env RUN_CHOWN=${runChown} -d ${dockerArgs} salix-db`); const container = await this.execP(`docker run --env RUN_CHOWN=${runChown} -d ${dockerArgs} salix-db`);
this.id = container.stdout.trim(); this.id = container.stdout.trim();
@ -158,6 +162,7 @@ module.exports = class Docker {
return reject(new Error('Docker exited, please see the docker logs for more info')); return reject(new Error('Docker exited, please see the docker logs for more info'));
let conn = mysql.createConnection(myConf); let conn = mysql.createConnection(myConf);
conn.on('error', () => {}); conn.on('error', () => {});
conn.connect(err => { conn.connect(err => {
conn.destroy(); conn.destroy();

File diff suppressed because one or more lines are too long

View File

@ -114,28 +114,7 @@ INSERT INTO `vn`.`educationLevel` (`id`, `name`)
INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `userFk`, `bossFk`) INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `userFk`, `bossFk`)
SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9 SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9
FROM `vn`.`user`; FROM `vn`.`user`;
ALTER TABLE `vn`.`worker` ADD `originCountryFk` mediumint(8) unsigned NULL COMMENT 'País de origen';
ALTER TABLE `vn`.`worker` ADD `educationLevelFk` SMALLINT NULL;
ALTER TABLE `vn`.`worker` ADD `SSN` varchar(15) NULL;
ALTER TABLE `vn`.`worker` CHANGE `maritalStatus__` `maritalStatus` enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;
ALTER TABLE `vn`.`worker` MODIFY COLUMN `maritalStatus` enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;
ALTER TABLE `vn`.`worker` CHANGE `maritalStatus` maritalStatus enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL AFTER sectorFk;
ALTER TABLE `vn`.`worker` ADD CONSTRAINT `worker_FK_2` FOREIGN KEY (`educationLevelFk`) REFERENCES `vn`.`educationLevel`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE `vn`.`worker` ADD CONSTRAINT `worker_FK_1` FOREIGN KEY (`originCountryFk`) REFERENCES `vn`.`country`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
UPDATE `vn`.`worker` `w`
SET `maritalStatus` = 'S';
UPDATE `vn`.`worker` `w`
SET `originCountryFk` = '1';
UPDATE `vn`.`worker` `w`
SET `educationLevelFk` = '2';
UPDATE `vn`.`worker` `w`
SET `SSN` = '123456789123';
UPDATE `vn`.`worker` SET bossFk = NULL WHERE id = 20; UPDATE `vn`.`worker` SET bossFk = NULL WHERE id = 20;
UPDATE `vn`.`worker` SET bossFk = 20 WHERE id = 1 OR id = 9; UPDATE `vn`.`worker` SET bossFk = 20 WHERE id = 1 OR id = 9;
@ -180,13 +159,19 @@ INSERT INTO `account`.`mailForward`(`account`, `forwardTo`)
VALUES VALUES
(1, 'employee@domain.local'); (1, 'employee@domain.local');
INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossFk`, `phone`) INSERT INTO `vn`.`printer` (`id`, `name`, `path`, `isLabeler`)
VALUES VALUES
(1106, 'LGN', 'David Charles', 'Haller', 1106, 19, 432978106), (1, 'printer1', 'path1', 0),
(1107, 'ANT', 'Hank' , 'Pym' , 1107, 19, 432978107), (2, 'printer2', 'path2', 1);
(1108, 'DCX', 'Charles' , 'Xavier', 1108, 19, 432978108),
(1109, 'HLK', 'Bruce' , 'Banner', 1109, 19, 432978109),
(1110, 'JJJ', 'Jessica' , 'Jones' , 1110, 19, 432978110); INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossFk`, `phone`, `sectorFk`, `labelerFk`)
VALUES
(1106, 'LGN', 'David Charles', 'Haller', 1106, 19, 432978106, NULL, NULL),
(1107, 'ANT', 'Hank' , 'Pym' , 1107, 19, 432978107, NULL, 1),
(1108, 'DCX', 'Charles' , 'Xavier', 1108, 19, 432978108, 1, NULL),
(1109, 'HLK', 'Bruce' , 'Banner', 1109, 19, 432978109, 1, 2),
(1110, 'JJJ', 'Jessica' , 'Jones' , 1110, 19, 432978110, 2, 1);
INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`) INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
VALUES VALUES
@ -194,7 +179,7 @@ INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
(2, 'USD', 'Dollar USA', 1.4), (2, 'USD', 'Dollar USA', 1.4),
(3, 'GBP', 'Libra', 1), (3, 'GBP', 'Libra', 1),
(4, 'JPY', 'Yen Japones', 1); (4, 'JPY', 'Yen Japones', 1);
INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`, `continentFk`, `hasDailyInvoice`, `CEE`) INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`, `continentFk`, `hasDailyInvoice`, `CEE`)
VALUES VALUES
(1, 'España', 1, 'ES', 1, 24, 4, 0, 1), (1, 'España', 1, 'ES', 1, 24, 4, 0, 1),
@ -207,15 +192,6 @@ INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`,
(19,'Francia', 1, 'FR', 1, 27, 4, 0, 1), (19,'Francia', 1, 'FR', 1, 27, 4, 0, 1),
(30,'Canarias', 1, 'IC', 1, 24, 4, 1, 2); (30,'Canarias', 1, 'IC', 1, 24, 4, 1, 2);
INSERT INTO `hedera`.`language` (`code`, `name`, `orgName`, `isActive`)
VALUES
('ca', 'Català' , 'Catalan' , TRUE),
('en', 'English' , 'English' , TRUE),
('es', 'Español' , 'Spanish' , TRUE),
('fr', 'Français' , 'French' , TRUE),
('mn', 'Португалий', 'Mongolian' , TRUE),
('pt', 'Português' , 'Portuguese', TRUE);
INSERT INTO `vn`.`warehouseAlias`(`id`, `name`) INSERT INTO `vn`.`warehouseAlias`(`id`, `name`)
VALUES VALUES
(1, 'Main Warehouse'), (1, 'Main Warehouse'),
@ -242,25 +218,27 @@ INSERT INTO `vn`.`parking` (`id`, `column`, `row`, `sectorFk`, `code`, `pickingO
INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `isPrinted`, `priority`, `parked`, `userFk`) INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `isPrinted`, `priority`, `parked`, `userFk`)
VALUES VALUES
('GVC', '1', '0', '1', '0', '1106'), ('GVC', 1, 0, 1, 0, 1106),
('HEJ', '2', '0', '1', '0', '1106'); ('HEJ', 2, 0, 1, 0, 1106),
('UXN', 1, 0, 1, 0, 1106);
INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`,`code`, `maxAmount`) INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`,`code`, `maxAmount`, `daysInFuture`)
VALUES VALUES
(1, 'CC y Polizas de crédito', NULL, NULL, NULL), (1, 'CC and credit policies', 'Transfers', 'wireTransfer', NULL, 1),
(2, 'Cash', 'Cash', 'cash', 1000), (2, 'Cash', 'Cash', 'cash', 1000, 0),
(3, 'Credit card', 'Credit Card', 'creditCard', NULL), (3, 'Credit card', 'Credit Card', 'creditCard', NULL, 0),
(4, 'Finalcial lines', NULL, NULL, NULL), (4, 'Finalcial lines', NULL, NULL, NULL, 0),
(5, 'Other products', NULL, NULL, NULL), (5, 'Other products', NULL, NULL, NULL, 0),
(6, 'Loans', NULL, NULL, NULL), (6, 'Loans', NULL, NULL, NULL, 0),
(7, 'Leasing', NULL, NULL, NULL), (7, 'Leasing', NULL, NULL, NULL, 0),
(8, 'Compensations', 'Compensations', 'compensation', NULL); (8, 'Compensations', 'Compensations', 'compensation', NULL, 0);
INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`) INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`)
VALUES VALUES
(1, 'Pay on receipt', '5720000001', 3, 0, 1, 1), (1, 'Pay on receipt', '5720000001', 3, 0, 1, 1),
(2, 'Cash', '5700000001', 2, 0, 1, 1), (2, 'Cash', '5700000001', 2, 0, 1, 1),
(3, 'Compensation', '4000000000', 8, 0, 1, 1), (3, 'Compensation', '4000000000', 8, 0, 1, 1),
(4, 'Transfers', '4000000001', 1, 0, 1, 1),
(3117, 'Caixa Rural d''Algemesi', '5720000000', 8, 3117, 1, 1); (3117, 'Caixa Rural d''Algemesi', '5720000000', 8, 3117, 1, 1);
@ -402,9 +380,9 @@ INSERT INTO `vn`.`clientManaCache`(`clientFk`, `mana`, `dated`)
(1103, 0, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH)), (1103, 0, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH)),
(1104, -30, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH)); (1104, -30, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH));
INSERT INTO `vn`.`clientConfig`(`riskTolerance`) INSERT INTO `vn`.`clientConfig`(`riskTolerance`, `maxCreditRows`)
VALUES VALUES
(200); (200, 10);
INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`, `isDefaultAddress`) INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`, `isDefaultAddress`)
VALUES VALUES
@ -482,17 +460,17 @@ DROP TEMPORARY TABLE tmp.address;
INSERT INTO `vn`.`clientCredit`(`id`, `clientFk`, `workerFk`, `amount`, `created`) INSERT INTO `vn`.`clientCredit`(`id`, `clientFk`, `workerFk`, `amount`, `created`)
VALUES VALUES
(1 , 1101, 5, 300, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH)), (1 , 1101, 5, 300, DATE_ADD(vn.VN_CURDATE(), INTERVAL -11 MONTH)),
(2 , 1101, 5, 900, DATE_ADD(vn.VN_CURDATE(), INTERVAL -2 MONTH)), (2 , 1101, 5, 900, DATE_ADD(vn.VN_CURDATE(), INTERVAL -10 MONTH)),
(3 , 1101, 5, 800, DATE_ADD(vn.VN_CURDATE(), INTERVAL -3 MONTH)), (3 , 1101, 5, 800, DATE_ADD(vn.VN_CURDATE(), INTERVAL -9 MONTH)),
(4 , 1101, 5, 700, DATE_ADD(vn.VN_CURDATE(), INTERVAL -4 MONTH)), (4 , 1101, 5, 700, DATE_ADD(vn.VN_CURDATE(), INTERVAL -8 MONTH)),
(5 , 1101, 5, 600, DATE_ADD(vn.VN_CURDATE(), INTERVAL -5 MONTH)), (5 , 1101, 5, 600, DATE_ADD(vn.VN_CURDATE(), INTERVAL -7 MONTH)),
(6 , 1101, 5, 500, DATE_ADD(vn.VN_CURDATE(), INTERVAL -6 MONTH)), (6 , 1101, 5, 500, DATE_ADD(vn.VN_CURDATE(), INTERVAL -6 MONTH)),
(7 , 1101, 5, 400, DATE_ADD(vn.VN_CURDATE(), INTERVAL -7 MONTH)), (7 , 1101, 5, 400, DATE_ADD(vn.VN_CURDATE(), INTERVAL -5 MONTH)),
(8 , 1101, 9, 300, DATE_ADD(vn.VN_CURDATE(), INTERVAL -8 MONTH)), (8 , 1101, 9, 300, DATE_ADD(vn.VN_CURDATE(), INTERVAL -4 MONTH)),
(9 , 1101, 9, 200, DATE_ADD(vn.VN_CURDATE(), INTERVAL -9 MONTH)), (9 , 1101, 9, 200, DATE_ADD(vn.VN_CURDATE(), INTERVAL -3 MONTH)),
(10, 1101, 9, 100, DATE_ADD(vn.VN_CURDATE(), INTERVAL -10 MONTH)), (10, 1101, 9, 100, DATE_ADD(vn.VN_CURDATE(), INTERVAL -2 MONTH)),
(11, 1101, 9, 50 , DATE_ADD(vn.VN_CURDATE(), INTERVAL -11 MONTH)), (11, 1101, 9, 50 , DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH)),
(12, 1102, 9, 800, vn.VN_CURDATE()), (12, 1102, 9, 800, vn.VN_CURDATE()),
(14, 1104, 9, 90 , vn.VN_CURDATE()), (14, 1104, 9, 90 , vn.VN_CURDATE()),
(15, 1105, 9, 90 , vn.VN_CURDATE()); (15, 1105, 9, 90 , vn.VN_CURDATE());
@ -833,14 +811,19 @@ INSERT INTO `vn`.`itemCategory`(`id`, `name`, `display`, `color`, `icon`, `code`
(7, 'Accessories', 1, NULL, 'icon-accessory', 'accessory'), (7, 'Accessories', 1, NULL, 'icon-accessory', 'accessory'),
(8, 'Fruit', 1, NULL, 'icon-fruit', 'fruit'); (8, 'Fruit', 1, NULL, 'icon-fruit', 'fruit');
INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `warehouseFk`, `life`,`workerFk`, `isPackaging`) INSERT INTO `vn`.`temperature`(`code`, `name`, `description`)
VALUES VALUES
(1, 'CRI', 'Crisantemo', 2, 1, 31, 35, 0), ('warm', 'Warm', 'Warm'),
(2, 'ITG', 'Anthurium', 1, 1, 31, 35, 0), ('cool', 'Cool', 'Cool');
(3, 'WPN', 'Paniculata', 2, 1, 31, 35, 0),
(4, 'PRT', 'Delivery ports', 3, 1, NULL, 35, 1), INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `warehouseFk`, `life`,`workerFk`, `isPackaging`, `temperatureFk`)
(5, 'CON', 'Container', 3, 1, NULL, 35, 1), VALUES
(6, 'ALS', 'Alstroemeria', 1, 1, 31, 16, 0); (1, 'CRI', 'Crisantemo', 2, 1, 31, 35, 0, 'cool'),
(2, 'ITG', 'Anthurium', 1, 1, 31, 35, 0, 'cool'),
(3, 'WPN', 'Paniculata', 2, 1, 31, 35, 0, 'cool'),
(4, 'PRT', 'Delivery ports', 3, 1, NULL, 35, 1, 'warm'),
(5, 'CON', 'Container', 3, 1, NULL, 35, 1, 'warm'),
(6, 'ALS', 'Alstroemeria', 1, 1, 31, 16, 0, 'warm');
INSERT INTO `vn`.`ink`(`id`, `name`, `picture`, `showOrder`, `hex`) INSERT INTO `vn`.`ink`(`id`, `name`, `picture`, `showOrder`, `hex`)
VALUES VALUES
@ -898,25 +881,25 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`)
('VT', 'Sales'); ('VT', 'Sales');
INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`, INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`,
`comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`, `genericFk`, `itemPackingTypeFk`, `hasMinPrice`) `comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`, `genericFk`, `itemPackingTypeFk`, `hasMinPrice`, `packingShelve`)
VALUES VALUES
(1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0, NULL, 'V', 0), (1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0, NULL, 'V', 0, 15),
(2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0, NULL, 'H', 0), (2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0, NULL, 'H', 0, 10),
(3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0, NULL, NULL, 0), (3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0, NULL, NULL, 0, 5),
(4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0, NULL, NULL, 0), (4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0, NULL, NULL, 0, NULL),
(5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT', 0, NULL, NULL, 0), (5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT', 0, NULL, NULL, 0, NULL),
(6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0, NULL, NULL, 0), (6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0, NULL, NULL, 0, NULL),
(7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0, NULL, NULL, 0), (7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0, NULL, NULL, 0, NULL),
(8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0, NULL, NULL, 0), (8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0, NULL, NULL, 0, NULL),
(9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 1, NULL, NULL, 0), (9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 1, NULL, NULL, 0, NULL),
(10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0, NULL, NULL, 0), (10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0, NULL, NULL, 0, NULL),
(11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0, NULL, NULL, 0), (11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0, NULL, NULL, 0, NULL),
(12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0, NULL, NULL, 0), (12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0, NULL, NULL, 0, NULL),
(13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 1, 2, 'VT', 1, NULL, NULL, 1), (13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 1, 2, 'VT', 1, NULL, NULL, 1, NULL),
(14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1, NULL, NULL, 0), (14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1, NULL, NULL, 0, NULL),
(15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL, NULL, 0), (15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL, NULL, 0, NULL),
(16, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL, NULL, 0), (16, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL, NULL, 0, NULL),
(71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT', 0, NULL, NULL, 0); (71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT', 0, NULL, NULL, 0, NULL);
-- Update the taxClass after insert of the items -- Update the taxClass after insert of the items
UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2 UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2
@ -943,18 +926,35 @@ INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPack
('cc', 1640038.00, 56.00, 220.00, 128.00, 1, vn.VN_CURDATE(), 15, 90.00), ('cc', 1640038.00, 56.00, 220.00, 128.00, 1, vn.VN_CURDATE(), 15, 90.00),
('pallet 100', 2745600.00, 100.00, 220.00, 120.00, 1, vn.VN_CURDATE(), 16, 0.00); ('pallet 100', 2745600.00, 100.00, 220.00, 120.00, 1, vn.VN_CURDATE(), 16, 0.00);
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`, `externalId`, `packagingFk`) INSERT INTO `vn`.`expeditionStateType`(`id`, `description`, `code`)
VALUES VALUES
(1, 1, 1, 71, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH), 15, 1, 1, 18, 'UR9000006041', 94), (1, 'En reparto', 'ON DELIVERY'),
(2, 1, 1, 71, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH), 16, 2, 1, 18, 'UR9000006041', 94), (2, 'Entregada', 'DELIVERED'),
(3, 1, 1, 71, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 3, 1, 18, 'UR9000006041', 94), (3, 'Perdida', 'LOST');
(4, 1, 1, 71, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 4, 1, 18, 'UR9000006041', 94),
(5, 1, 2, 71, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 1, 1, 18, NULL, 94),
(6, 7, 3, 71, DATE_ADD(vn.VN_CURDATE(), INTERVAL -2 MONTH), NULL, 1, 1, 18, NULL, 94), INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`, `externalId`, `packagingFk`, `stateTypeFk`)
(7, 2, 4, 71, DATE_ADD(vn.VN_CURDATE(), INTERVAL -3 MONTH), NULL, 1, 1, 18, NULL, 94), VALUES
(8, 3, 5, 71, DATE_ADD(vn.VN_CURDATE(), INTERVAL -4 MONTH), NULL, 1, 1, 18, NULL, 94), (1, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 15, 1, 1, 18, 'UR9000006041', 94, 1),
(9, 3, 6, 71, DATE_ADD(vn.VN_CURDATE(), INTERVAL -1 MONTH), NULL, 1, 1, 18, NULL, 94), (2, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 16, 2, 1, 18, 'UR9000006041', 94, 1),
(10, 7, 7, 71, vn.VN_NOW(), NULL, 1, 1, 18, NULL, 94); (3, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 3, 1, 18, 'UR9000006041', 94, 2),
(4, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 4, 1, 18, 'UR9000006041', 94, 2),
(5, 1, 2, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 1, 1, 18, NULL, 94, 3),
(6, 7, 3, 71, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), NULL, 1, 1, 18, NULL, 94, 3),
(7, 2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), NULL, 1, 1, 18, NULL, 94, NULL),
(8, 3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), NULL, 1, 1, 18, NULL, 94, 1),
(9, 3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), NULL, 1, 1, 18, NULL, 94, 2),
(10, 7, 7, 71, NOW(), NULL, 1, 1, 18, NULL, 94, 3);
INSERT INTO `vn`.`expeditionState`(`id`, `created`, `expeditionFk`, `typeFk`, `userFk`)
VALUES
(1, DATE_ADD(vn.VN_CURDATE()), 1, 1, 1),
(2, DATE_ADD(vn.VN_CURDATE()), 2, 1, 1),
(3, DATE_ADD(vn.VN_CURDATE()), 3, 1, 1),
(4, DATE_ADD(vn.VN_CURDATE()), 3, 2, 1106),
(5, DATE_ADD(vn.VN_CURDATE()), 5, 1, 1106),
(6, DATE_ADD(vn.VN_CURDATE()), 5, 3, 1106);
INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`, `created`, `pvp`) INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`, `created`, `pvp`)
VALUES VALUES
@ -1138,10 +1138,11 @@ INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
(32, 36, -92.324), (32, 36, -92.324),
(32, 39, 0.994); (32, 39, 0.994);
INSERT INTO `vn`.`itemShelving` (`id`, `itemFk`, `shelvingFk`, `shelve`, `deep`, `quantity`, `visible`, `available`, `grouping`, `packing`, `level`, `userFk`) INSERT INTO `vn`.`itemShelving` (`itemFk`, `shelvingFk`, `shelve`, `visible`, `grouping`, `packing`, `userFk`)
VALUES VALUES
('1', '2', 'GVC', 'A', '0', '1', '1', '1', '1', '1', '1', '1106'), (2, 'GVC', 'A', 1, 1, 1, 1106),
('2', '4', 'HEJ', 'A', '0', '2', '1', '1', '1', '1', '1', '1106'); (4, 'HEJ', 'A', 1, 1, 1, 1106),
(1, 'UXN', 'A', 2, 12, 12, 1106);
INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`) INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`)
VALUES VALUES
@ -1195,14 +1196,6 @@ INSERT INTO `vn`.`parking` (`column`, `row`, `sectorFk`, `code`, `pickingOrder`)
VALUES VALUES
('100', '01', 1, '100-01', 1); ('100', '01', 1, '100-01', 1);
INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `priority`, `userFk`)
VALUES
('UXN', 1, 1, 1106);
INSERT INTO `vn`.`itemShelving` (`itemFk`, `shelvingFk`, `shelve`, `deep`, `quantity`, `visible`, `available`, `grouping`, `packing`, `level`, `userFk`)
VALUES
(1, 'UXN', 'A', 2, 12, 12, 12, 12, 12, 1, 1106);
INSERT INTO `vn`.`ticketCollection` (`ticketFk`, `collectionFk`, `level`) INSERT INTO `vn`.`ticketCollection` (`ticketFk`, `collectionFk`, `level`)
VALUES VALUES
(1, 1, 1); (1, 1, 1);
@ -1392,11 +1385,11 @@ INSERT INTO `vn`.`supplierAddress`(`id`, `supplierFk`, `nickname`, `street`, `pr
(5, 442, 'GCR building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222'), (5, 442, 'GCR building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222'),
(6, 442, 'The Gotham Tonight building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222'); (6, 442, 'The Gotham Tonight building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222');
INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif`, `commission`, `created`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`, `payDay`, `taxTypeSageFk`, `withholdingSageFk`, `transactionTypeSageFk`, `workerFk`, `supplierActivityFk`, `isPayMethodChecked`) INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif`, `commission`, `created`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`, `payDay`, `taxTypeSageFk`, `withholdingSageFk`, `transactionTypeSageFk`, `workerFk`, `supplierActivityFk`, `isPayMethodChecked`, `healthRegister`)
VALUES VALUES
(1, 'Plants SL', 'Plants nick', 4100000001, 1, '06089160W', 0, vn.VN_CURDATE(), 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants', 1), (1, 'Plants SL', 'Plants nick', 4100000001, 1, '06089160W', 0, vn.VN_CURDATE(), 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants', 1, '400664487V'),
(2, 'Farmer King', 'The farmer', 4000020002, 1, '87945234L', 0, vn.VN_CURDATE(), 1, 'supplier address 2', 'SILLA', 2, 43022, 1, 2, 10, 93, 2, 8, 18, 'animals', 1), (2, 'Farmer King', 'The farmer', 4000020002, 1, '87945234L', 0, vn.VN_CURDATE(), 1, 'supplier address 2', 'SILLA', 2, 43022, 1, 2, 10, 93, 2, 8, 18, 'animals', 1, '400664487V'),
(442, 'Verdnatura Levante SL', 'Verdnatura', 5115000442, 1, '06815934E', 0, vn.VN_CURDATE(), 1, 'supplier address 3', 'SILLA', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'flowerPlants', 1); (442, 'Verdnatura Levante SL', 'Verdnatura', 5115000442, 1, '06815934E', 0, vn.VN_CURDATE(), 1, 'supplier address 3', 'SILLA', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'complements', 1, '400664487V');
INSERT INTO `vn`.`supplierContact`(`id`, `supplierFk`, `phone`, `mobile`, `email`, `observation`, `name`) INSERT INTO `vn`.`supplierContact`(`id`, `supplierFk`, `phone`, `mobile`, `email`, `observation`, `name`)
VALUES VALUES
@ -1700,51 +1693,59 @@ INSERT INTO `hedera`.`orderRowComponent`(`rowFk`, `componentFk`, `price`)
INSERT INTO `hedera`.`visit`(`id`, `firstAgentFk`) INSERT INTO `hedera`.`visit`(`id`, `firstAgentFk`)
VALUES VALUES
(1, NULL), (1, NULL),
(2, NULL), (2, NULL),
(3, NULL), (3, NULL),
(4, NULL), (4, NULL),
(5, NULL), (5, NULL),
(6, NULL), (6, NULL),
(7, NULL), (7, NULL),
(8, NULL), (8, NULL),
(9, NULL); (9, NULL),
(10, NULL),
(11, NULL);
INSERT INTO `hedera`.`visitAgent`(`id`, `visitFk`) INSERT INTO `hedera`.`visitAgent`(`id`, `visitFk`)
VALUES VALUES
(1, 1), (1, 1),
(2, 2), (2, 2),
(3, 3), (3, 3),
(4, 4), (4, 4),
(5, 5), (5, 5),
(6, 6), (6, 6),
(7, 7), (7, 7),
(8, 8), (8, 8),
(9, 9); (9, 9),
(10, 10),
(11, 11);
INSERT INTO `hedera`.`visitAccess`(`id`, `agentFk`, `stamp`) INSERT INTO `hedera`.`visitAccess`(`id`, `agentFk`, `stamp`)
VALUES VALUES
(1, 1, vn.VN_CURDATE()), (1, 1, vn.VN_CURDATE()),
(2, 2, vn.VN_CURDATE()), (2, 2, vn.VN_CURDATE()),
(3, 3, vn.VN_CURDATE()), (3, 3, vn.VN_CURDATE()),
(4, 4, vn.VN_CURDATE()), (4, 4, vn.VN_CURDATE()),
(5, 5, vn.VN_CURDATE()), (5, 5, vn.VN_CURDATE()),
(6, 6, vn.VN_CURDATE()), (6, 6, vn.VN_CURDATE()),
(7, 7, vn.VN_CURDATE()), (7, 7, vn.VN_CURDATE()),
(8, 8, vn.VN_CURDATE()), (8, 8, vn.VN_CURDATE()),
(9, 9, vn.VN_CURDATE()); (9, 9, vn.VN_CURDATE()),
(10, 10, vn.VN_CURDATE()),
(11, 11, vn.VN_CURDATE());
INSERT INTO `hedera`.`visitUser`(`id`, `accessFk`, `userFk`, `stamp`) INSERT INTO `hedera`.`visitUser`(`id`, `accessFk`, `userFk`, `stamp`)
VALUES VALUES
(1, 1, 1101, vn.VN_CURDATE()), (1, 1, 1101, vn.VN_CURDATE()),
(2, 2, 1101, vn.VN_CURDATE()), (2, 2, 1101, vn.VN_CURDATE()),
(3, 3, 1101, vn.VN_CURDATE()), (3, 3, 1101, vn.VN_CURDATE()),
(4, 4, 1102, vn.VN_CURDATE()), (4, 4, 1102, vn.VN_CURDATE()),
(5, 5, 1102, vn.VN_CURDATE()), (5, 5, 1102, vn.VN_CURDATE()),
(6, 6, 1102, vn.VN_CURDATE()), (6, 6, 1102, vn.VN_CURDATE()),
(7, 7, 1103, vn.VN_CURDATE()), (7, 7, 1103, vn.VN_CURDATE()),
(8, 8, 1103, vn.VN_CURDATE()), (8, 8, 1103, vn.VN_CURDATE()),
(9, 9, 1103, vn.VN_CURDATE()); (9, 9, 1103, vn.VN_CURDATE()),
(10, 10, 1102, DATE_SUB(vn.VN_CURDATE(), INTERVAL 1 DAY)),
(11, 11, 1103, DATE_SUB(vn.VN_CURDATE(), INTERVAL 1 DAY));
INSERT INTO `hedera`.`userSession`(`created`, `lastUpdate`, `ssid`, `data`, `userVisitFk`) INSERT INTO `hedera`.`userSession`(`created`, `lastUpdate`, `ssid`, `data`, `userVisitFk`)
VALUES VALUES
@ -2326,13 +2327,19 @@ INSERT INTO `vn`.`dmsType`(`id`, `name`, `path`, `readRoleFk`, `writeRoleFk`, `c
INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`) INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`)
VALUES VALUES
(1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', vn.VN_CURDATE()), (1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', vn.VN_CURDATE()),
(2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:104', 'Client:104 dms for the client', vn.VN_CURDATE()), (2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:104', 'Client:104 dms for the client', vn.VN_CURDATE()),
(3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 104', 'Client:104 readme', vn.VN_CURDATE()), (3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 104', 'Client:104 readme', vn.VN_CURDATE()),
(4, 3, '4.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Worker: 106', 'Worker:106 readme', vn.VN_CURDATE()), (4, 3, '4.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Worker: 106', 'Worker:106 readme', vn.VN_CURDATE()),
(5, 5, '5.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'travel: 1', 'dmsForThermograph', vn.VN_CURDATE()), (5, 5, '5.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'travel: 1', 'dmsForThermograph', vn.VN_CURDATE()),
(6, 5, '6.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'NotExists', 'DoesNotExists', vn.VN_CURDATE()); (6, 5, '6.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'NotExists', 'DoesNotExists', vn.VN_CURDATE()),
(7, 20, '7.jpg', 'image/jpeg', 9, 1, 442, NULL, FALSE, '1', 'TICKET ID DEL CLIENTE BRUCE WAYNE ID 1101', vn.VN_CURDATE()),
(8, 20, '8.mp4', 'video/mp4', 9, 1, 442, NULL, FALSE, '1', 'TICKET ID DEL CLIENTE BRUCE WAYNE ID 1101', vn.VN_CURDATE());
INSERT INTO `vn`.`claimDms`(`claimFk`, `dmsFk`)
VALUES
(1, 7),
(1, 8);
INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`) INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`)
VALUES VALUES
@ -2363,11 +2370,6 @@ INSERT INTO `vn`.`workerTimeControlParams` (`id`, `dayBreak`, `weekBreak`, `week
(1, 43200, 129600, 734400, 43200, 50400, 259200, 1296000, 36000); (1, 43200, 129600, 734400, 43200, 50400, 259200, 1296000, 36000);
INSERT IGNORE INTO `vn`.`greugeConfig` (`id`, `freightPickUpPrice`) VALUES ('1', '11'); INSERT IGNORE INTO `vn`.`greugeConfig` (`id`, `freightPickUpPrice`) VALUES ('1', '11');
INSERT INTO `vn`.`temperature`(`code`, `name`, `description`)
VALUES
('warm', 'Warm', 'Warm'),
('cool', 'Cool', 'Cool');
INSERT INTO `vn`.`thermograph`(`id`, `model`) INSERT INTO `vn`.`thermograph`(`id`, `model`)
VALUES VALUES
@ -2592,7 +2594,7 @@ INSERT INTO `bs`.`sale` (`saleFk`, `amount`, `dated`, `typeFk`, `clientFk`)
INSERT INTO `vn`.`docuware` (`code`, `fileCabinetName`, `dialogName` , `find`) INSERT INTO `vn`.`docuware` (`code`, `fileCabinetName`, `dialogName` , `find`)
VALUES VALUES
('deliveryClientTest', 'deliveryClientTest', 'findTest', 'word'); ('deliveryClient', 'deliveryClient', 'findTicket', 'word');
INSERT INTO `vn`.`docuwareConfig` (`url`) INSERT INTO `vn`.`docuwareConfig` (`url`)
VALUES VALUES
@ -2617,3 +2619,30 @@ INSERT INTO `vn`.`supplierAgencyTerm` (`agencyFk`, `supplierFk`, `minimumPackage
(3, 2, 0, 15.00, 0.00, NULL, 0, 0.00, 0), (3, 2, 0, 15.00, 0.00, NULL, 0, 0.00, 0),
(4, 2, 0, 20.00, 0.00, NULL, 0, 0.00, 0), (4, 2, 0, 20.00, 0.00, NULL, 0, 0.00, 0),
(5, 442, 0, 0.00, 3.05, NULL, 0, 0.00, 0); (5, 442, 0, 0.00, 3.05, NULL, 0, 0.00, 0);
INSERT INTO `vn`.`mobileAppVersionControl` (`appName`, `version`, `isVersionCritical`)
VALUES
('delivery', '9.2', 0),
('warehouse', '8.1', 0);
INSERT INTO `vn`.`machine` (`plate`, `maker`, `model`, `warehouseFk`, `departmentFk`, `type`, `use`, `productionYear`, `workerFk`, `companyFk`)
VALUES
('RE-001', 'STILL', 'LTX-20', 60, 23, 'ELECTRIC TOW', 'Drag cars', 2020, 103, 442),
('RE-002', 'STILL', 'LTX-20', 60, 23, 'ELECTRIC TOW', 'Drag cars', 2020, 103, 442);
INSERT INTO `vn`.`machineWorker` (`workerFk`, `machineFk`, `inTimed`, `outTimed`)
VALUES
(1106, 1, CURDATE(), CURDATE()),
(1106, 1, DATE_ADD(CURDATE(), INTERVAL + 1 DAY), DATE_ADD(CURDATE(), INTERVAL +1 DAY)),
(1106, 2, CURDATE(), NULL),
(1106, 2, DATE_ADD(CURDATE(), INTERVAL + 1 DAY), DATE_ADD(CURDATE(), INTERVAL +1 DAY));
INSERT INTO `vn`.`mdbBranch` (`name`)
VALUES
('test'),
('master');
INSERT INTO `vn`.`mdbVersion` (`app`, `branchFk`, `version`)
VALUES
('tpv', 'test', '1'),
('lab', 'master', '1');

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,8 @@ echo "" > "$DUMPED_FILE"
TABLES=( TABLES=(
util util
config config
version
versionLog
) )
dump_tables ${TABLES[@]} dump_tables ${TABLES[@]}
@ -74,10 +76,20 @@ dump_tables ${TABLES[@]}
TABLES=( TABLES=(
hedera hedera
browser
imageCollection imageCollection
imageCollectionSize
language
link
location
menu
message
metatag
newsTag
restPriv
social
tpvError tpvError
tpvResponse tpvResponse
imageCollectionSize
) )
dump_tables ${TABLES[@]} dump_tables ${TABLES[@]}

View File

@ -49,6 +49,7 @@ IGNORETABLES=(
--ignore-table=vn.grantGroup --ignore-table=vn.grantGroup
--ignore-table=vn.invoiceCorrection__ --ignore-table=vn.invoiceCorrection__
--ignore-table=vn.itemTaxCountrySpain --ignore-table=vn.itemTaxCountrySpain
--ignore-table=vn.itemShelvingPlacementSupplyStock__
--ignore-table=vn.itemFreeNumber__ --ignore-table=vn.itemFreeNumber__
--ignore-table=vn.mail__ --ignore-table=vn.mail__
--ignore-table=vn.manaSpellers --ignore-table=vn.manaSpellers
@ -59,7 +60,6 @@ IGNORETABLES=(
--ignore-table=vn.plantpassportAuthority__ --ignore-table=vn.plantpassportAuthority__
--ignore-table=vn.preparationException --ignore-table=vn.preparationException
--ignore-table=vn.priceFixed__ --ignore-table=vn.priceFixed__
--ignore-table=vn.printer
--ignore-table=vn.printingQueue --ignore-table=vn.printingQueue
--ignore-table=vn.printServerQueue__ --ignore-table=vn.printServerQueue__
--ignore-table=vn.promissoryNote --ignore-table=vn.promissoryNote

View File

@ -32,6 +32,7 @@ services:
- /mnt/appdata/pdfs:/var/lib/salix/pdfs - /mnt/appdata/pdfs:/var/lib/salix/pdfs
- /mnt/appdata/dms:/var/lib/salix/dms - /mnt/appdata/dms:/var/lib/salix/dms
- /mnt/appdata/image:/var/lib/salix/image - /mnt/appdata/image:/var/lib/salix/image
- /mnt/appdata/vn-access:/var/lib/salix/vn-access
deploy: deploy:
replicas: ${BACK_REPLICAS:?} replicas: ${BACK_REPLICAS:?}
placement: placement:

View File

@ -101,6 +101,47 @@ export default {
email: 'vn-user-mail-forwarding vn-textfield[ng-model="data.forwardTo"]', email: 'vn-user-mail-forwarding vn-textfield[ng-model="data.forwardTo"]',
save: 'vn-user-mail-forwarding vn-submit' save: 'vn-user-mail-forwarding vn-submit'
}, },
accountAcl: {
addAcl: 'vn-acl-index button vn-icon[icon="add"]',
thirdAcl: 'vn-acl-index vn-list> a:nth-child(3)',
deleteThirdAcl: 'vn-acl-index vn-list > a:nth-child(3) > vn-item-section > vn-icon-button[icon="delete"]',
role: 'vn-acl-create vn-autocomplete[ng-model="$ctrl.acl.principalId"]',
model: 'vn-acl-create vn-autocomplete[ng-model="$ctrl.acl.model"]',
property: 'vn-acl-create vn-autocomplete[ng-model="$ctrl.acl.property"]',
accessType: 'vn-acl-create vn-autocomplete[ng-model="$ctrl.acl.accessType"]',
permission: 'vn-acl-create vn-autocomplete[ng-model="$ctrl.acl.permission"]',
save: 'vn-acl-create vn-submit'
},
accountConnections: {
firstConnection: 'vn-connections vn-list > a:nth-child(1)',
deleteFirstConnection: 'vn-connections vn-list > a:nth-child(1) > vn-item-section > vn-icon-button[icon="exit_to_app"]'
},
accountAccounts: {
syncRoles: 'vn-account-accounts vn-button[label="Synchronize roles"]',
syncUser: 'vn-account-accounts vn-button[label="Synchronize user"]',
syncAll: 'vn-account-accounts vn-button[label="Synchronize all"]',
syncUserName: 'vn-textfield[ng-model="$ctrl.syncUser"]',
syncUserPassword: 'vn-textfield[ng-model="$ctrl.syncPassword"]',
buttonAccept: 'button[response="accept"]'
},
accountLdap: {
checkEnable: 'vn-account-ldap vn-check[ng-model="watcher.hasData"]',
server: 'vn-account-ldap vn-textfield[ng-model="$ctrl.config.server"]',
rdn: 'vn-account-ldap vn-textfield[ng-model="$ctrl.config.rdn"]',
password: 'vn-account-ldap vn-textfield[ng-model="$ctrl.config.password"]',
userDn: 'vn-account-ldap vn-textfield[ng-model="$ctrl.config.userDn"]',
groupDn: 'vn-account-ldap vn-textfield[ng-model="$ctrl.config.groupDn"]',
save: 'vn-account-ldap vn-submit'
},
accountSamba: {
checkEnable: 'vn-account-samba vn-check[ng-model="watcher.hasData"]',
adDomain: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adDomain"]',
adController: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adController"]',
adUser: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adUser"]',
adPassword: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adPassword"]',
verifyCert: 'vn-account-samba vn-check[ng-model="$ctrl.config.verifyCert"]',
save: 'vn-account-samba vn-submit'
},
clientsIndex: { clientsIndex: {
createClientButton: `vn-float-button` createClientButton: `vn-float-button`
}, },
@ -731,7 +772,7 @@ export default {
claimAction: { claimAction: {
importClaimButton: 'vn-claim-action vn-button[label="Import claim"]', importClaimButton: 'vn-claim-action vn-button[label="Import claim"]',
anyLine: 'vn-claim-action vn-tbody > vn-tr', anyLine: 'vn-claim-action vn-tbody > vn-tr',
firstDeleteLine: 'vn-claim-action vn-tr:nth-child(1) vn-icon-button[icon="delete"]', firstDeleteLine: 'vn-claim-action tr:nth-child(1) vn-icon-button[icon="delete"]',
isPaidWithManaCheckbox: 'vn-claim-action vn-check[ng-model="$ctrl.claim.isChargedToMana"]' isPaidWithManaCheckbox: 'vn-claim-action vn-check[ng-model="$ctrl.claim.isChargedToMana"]'
}, },
ordersIndex: { ordersIndex: {
@ -982,8 +1023,8 @@ export default {
save: 'vn-invoice-in-basic-data button[type=submit]' save: 'vn-invoice-in-basic-data button[type=submit]'
}, },
invoiceInTax: { invoiceInTax: {
addTaxButton: 'vn-invoice-in-tax vn-icon-button[icon="add_circle"]', addTaxButton: 'vn-invoice-in-tax vn-icon-button[vn-tooltip="Add tax"]',
thirdExpence: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.expenseFk"]', thirdExpense: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.expenseFk"]',
thirdTaxableBase: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-input-number[ng-model="invoiceInTax.taxableBase"]', thirdTaxableBase: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-input-number[ng-model="invoiceInTax.taxableBase"]',
thirdTaxType: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.taxTypeSageFk"]', thirdTaxType: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.taxTypeSageFk"]',
thirdTransactionType: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.transactionTypeSageFk"]', thirdTransactionType: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.transactionTypeSageFk"]',
@ -1133,7 +1174,7 @@ export default {
entryLatestBuys: { entryLatestBuys: {
firstBuy: 'vn-entry-latest-buys tbody > tr:nth-child(1)', firstBuy: 'vn-entry-latest-buys tbody > tr:nth-child(1)',
allBuysCheckBox: 'vn-entry-latest-buys thead vn-check', allBuysCheckBox: 'vn-entry-latest-buys thead vn-check',
secondBuyCheckBox: 'vn-entry-latest-buys tbody tr:nth-child(2) vn-check[ng-model="buy.$checked"]', secondBuyCheckBox: 'vn-entry-latest-buys tbody tr:nth-child(2) vn-check[ng-model="buy.checked"]',
editBuysButton: 'vn-entry-latest-buys vn-button[icon="edit"]', editBuysButton: 'vn-entry-latest-buys vn-button[icon="edit"]',
fieldAutocomplete: 'vn-autocomplete[ng-model="$ctrl.editedColumn.field"]', fieldAutocomplete: 'vn-autocomplete[ng-model="$ctrl.editedColumn.field"]',
newValueInput: 'vn-textfield[ng-model="$ctrl.editedColumn.newValue"]', newValueInput: 'vn-textfield[ng-model="$ctrl.editedColumn.newValue"]',

87
e2e/helpers/tests.js Normal file
View File

@ -0,0 +1,87 @@
require('@babel/register')({presets: ['@babel/env']});
require('core-js/stable');
require('regenerator-runtime/runtime');
const axios = require('axios');
const Docker = require('../../db/docker.js');
const e2eConfig = require('./config.js');
const log = require('fancy-log');
process.on('warning', warning => {
console.log(warning.name);
console.log(warning.message);
console.log(warning.stack);
});
async function test() {
if (process.argv[2] === 'show')
process.env.E2E_SHOW = true;
const container = new Docker('salix-db');
await container.run();
const Jasmine = require('jasmine');
const jasmine = new Jasmine();
const specFiles = [
`./e2e/paths/01*/*[sS]pec.js`,
`./e2e/paths/02*/*[sS]pec.js`,
`./e2e/paths/03*/*[sS]pec.js`,
`./e2e/paths/04*/*[sS]pec.js`,
`./e2e/paths/05*/*[sS]pec.js`,
`./e2e/paths/06*/*[sS]pec.js`,
`./e2e/paths/07*/*[sS]pec.js`,
`./e2e/paths/08*/*[sS]pec.js`,
`./e2e/paths/09*/*[sS]pec.js`,
`./e2e/paths/10*/*[sS]pec.js`,
`./e2e/paths/11*/*[sS]pec.js`,
`./e2e/paths/12*/*[sS]pec.js`,
`./e2e/paths/13*/*[sS]pec.js`,
`./e2e/paths/**/*[sS]pec.js`
];
jasmine.loadConfig({
spec_dir: '.',
spec_files: specFiles,
helpers: [],
random: false,
});
await backendStatus();
jasmine.jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
await jasmine.execute();
}
async function backendStatus() {
log('Awaiting backend connection...');
const milliseconds = 1000;
const maxAttempts = 10;
return new Promise(resolve => {
let timer;
let attempts = 1;
timer = setInterval(async() => {
try {
attempts++;
const url = `${e2eConfig.url}/api/Applications/status`;
const {data} = await axios.get(url);
if (data == true) {
clearInterval(timer);
log('Backend connection stablished!');
resolve(attempts);
}
} catch (error) {
if (error && attempts >= maxAttempts) {
log('Could not connect to backend');
process.exit();
}
}
}, milliseconds);
});
}
test();

View File

@ -111,7 +111,7 @@ describe('Client lock verified data path', () => {
await page.waitToClick(selectors.clientFiscalData.saveButton); await page.waitToClick(selectors.clientFiscalData.saveButton);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
expect(message.text).toContain(`You can't make changes on a client with verified data`); expect(message.text).toContain(`Not enough privileges to edit a client with verified data`);
}); });
}); });
@ -135,7 +135,7 @@ describe('Client lock verified data path', () => {
await page.waitToClick(selectors.clientFiscalData.saveButton); await page.waitToClick(selectors.clientFiscalData.saveButton);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!'); expect(message.text).toContain(`Data saved!`);
}); });
it('should now confirm the social name have been edited once and for all', async() => { it('should now confirm the social name have been edited once and for all', async() => {

View File

@ -19,7 +19,7 @@ describe('InvoiceIn tax path', () => {
it('should add a new tax', async() => { it('should add a new tax', async() => {
await page.waitToClick(selectors.invoiceInTax.addTaxButton); await page.waitToClick(selectors.invoiceInTax.addTaxButton);
await page.autocompleteSearch(selectors.invoiceInTax.thirdExpence, '6210000567'); await page.autocompleteSearch(selectors.invoiceInTax.thirdExpense, '6210000567');
await page.write(selectors.invoiceInTax.thirdTaxableBase, '100'); await page.write(selectors.invoiceInTax.thirdTaxableBase, '100');
await page.autocompleteSearch(selectors.invoiceInTax.thirdTaxType, '6'); await page.autocompleteSearch(selectors.invoiceInTax.thirdTaxType, '6');
await page.autocompleteSearch(selectors.invoiceInTax.thirdTransactionType, 'Operaciones exentas'); await page.autocompleteSearch(selectors.invoiceInTax.thirdTransactionType, 'Operaciones exentas');
@ -37,9 +37,9 @@ describe('InvoiceIn tax path', () => {
expect(result).toEqual('Taxable base €1,323.16'); expect(result).toEqual('Taxable base €1,323.16');
}); });
it('should navigate back to the tax section and check the reciently added line contains the expected expense', async() => { it('should navigate back to tax section, check the reciently added line contains the expected expense', async() => {
await page.accessToSection('invoiceIn.card.tax'); await page.accessToSection('invoiceIn.card.tax');
const result = await page.waitToGetProperty(selectors.invoiceInTax.thirdExpence, 'value'); const result = await page.waitToGetProperty(selectors.invoiceInTax.thirdExpense, 'value');
expect(result).toEqual('6210000567: Alquiler VNH'); expect(result).toEqual('6210000567: Alquiler VNH');
}); });

View File

@ -0,0 +1,60 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Account ACL path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('developer', 'account');
await page.accessToSection('account.acl');
});
afterAll(async() => {
await browser.close();
});
it('should go to create new acl', async() => {
await page.waitToClick(selectors.accountAcl.addAcl);
await page.waitForState('account.acl.create');
});
it('should create new acl', async() => {
await page.autocompleteSearch(selectors.accountAcl.role, 'sysadmin');
await page.autocompleteSearch(selectors.accountAcl.model, 'UserAccount');
await page.autocompleteSearch(selectors.accountAcl.accessType, '*');
await page.autocompleteSearch(selectors.accountAcl.permission, 'ALLOW');
await page.waitToClick(selectors.accountAcl.save);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should navigate to edit', async() => {
await page.doSearch();
await page.waitToClick(selectors.accountAcl.thirdAcl);
await page.waitForState('account.acl.edit');
});
it('should edit the third acl', async() => {
await page.autocompleteSearch(selectors.accountAcl.model, 'Supplier');
await page.autocompleteSearch(selectors.accountAcl.accessType, 'READ');
await page.waitToClick(selectors.accountAcl.save);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should delete the third result', async() => {
const result = await page.waitToGetProperty(selectors.accountAcl.thirdAcl, 'innerText');
await page.waitToClick(selectors.accountAcl.deleteThirdAcl);
await page.waitToClick(selectors.globalItems.acceptButton);
const message = await page.waitForSnackbar();
const newResult = await page.waitToGetProperty(selectors.accountAcl.thirdAcl, 'innerText');
expect(message.text).toContain('ACL removed');
expect(result).not.toEqual(newResult);
});
});

View File

@ -0,0 +1,33 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Account Connections path', () => {
let browser;
let page;
const account = 'sysadmin';
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule(account, 'account');
await page.accessToSection('account.connections');
});
afterAll(async() => {
await browser.close();
});
it('should check this is the last connection', async() => {
const firstResult = await page.waitToGetProperty(selectors.accountConnections.firstConnection, 'innerText');
expect(firstResult).toContain(account);
});
it('should kill this connection and then get redirected to the login page', async() => {
await page.waitToClick(selectors.accountConnections.deleteFirstConnection);
await page.waitToClick(selectors.globalItems.acceptButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Your session has expired, please login again');
});
});

View File

@ -0,0 +1,49 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Account Accounts path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('sysadmin', 'account');
await page.accessToSection('account.accounts');
});
afterAll(async() => {
await browser.close();
});
it('should sync roles', async() => {
await page.waitToClick(selectors.accountAccounts.syncRoles);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Roles synchronized!');
});
it('should sync user', async() => {
await page.waitToClick(selectors.accountAccounts.syncUser);
await page.write(selectors.accountAccounts.syncUserName, 'sysadmin');
await page.write(selectors.accountAccounts.syncUserPassword, 'nightmare');
await page.waitToClick(selectors.accountAccounts.buttonAccept);
const message = await page.waitForSnackbar();
expect(message.text).toContain('User synchronized!');
});
it('should relogin', async() => {
await page.loginAndModule('sysadmin', 'account');
await page.accessToSection('account.accounts');
});
it('should sync all', async() => {
await page.waitToClick(selectors.accountAccounts.syncAll);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Synchronizing in the background');
});
});

View File

@ -0,0 +1,32 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Account LDAP path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('sysadmin', 'account');
await page.accessToSection('account.ldap');
});
afterAll(async() => {
await browser.close();
});
it('should set data and save', async() => {
await page.waitToClick(selectors.accountLdap.checkEnable);
await page.write(selectors.accountLdap.server, '1234');
await page.write(selectors.accountLdap.rdn, '1234');
await page.write(selectors.accountLdap.password, 'nightmare');
await page.write(selectors.accountLdap.userDn, 'sysadmin');
await page.write(selectors.accountLdap.groupDn, '1234');
await page.waitToClick(selectors.accountLdap.save);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
});

View File

@ -0,0 +1,32 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Account Samba path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('sysadmin', 'account');
await page.accessToSection('account.samba');
});
afterAll(async() => {
await browser.close();
});
it('should set data and save', async() => {
await page.waitToClick(selectors.accountSamba.checkEnable);
await page.write(selectors.accountSamba.adDomain, '1234');
await page.write(selectors.accountSamba.adController, '1234');
await page.write(selectors.accountSamba.adUser, 'nightmare');
await page.write(selectors.accountSamba.adPassword, 'sysadmin');
await page.waitToClick(selectors.accountSamba.verifyCert);
await page.waitToClick(selectors.accountSamba.save);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
});

View File

@ -0,0 +1 @@
SelectAllRows: Select the {{rows}} row(s)

View File

@ -0,0 +1,3 @@
SelectAllRows: Seleccionar las {{rows}} fila(s)
All: Se han seleccionado
row(s) have been selected.: fila(s).

View File

@ -2,4 +2,25 @@
ng-model="$ctrl.checked" ng-model="$ctrl.checked"
indeterminate="$ctrl.isIndeterminate" indeterminate="$ctrl.isIndeterminate"
translate-attr="{title: 'Check all'}"> translate-attr="{title: 'Check all'}">
</vn-check> </vn-check>
<vn-icon-button
class="vn-pl-none"
ng-if="$ctrl.isCheckedDummy()"
icon="expand_more"
vn-popover="menu"
ng-click="$ctrl.countRows()">
</vn-icon-button>
<vn-menu
vn-id="menu"
ng-if="$ctrl.isCheckedDummy()">
<vn-list>
<span translate>All</span>
<span class="bold">
{{$ctrl.rows}}
</span>
<span translate>row(s) have been selected.</span>
<span class="bold link" ng-click="$ctrl.checkDummy()">
{{$ctrl.allRowsText}}
</span>
</vn-list>
</vn-menu>

View File

@ -106,6 +106,9 @@ export default class MultiCheck extends FormInput {
this.toggle(); this.toggle();
this.emit('change', value); this.emit('change', value);
if (!value)
this.checkedDummyCount = null;
} }
/** /**
@ -132,12 +135,48 @@ export default class MultiCheck extends FormInput {
areAllUnchecked() { areAllUnchecked() {
if (!this.model || !this.model.data) return; if (!this.model || !this.model.data) return;
this.checkedDummyCount = null;
const data = this.model.data; const data = this.model.data;
return data.every(item => { return data.every(item => {
return item[this.checkField] === false; return item[this.checkField] === false;
}); });
} }
countRows() {
if (!this.model || !this.model.data) return;
const data = this.model.data;
const params = {
filter: {
limit: null
}
};
if (this.model.userFilter)
Object.assign(params.filter, this.model.userFilter);
if (this.model.userParams)
Object.assign(params, this.model.userParams);
this.rows = data.length;
this.$http.get(this.model.url, {params})
.then(res => {
this.allRowsCount = res.data.length;
this.allRowsText = this.$t('SelectAllRows', {
rows: this.allRowsCount
});
});
}
checkDummy() {
if (this.checkedDummyCount)
return this.checkedDummyCount = null;
this.checkedDummyCount = this.allRowsCount;
}
isCheckedDummy() {
return this.checked && this.checkDummyEnabled;
}
/** /**
* Toggles checked property on * Toggles checked property on
* all instances * all instances
@ -158,7 +197,9 @@ ngModule.vnComponent('vnMultiCheck', {
checkField: '@?', checkField: '@?',
checkAll: '=?', checkAll: '=?',
checked: '=?', checked: '=?',
disabled: '<?' disabled: '<?',
checkDummyEnabled: '<?',
checkedDummyCount: '=?'
} }
}); });

View File

@ -4,10 +4,14 @@ import crudModel from 'core/mocks/crud-model';
describe('Component vnMultiCheck', () => { describe('Component vnMultiCheck', () => {
let controller; let controller;
let $element; let $element;
let $httpBackend;
let $httpParamSerializer;
beforeEach(ngModule('vnCore')); beforeEach(ngModule('vnCore'));
beforeEach(inject($componentController => { beforeEach(inject(($componentController, _$httpBackend_, _$httpParamSerializer_) => {
$httpBackend = _$httpBackend_;
$httpParamSerializer = _$httpParamSerializer_;
$element = angular.element(`<div class="shown"></div>`); $element = angular.element(`<div class="shown"></div>`);
controller = $componentController('vnMultiCheck', {$element: $element}); controller = $componentController('vnMultiCheck', {$element: $element});
controller._model = crudModel; controller._model = crudModel;
@ -26,6 +30,14 @@ describe('Component vnMultiCheck', () => {
expect(controller._checked).toEqual(crudModel); expect(controller._checked).toEqual(crudModel);
expect(controller.toggle).toHaveBeenCalledWith(); expect(controller.toggle).toHaveBeenCalledWith();
}); });
it(`should set checkedDummyCount to null`, () => {
jest.spyOn(controller, 'toggle');
controller.checkedDummyCount = 12;
controller.checked = null;
expect(controller.checkedDummyCount).toBeNull();
});
}); });
describe('toggle()', () => { describe('toggle()', () => {
@ -132,4 +144,76 @@ describe('Component vnMultiCheck', () => {
expect(thirdRow.checked).toBeTruthy(); expect(thirdRow.checked).toBeTruthy();
}); });
}); });
describe('countRows()', () => {
it(`should count visible rows and all rows of model`, () => {
controller.model.url = 'modelUrl/filter';
const data = controller.model.data;
const filter = {
limit: null
};
const serializedParams = $httpParamSerializer({filter});
const response = [
{id: 1, name: 'My item 1'},
{id: 2, name: 'My item 2'},
{id: 3, name: 'My item 3'},
{id: 4, name: 'My item 4'},
{id: 5, name: 'My item 5'},
{id: 6, name: 'My item 6'}
];
controller.countRows();
$httpBackend.expectGET(`modelUrl/filter?${serializedParams}`).respond(response);
$httpBackend.flush();
expect(controller.rows).toEqual(data.length);
expect(controller.allRowsCount).toEqual(response.length);
expect(controller.allRowsCount).toBeGreaterThan(controller.rows);
});
});
describe('checkDummy()', () => {
const allRows = 1234;
it(`should set the checked dummy count to all rows count if there was no count yet`, () => {
controller.checkedDummyCount = null;
controller.allRowsCount = allRows;
controller.checkDummy();
expect(controller.checkedDummyCount).toEqual(controller.allRowsCount);
});
it(`should remove the dummy count if there was an existing one`, () => {
controller.checkedDummyCount = allRows;
controller.checkDummy();
expect(controller.checkedDummyCount).toBeNull();
});
});
describe('isCheckedDummy()', () => {
it(`should return true only if is checked and checked dummy is enabled`, () => {
controller.checked = true;
controller.checkDummyEnabled = true;
const isCheckedDummy = controller.isCheckedDummy();
expect(isCheckedDummy).toEqual(true);
});
it(`should return false if not checked`, () => {
controller.checked = false;
controller.checkDummyEnabled = true;
const isCheckedDummy = controller.isCheckedDummy();
expect(isCheckedDummy).toEqual(false);
});
it(`should return false if checked dummy is disabled`, () => {
controller.checked = true;
controller.checkDummyEnabled = false;
const isCheckedDummy = controller.isCheckedDummy();
expect(isCheckedDummy).toEqual(false);
});
});
}); });

View File

@ -1,5 +1,10 @@
@import "variables";
vn-multi-check { vn-multi-check {
.vn-check { .vn-check {
margin-bottom: 12px margin-bottom: 12px
} }
}
.bold{
font-weight: bold;
} }

View File

@ -46,11 +46,13 @@
</div> </div>
</vn-horizontal> </vn-horizontal>
<div id="table"></div> <div id="table"></div>
<vn-pagination <div ng-transclude="pagination">
ng-if="$ctrl.model" <vn-pagination
model="$ctrl.model" ng-if="$ctrl.model"
class="vn-pt-md"> model="$ctrl.model"
</vn-pagination> class="vn-pt-md">
</vn-pagination>
</div>
</div> </div>
<vn-confirm <vn-confirm

View File

@ -318,6 +318,8 @@ export default class SmartTable extends Component {
for (let column of columns) { for (let column of columns) {
const field = column.getAttribute('field'); const field = column.getAttribute('field');
const cell = document.createElement('td'); const cell = document.createElement('td');
cell.setAttribute('centered', '');
if (field) { if (field) {
let input; let input;
let options; let options;
@ -331,6 +333,15 @@ export default class SmartTable extends Component {
continue; continue;
} }
input = this.$compile(`
<vn-textfield
class="dense"
name="${field}"
ng-model="searchProps['${field}']"
ng-keydown="$ctrl.searchWithEvent($event, '${field}')"
clear-disabled="true"
/>`)(this.$inputsScope);
if (options && options.autocomplete) { if (options && options.autocomplete) {
let props = ``; let props = ``;
@ -346,16 +357,29 @@ export default class SmartTable extends Component {
on-change="$ctrl.searchByColumn('${field}')" on-change="$ctrl.searchByColumn('${field}')"
clear-disabled="true" clear-disabled="true"
/>`)(this.$inputsScope); />`)(this.$inputsScope);
} else { }
if (options && options.checkbox) {
input = this.$compile(` input = this.$compile(`
<vn-textfield <vn-check
class="dense" class="dense"
name="${field}" name="${field}"
ng-model="searchProps['${field}']" ng-model="searchProps['${field}']"
ng-keydown="$ctrl.searchWithEvent($event, '${field}')" on-change="$ctrl.searchByColumn('${field}')"
clear-disabled="true" triple-state="true"
/>`)(this.$inputsScope); />`)(this.$inputsScope);
} }
if (options && options.datepicker) {
input = this.$compile(`
<vn-date-picker
class="dense"
name="${field}"
ng-model="searchProps['${field}']"
on-change="$ctrl.searchByColumn('${field}')"
/>`)(this.$inputsScope);
}
cell.appendChild(input[0]); cell.appendChild(input[0]);
} }
searchRow.appendChild(cell); searchRow.appendChild(cell);
@ -372,13 +396,12 @@ export default class SmartTable extends Component {
searchByColumn(field) { searchByColumn(field) {
const searchCriteria = this.$inputsScope.searchProps[field]; const searchCriteria = this.$inputsScope.searchProps[field];
const emptySearch = searchCriteria == '' || null; const emptySearch = searchCriteria === '' || searchCriteria == null;
const filters = this.filterSanitizer(field); const filters = this.filterSanitizer(field);
if (filters && filters.userFilter) if (filters && filters.userFilter)
this.model.userFilter = filters.userFilter; this.model.userFilter = filters.userFilter;
if (!emptySearch) if (!emptySearch)
this.addFilter(field, this.$inputsScope.searchProps[field]); this.addFilter(field, this.$inputsScope.searchProps[field]);
else this.model.refresh(); else this.model.refresh();
@ -497,7 +520,8 @@ ngModule.vnComponent('smartTable', {
controller: SmartTable, controller: SmartTable,
transclude: { transclude: {
table: '?slotTable', table: '?slotTable',
actions: '?slotActions' actions: '?slotActions',
pagination: '?slotPagination'
}, },
bindings: { bindings: {
model: '<?', model: '<?',

View File

@ -26,7 +26,7 @@
.icon-agency-term:before { .icon-agency-term:before {
content: "\e950"; content: "\e950";
} }
.icon-deaulter:before { .icon-defaulter:before {
content: "\e94b"; content: "\e94b";
} }
.icon-100:before { .icon-100:before {

View File

@ -3,8 +3,6 @@ const gulp = require('gulp');
const PluginError = require('plugin-error'); const PluginError = require('plugin-error');
const argv = require('minimist')(process.argv.slice(2)); const argv = require('minimist')(process.argv.slice(2));
const log = require('fancy-log'); const log = require('fancy-log');
const got = require('got');
const e2eConfig = require('./e2e/helpers/config.js');
const Docker = require('./db/docker.js'); const Docker = require('./db/docker.js');
// Configuration // Configuration
@ -67,188 +65,6 @@ back.description = `Starts backend and database service`;
const defaultTask = gulp.parallel(front, back); const defaultTask = gulp.parallel(front, back);
defaultTask.description = `Starts all application services`; defaultTask.description = `Starts all application services`;
// Backend tests - Private method
async function launchBackTest(done) {
let err;
let dataSources = require('./loopback/server/datasources.json');
const container = new Docker();
await container.run(argv.ci);
dataSources = JSON.parse(JSON.stringify(dataSources));
Object.assign(dataSources.vn, {
host: container.dbConf.host,
port: container.dbConf.port
});
let bootOptions = {dataSources};
let app = require(`./loopback/server/server`);
try {
app.boot(bootOptions);
await new Promise((resolve, reject) => {
const jasmine = require('gulp-jasmine');
const options = {
verbose: false,
includeStackTrace: false,
errorOnFail: false,
timeout: 5000,
config: {}
};
if (argv.ci) {
const reporters = require('jasmine-reporters');
options.reporter = new reporters.JUnitXmlReporter();
}
let backSpecFiles = [
'back/helpers.spec.js',
'back/**/*.spec.js',
'loopback/**/*.spec.js',
'modules/*/back/**/*.spec.js'
];
gulp.src(backSpecFiles)
.pipe(jasmine(options))
.on('end', resolve)
.on('error', reject)
.resume();
});
} catch (e) {
err = e;
}
await app.disconnect();
await container.rm();
done();
if (err)
throw err;
}
launchBackTest.description = `
Runs the backend tests once using a random container, can receive --ci arg to save reports on a xml file`;
// Backend tests
function backTest(done) {
const nodemon = require('gulp-nodemon');
nodemon({
exec: ['node --tls-min-v1.0 ./node_modules/gulp/bin/gulp.js'],
args: ['launchBackTest'],
watch: backSources,
done: done
});
}
backTest.description = `Watches for changes in modules to execute backTest task`;
// End to end tests
function e2eSingleRun() {
require('@babel/register')({presets: ['@babel/env']});
require('core-js/stable');
require('regenerator-runtime/runtime');
const jasmine = require('gulp-jasmine');
const SpecReporter = require('jasmine-spec-reporter').SpecReporter;
if (argv.show || argv.s)
process.env.E2E_SHOW = true;
const specFiles = [
`${__dirname}/e2e/paths/01*/*[sS]pec.js`,
`${__dirname}/e2e/paths/02*/*[sS]pec.js`,
`${__dirname}/e2e/paths/03*/*[sS]pec.js`,
`${__dirname}/e2e/paths/04*/*[sS]pec.js`,
`${__dirname}/e2e/paths/05*/*[sS]pec.js`,
`${__dirname}/e2e/paths/06*/*[sS]pec.js`,
`${__dirname}/e2e/paths/07*/*[sS]pec.js`,
`${__dirname}/e2e/paths/08*/*[sS]pec.js`,
`${__dirname}/e2e/paths/09*/*[sS]pec.js`,
`${__dirname}/e2e/paths/10*/*[sS]pec.js`,
`${__dirname}/e2e/paths/11*/*[sS]pec.js`,
`${__dirname}/e2e/paths/12*/*[sS]pec.js`,
`${__dirname}/e2e/paths/13*/*[sS]pec.js`,
`${__dirname}/e2e/paths/**/*[sS]pec.js`
];
return gulp.src(specFiles).pipe(jasmine({
errorOnFail: false,
timeout: 30000,
config: {
random: false,
// TODO: Waiting for this option to be implemented
// https://github.com/jasmine/jasmine/issues/1533
stopSpecOnExpectationFailure: false
},
reporter: [
new SpecReporter({
spec: {
displayStacktrace: 'none',
displaySuccessful: true,
displayFailedSpec: true,
displaySpecDuration: true,
},
summary: {
displayStacktrace: 'raw',
displayPending: false
},
colors: {
enabled: true,
successful: 'brightGreen',
failed: 'brightRed'
},
// stacktrace: {
// filter: stacktrace => {
// const lines = stacktrace.split('\n');
// const filtered = [];
// for (let i = 1; i < lines.length; i++) {
// if (/e2e\/paths/.test(lines[i]))
// filtered.push(lines[i]);
// }
// return filtered.join('\n');
// }
// }
})
]
}));
}
e2e = gulp.series(docker, async function isBackendReady() {
const attempts = await backendStatus();
log(`Backend ready after ${attempts} attempt(s)`);
return attempts;
}, e2eSingleRun);
e2e.description = `Restarts database and runs the e2e tests`;
async function backendStatus() {
const milliseconds = 250;
return new Promise(resolve => {
let timer;
let attempts = 1;
timer = setInterval(async() => {
try {
const url = `${e2eConfig.url}/api/Applications/status`;
const {body} = await got.get(url);
if (body == 'true') {
clearInterval(timer);
resolve(attempts);
} else
attempts++;
} catch (error) {
if (error || attempts > 100) // 250ms * 100 => 25s timeout
throw new Error('Could not connect to backend');
}
}, milliseconds);
});
}
backendStatus.description = `Performs a simple requests to check the backend status`;
function install() { function install() {
const install = require('gulp-install'); const install = require('gulp-install');
const print = require('gulp-print'); const print = require('gulp-print');
@ -432,9 +248,6 @@ module.exports = {
back, back,
backOnly, backOnly,
backWatch, backWatch,
backTest,
launchBackTest,
e2e,
i, i,
install, install,
build, build,
@ -445,6 +258,5 @@ module.exports = {
locales, locales,
localesRoutes, localesRoutes,
watch, watch,
docker, docker
backendStatus,
}; };

Some files were not shown because too many files have changed in this diff Show More