Merge branch '6451_insomnia' of https://gitea.verdnatura.es/verdnatura/salix into 6451_insomnia
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
42c622223e
|
@ -11,27 +11,12 @@
|
||||||
"[javascript]": {
|
"[javascript]": {
|
||||||
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
||||||
},
|
},
|
||||||
|
"[json]": {
|
||||||
|
"editor.defaultFormatter": "vscode.json-language-features"
|
||||||
|
},
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"salix",
|
"salix",
|
||||||
"fdescribe"
|
"fdescribe",
|
||||||
],
|
"Loggable"
|
||||||
"rest-client.previewOption": "body",
|
]
|
||||||
"rest-client.environmentVariables": {
|
|
||||||
"$shared": {
|
|
||||||
"version": "v1",
|
|
||||||
"prodToken": "verdnatura",
|
|
||||||
"nonProdToken": "verdnatura"
|
|
||||||
},
|
|
||||||
"local": {
|
|
||||||
"version": "v2",
|
|
||||||
"host": "http://localhost:3000",
|
|
||||||
"token": "{{$shared nonProdToken}}",
|
|
||||||
"secretKey": "devSecret"
|
|
||||||
},
|
|
||||||
"production": {
|
|
||||||
"host": "example.com",
|
|
||||||
"token": "{{$shared prodToken}}",
|
|
||||||
"secretKey" : "prodSecret"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
20
CHANGELOG.md
20
CHANGELOG.md
|
@ -5,7 +5,20 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [2352.01] - 2023-12-28
|
## [2404.01] - 2024-01-25
|
||||||
|
|
||||||
|
### Added
|
||||||
|
### Changed
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
|
||||||
|
## [2402.01] - 2024-01-11
|
||||||
|
|
||||||
|
### Added
|
||||||
|
### Changed
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
## [2400.01] - 2024-01-04
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -13,9 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [2350.01] - 2023-12-14
|
## [2350.01] - 2023-12-14
|
||||||
|
|
||||||
### Added
|
### Características Añadidas 🆕
|
||||||
### Changed
|
- **Tickets → Expediciones:** Añadido soporte para Viaexpress
|
||||||
### Fixed
|
|
||||||
|
|
||||||
|
|
||||||
## [2348.01] - 2023-11-30
|
## [2348.01] - 2023-11-30
|
||||||
|
|
|
@ -22,8 +22,8 @@ module.exports = Self => {
|
||||||
|
|
||||||
Self.removeFile = async(ctx, id, options) => {
|
Self.removeFile = async(ctx, id, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
let tx;
|
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
|
@ -24,15 +24,40 @@ describe('docuware upload()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should try upload file', async() => {
|
it('should try upload file', async() => {
|
||||||
|
const tx = await models.Docuware.beginTransaction({});
|
||||||
spyOn(ticketModel, 'deliveryNotePdf').and.returnValue(new Promise(resolve => resolve({})));
|
spyOn(ticketModel, 'deliveryNotePdf').and.returnValue(new Promise(resolve => resolve({})));
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
try {
|
try {
|
||||||
await models.Docuware.upload(ctx, ticketIds, fileCabinetName);
|
const options = {transaction: tx};
|
||||||
|
const user = await models.UserConfig.findById(userId, null, options);
|
||||||
|
await user.updateAttribute('tabletFk', 'Tablet1', options);
|
||||||
|
await models.Docuware.upload(ctx, ticketIds, fileCabinetName, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e.message;
|
error = e;
|
||||||
|
await tx.rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(error).toEqual('Action not allowed on the test environment');
|
expect(error.message).toEqual('Action not allowed on the test environment');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw error when not have tablet assigned', async() => {
|
||||||
|
const tx = await models.Docuware.beginTransaction({});
|
||||||
|
spyOn(ticketModel, 'deliveryNotePdf').and.returnValue(new Promise(resolve => resolve({})));
|
||||||
|
|
||||||
|
let error;
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
await models.Docuware.upload(ctx, ticketIds, fileCabinetName, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
await tx.rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error.message).toEqual('This user does not have an assigned tablet');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,12 +29,24 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.upload = async function(ctx, ticketIds, fileCabinet) {
|
Self.upload = async function(ctx, ticketIds, fileCabinet, options) {
|
||||||
delete ctx.args.ticketIds;
|
delete ctx.args.ticketIds;
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const action = 'store';
|
const action = 'store';
|
||||||
|
|
||||||
const options = await Self.getOptions();
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const userConfig = await models.UserConfig.findById(ctx.req.accessToken.userId, {
|
||||||
|
fields: ['tabletFk']
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
if (!userConfig?.tabletFk)
|
||||||
|
throw new UserError('This user does not have an assigned tablet');
|
||||||
|
|
||||||
|
const docuwareOptions = await Self.getOptions();
|
||||||
const fileCabinetId = await Self.getFileCabinet(fileCabinet);
|
const fileCabinetId = await Self.getFileCabinet(fileCabinet);
|
||||||
const dialogId = await Self.getDialog(fileCabinet, action, fileCabinetId);
|
const dialogId = await Self.getDialog(fileCabinet, action, fileCabinetId);
|
||||||
|
|
||||||
|
@ -45,7 +57,7 @@ module.exports = Self => {
|
||||||
const deliveryNote = await models.Ticket.deliveryNotePdf(ctx, {
|
const deliveryNote = await models.Ticket.deliveryNotePdf(ctx, {
|
||||||
id,
|
id,
|
||||||
type: 'deliveryNote'
|
type: 'deliveryNote'
|
||||||
});
|
}, myOptions);
|
||||||
// get ticket data
|
// get ticket data
|
||||||
const ticket = await models.Ticket.findById(id, {
|
const ticket = await models.Ticket.findById(id, {
|
||||||
include: [{
|
include: [{
|
||||||
|
@ -54,7 +66,7 @@ module.exports = Self => {
|
||||||
fields: ['id', 'name', 'fi']
|
fields: ['id', 'name', 'fi']
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
});
|
}, myOptions);
|
||||||
|
|
||||||
// upload file
|
// upload file
|
||||||
const templateJson = {
|
const templateJson = {
|
||||||
|
@ -102,7 +114,7 @@ module.exports = Self => {
|
||||||
{
|
{
|
||||||
'FieldName': 'FILTRO_TABLET',
|
'FieldName': 'FILTRO_TABLET',
|
||||||
'ItemElementName': 'string',
|
'ItemElementName': 'string',
|
||||||
'Item': 'Tablet1',
|
'Item': userConfig.tabletFk,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
@ -116,11 +128,11 @@ module.exports = Self => {
|
||||||
const deleteJson = {
|
const deleteJson = {
|
||||||
'Field': [{'FieldName': 'ESTADO', 'Item': 'Pendiente eliminar', 'ItemElementName': 'String'}]
|
'Field': [{'FieldName': 'ESTADO', 'Item': 'Pendiente eliminar', 'ItemElementName': 'String'}]
|
||||||
};
|
};
|
||||||
const deleteUri = `${options.url}/FileCabinets/${fileCabinetId}/Documents/${docuwareFile.id}/Fields`;
|
const deleteUri = `${docuwareOptions.url}/FileCabinets/${fileCabinetId}/Documents/${docuwareFile.id}/Fields`;
|
||||||
await axios.put(deleteUri, deleteJson, options.headers);
|
await axios.put(deleteUri, deleteJson, docuwareOptions.headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uploadUri = `${options.url}/FileCabinets/${fileCabinetId}/Documents?StoreDialogId=${dialogId}`;
|
const uploadUri = `${docuwareOptions.url}/FileCabinets/${fileCabinetId}/Documents?StoreDialogId=${dialogId}`;
|
||||||
const FormData = require('form-data');
|
const FormData = require('form-data');
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
|
|
||||||
|
@ -130,7 +142,7 @@ module.exports = Self => {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data',
|
'Content-Type': 'multipart/form-data',
|
||||||
'X-File-ModifiedDate': Date.vnNew(),
|
'X-File-ModifiedDate': Date.vnNew(),
|
||||||
'Cookie': options.headers.headers.Cookie,
|
'Cookie': docuwareOptions.headers.headers.Cookie,
|
||||||
...data.getHeaders()
|
...data.getHeaders()
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -141,11 +153,11 @@ module.exports = Self => {
|
||||||
const $t = ctx.req.__;
|
const $t = ctx.req.__;
|
||||||
const message = $t('Failed to upload delivery note', {id});
|
const message = $t('Failed to upload delivery note', {id});
|
||||||
if (uploaded.length)
|
if (uploaded.length)
|
||||||
await models.TicketTracking.setDelivered(ctx, uploaded);
|
await models.TicketTracking.setDelivered(ctx, uploaded, myOptions);
|
||||||
throw new UserError(message);
|
throw new UserError(message);
|
||||||
}
|
}
|
||||||
uploaded.push(id);
|
uploaded.push(id);
|
||||||
}
|
}
|
||||||
return models.TicketTracking.setDelivered(ctx, ticketIds);
|
return models.TicketTracking.setDelivered(ctx, ticketIds, myOptions);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -68,7 +68,7 @@ module.exports = Self => {
|
||||||
userToUpdate.hasGrant = hasGrant;
|
userToUpdate.hasGrant = hasGrant;
|
||||||
|
|
||||||
if (roleFk) {
|
if (roleFk) {
|
||||||
const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions);
|
const role = await models.VnRole.findById(roleFk, {fields: ['name']}, myOptions);
|
||||||
const hasRole = await Self.hasRole(userId, role.name, myOptions);
|
const hasRole = await Self.hasRole(userId, role.name, myOptions);
|
||||||
|
|
||||||
if (!hasRole)
|
if (!hasRole)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
const {models} = require('vn-loopback/server/server');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('renewToken', {
|
Self.remoteMethodCtx('renewToken', {
|
||||||
|
@ -16,20 +16,31 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.renewToken = async function(ctx) {
|
Self.renewToken = async function(ctx) {
|
||||||
const models = Self.app.models;
|
const {accessToken: token} = ctx.req;
|
||||||
const token = ctx.req.accessToken;
|
|
||||||
|
|
||||||
const now = new Date();
|
// Check if current token is valid
|
||||||
|
|
||||||
|
const {renewPeriod, courtesyTime} = await models.AccessTokenConfig.findOne({
|
||||||
|
fields: ['renewPeriod', 'courtesyTime']
|
||||||
|
});
|
||||||
|
const now = Date.now();
|
||||||
const differenceMilliseconds = now - token.created;
|
const differenceMilliseconds = now - token.created;
|
||||||
const differenceSeconds = Math.floor(differenceMilliseconds / 1000);
|
const differenceSeconds = Math.floor(differenceMilliseconds / 1000);
|
||||||
|
const isNotExceeded = differenceSeconds < renewPeriod - courtesyTime;
|
||||||
|
if (isNotExceeded)
|
||||||
|
return token;
|
||||||
|
|
||||||
const fields = ['renewPeriod', 'courtesyTime'];
|
// Schedule to remove current token
|
||||||
const accessTokenConfig = await models.AccessTokenConfig.findOne({fields});
|
setTimeout(async() => {
|
||||||
|
try {
|
||||||
if (differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime)
|
|
||||||
throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded');
|
|
||||||
|
|
||||||
await Self.logout(token.id);
|
await Self.logout(token.id);
|
||||||
|
} catch (err) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}, courtesyTime * 1000);
|
||||||
|
|
||||||
|
// Create new accessToken
|
||||||
const user = await Self.findById(token.userId);
|
const user = await Self.findById(token.userId);
|
||||||
const accessToken = await user.createAccessToken();
|
const accessToken = await user.createAccessToken();
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ describe('VnUser privileges()', () => {
|
||||||
const tx = await models.VnUser.beginTransaction({});
|
const tx = await models.VnUser.beginTransaction({});
|
||||||
|
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
const agency = await models.Role.findOne({
|
const agency = await models.VnRole.findOne({
|
||||||
where: {
|
where: {
|
||||||
name: 'agency'
|
name: 'agency'
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
const {models} = require('vn-loopback/server/server');
|
||||||
|
describe('Renew Token', () => {
|
||||||
|
const startingTime = Date.now();
|
||||||
|
let ctx = null;
|
||||||
|
beforeAll(async() => {
|
||||||
|
const unAuthCtx = {
|
||||||
|
req: {
|
||||||
|
headers: {},
|
||||||
|
connection: {
|
||||||
|
remoteAddress: '127.0.0.1'
|
||||||
|
},
|
||||||
|
getLocale: () => 'en'
|
||||||
|
},
|
||||||
|
args: {}
|
||||||
|
};
|
||||||
|
let login = await models.VnUser.signIn(unAuthCtx, 'salesAssistant', 'nightmare');
|
||||||
|
let accessToken = await models.AccessToken.findById(login.token);
|
||||||
|
ctx = {req: {accessToken: accessToken}};
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jasmine.clock().install();
|
||||||
|
jasmine.clock().mockDate(new Date(startingTime));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jasmine.clock().uninstall();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should renew token', async() => {
|
||||||
|
const mockDate = new Date(startingTime + 26600000);
|
||||||
|
jasmine.clock().mockDate(mockDate);
|
||||||
|
const {id} = await models.VnUser.renewToken(ctx);
|
||||||
|
|
||||||
|
expect(id).not.toEqual(ctx.req.accessToken.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('NOT should renew', async() => {
|
||||||
|
let error;
|
||||||
|
let response;
|
||||||
|
try {
|
||||||
|
response = await models.VnUser.renewToken(ctx);
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toBeUndefined();
|
||||||
|
expect(response.id).toEqual(ctx.req.accessToken.id);
|
||||||
|
});
|
||||||
|
});
|
|
@ -20,10 +20,7 @@ describe('VnUser Sign-in()', () => {
|
||||||
let ctx = {req: {accessToken: accessToken}};
|
let ctx = {req: {accessToken: accessToken}};
|
||||||
let signInLog = await SignInLog.find({where: {token: accessToken.id}});
|
let signInLog = await SignInLog.find({where: {token: accessToken.id}});
|
||||||
|
|
||||||
expect(signInLog.length).toEqual(1);
|
expect(signInLog.length).toEqual(0);
|
||||||
expect(signInLog[0].userFk).toEqual(accessToken.userId);
|
|
||||||
expect(signInLog[0].owner).toEqual(true);
|
|
||||||
expect(login.token).toBeDefined();
|
|
||||||
|
|
||||||
await VnUser.logout(ctx.req.accessToken.id);
|
await VnUser.logout(ctx.req.accessToken.id);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethod('validateToken', {
|
|
||||||
description: 'Validates the current logged user token',
|
|
||||||
returns: {
|
|
||||||
type: 'Boolean',
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/validateToken`,
|
|
||||||
verb: 'GET'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.validateToken = async function() {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -139,9 +139,6 @@
|
||||||
"Warehouse": {
|
"Warehouse": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"VnUser": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"OsTicket": {
|
"OsTicket": {
|
||||||
"dataSource": "osticket"
|
"dataSource": "osticket"
|
||||||
},
|
},
|
||||||
|
@ -156,6 +153,12 @@
|
||||||
},
|
},
|
||||||
"ViaexpressConfig": {
|
"ViaexpressConfig": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"VnUser": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"VnRole": {
|
||||||
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,12 @@
|
||||||
"relations": {
|
"relations": {
|
||||||
"readRole": {
|
"readRole": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "readRoleFk"
|
"foreignKey": "readRoleFk"
|
||||||
},
|
},
|
||||||
"writeRole": {
|
"writeRole": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "writeRoleFk"
|
"foreignKey": "writeRoleFk"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "docuwareTablet",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "docuwareTablet"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"tablet": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,12 +46,12 @@
|
||||||
},
|
},
|
||||||
"readRole": {
|
"readRole": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "readRoleFk"
|
"foreignKey": "readRoleFk"
|
||||||
},
|
},
|
||||||
"writeRole": {
|
"writeRole": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "writeRoleFk"
|
"foreignKey": "writeRoleFk"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -64,4 +64,3 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
},
|
},
|
||||||
"role": {
|
"role": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "roleFk"
|
"foreignKey": "roleFk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('loopback model MailAliasAccount', () => {
|
||||||
|
it('should fail to add a mail Alias if the worker doesnt have ACLs', async() => {
|
||||||
|
const tx = await models.MailAliasAccount.beginTransaction({});
|
||||||
|
let error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx, accessToken: {userId: 57}};
|
||||||
|
await models.MailAliasAccount.create({mailAlias: 2, account: 5}, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error.message).toEqual('The alias cant be modified');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add a mail Alias', async() => {
|
||||||
|
const tx = await models.MailAliasAccount.beginTransaction({});
|
||||||
|
let error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx, accessToken: {userId: 9}};
|
||||||
|
await models.MailAliasAccount.create({mailAlias: 2, account: 5}, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add a mail Alias of an inherit role', async() => {
|
||||||
|
const tx = await models.MailAliasAccount.beginTransaction({});
|
||||||
|
let error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx, accessToken: {userId: 9}};
|
||||||
|
await models.MailAliasAccount.create({mailAlias: 3, account: 5}, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete a mail Alias', async() => {
|
||||||
|
const tx = await models.MailAliasAccount.beginTransaction({});
|
||||||
|
let error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx, accessToken: {userId: 1}};
|
||||||
|
const mailAclId = 2;
|
||||||
|
await models.MailAliasAccount.destroyAll({id: mailAclId}, options);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
},
|
},
|
||||||
"darkMode": {
|
"darkMode": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"tabletFk": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
@ -43,6 +46,11 @@
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "VnUser",
|
"model": "VnUser",
|
||||||
"foreignKey": "userFk"
|
"foreignKey": "userFk"
|
||||||
|
},
|
||||||
|
"Tablet": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "docuwareTablet",
|
||||||
|
"foreignKey": "tabletFk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"name": "VnRole",
|
||||||
|
"base": "Role",
|
||||||
|
"validateUpsert": true,
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "account.role"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,6 @@ module.exports = function(Self) {
|
||||||
require('../methods/vn-user/sign-in')(Self);
|
require('../methods/vn-user/sign-in')(Self);
|
||||||
require('../methods/vn-user/acl')(Self);
|
require('../methods/vn-user/acl')(Self);
|
||||||
require('../methods/vn-user/recover-password')(Self);
|
require('../methods/vn-user/recover-password')(Self);
|
||||||
require('../methods/vn-user/validate-token')(Self);
|
|
||||||
require('../methods/vn-user/privileges')(Self);
|
require('../methods/vn-user/privileges')(Self);
|
||||||
require('../methods/vn-user/validate-auth')(Self);
|
require('../methods/vn-user/validate-auth')(Self);
|
||||||
require('../methods/vn-user/renew-token')(Self);
|
require('../methods/vn-user/renew-token')(Self);
|
||||||
|
@ -135,6 +134,7 @@ module.exports = function(Self) {
|
||||||
Self.signInValidate = async(user, userToken, token, ctx) => {
|
Self.signInValidate = async(user, userToken, token, ctx) => {
|
||||||
const [[key, value]] = Object.entries(Self.userUses(user));
|
const [[key, value]] = Object.entries(Self.userUses(user));
|
||||||
const isOwner = Self.rawSql(`SELECT ? = ? `, [userToken[key], value]);
|
const isOwner = Self.rawSql(`SELECT ? = ? `, [userToken[key], value]);
|
||||||
|
if (!isOwner) {
|
||||||
await Self.app.models.SignInLog.create({
|
await Self.app.models.SignInLog.create({
|
||||||
userName: user,
|
userName: user,
|
||||||
token: token.id,
|
token: token.id,
|
||||||
|
@ -142,8 +142,8 @@ module.exports = function(Self) {
|
||||||
ip: ctx.req.ip,
|
ip: ctx.req.ip,
|
||||||
owner: isOwner
|
owner: isOwner
|
||||||
});
|
});
|
||||||
if (!isOwner)
|
|
||||||
throw new UserError('Try again');
|
throw new UserError('Try again');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
"table": "account.user"
|
"table": "account.user"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
},
|
||||||
"resetPasswordTokenTTL": "604800",
|
"resetPasswordTokenTTL": "604800",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
|
@ -63,7 +66,7 @@
|
||||||
"relations": {
|
"relations": {
|
||||||
"role": {
|
"role": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "roleFk"
|
"foreignKey": "roleFk"
|
||||||
},
|
},
|
||||||
"roles": {
|
"roles": {
|
||||||
|
@ -95,34 +98,30 @@
|
||||||
"principalType": "ROLE",
|
"principalType": "ROLE",
|
||||||
"principalId": "$everyone",
|
"principalId": "$everyone",
|
||||||
"permission": "ALLOW"
|
"permission": "ALLOW"
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
"property": "recoverPassword",
|
"property": "recoverPassword",
|
||||||
"accessType": "EXECUTE",
|
"accessType": "EXECUTE",
|
||||||
"principalType": "ROLE",
|
"principalType": "ROLE",
|
||||||
"principalId": "$everyone",
|
"principalId": "$everyone",
|
||||||
"permission": "ALLOW"
|
"permission": "ALLOW"
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
"property": "validateToken",
|
|
||||||
"accessType": "EXECUTE",
|
|
||||||
"principalType": "ROLE",
|
|
||||||
"principalId": "$authenticated",
|
|
||||||
"permission": "ALLOW"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"property": "validateAuth",
|
"property": "validateAuth",
|
||||||
"accessType": "EXECUTE",
|
"accessType": "EXECUTE",
|
||||||
"principalType": "ROLE",
|
"principalType": "ROLE",
|
||||||
"principalId": "$everyone",
|
"principalId": "$everyone",
|
||||||
"permission": "ALLOW"
|
"permission": "ALLOW"
|
||||||
},
|
}, {
|
||||||
{
|
|
||||||
"property": "privileges",
|
"property": "privileges",
|
||||||
"accessType": "*",
|
"accessType": "*",
|
||||||
"principalType": "ROLE",
|
"principalType": "ROLE",
|
||||||
"principalId": "$authenticated",
|
"principalId": "$authenticated",
|
||||||
"permission": "ALLOW"
|
"permission": "ALLOW"
|
||||||
|
}, {
|
||||||
|
"property": "renewToken",
|
||||||
|
"accessType": "WRITE",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$authenticated",
|
||||||
|
"permission": "ALLOW"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"scopes": {
|
"scopes": {
|
||||||
|
|
|
@ -7,6 +7,10 @@ process.on('warning', warning => {
|
||||||
console.log(warning.stack);
|
console.log(warning.stack);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
process.on('SIGUSR2', async() => {
|
||||||
|
if (container) await container.rm();
|
||||||
|
});
|
||||||
|
|
||||||
process.on('exit', async function() {
|
process.on('exit', async function() {
|
||||||
if (container) await container.rm();
|
if (container) await container.rm();
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
-- Auto-generated SQL script #202311061003
|
||||||
|
UPDATE salix.accessTokenConfig
|
||||||
|
SET courtesyTime=60
|
||||||
|
WHERE id=1;
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`delivery_beforeInsert`
|
||||||
|
BEFORE INSERT ON `delivery`
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
IF (NEW.longitude IS NOT NULL AND NEW.latitude IS NOT NULL AND NEW.ticketFK IS NOT NULL)
|
||||||
|
THEN
|
||||||
|
UPDATE address
|
||||||
|
SET longitude = NEW.longitude,
|
||||||
|
latitude = NEW.latitude
|
||||||
|
WHERE id IN (
|
||||||
|
SELECT addressFK
|
||||||
|
FROM ticket
|
||||||
|
WHERE id = NEW.ticketFk
|
||||||
|
);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`delivery_beforeUpdate`
|
||||||
|
BEFORE UPDATE ON `delivery`
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
IF (NEW.longitude IS NOT NULL AND NEW.latitude IS NOT NULL AND NEW.ticketFK IS NOT NULL)
|
||||||
|
THEN
|
||||||
|
UPDATE address
|
||||||
|
SET longitude = NEW.longitude,
|
||||||
|
latitude = NEW.latitude
|
||||||
|
WHERE id IN (
|
||||||
|
SELECT addressFK
|
||||||
|
FROM ticket
|
||||||
|
WHERE id = NEW.ticketFk
|
||||||
|
);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE `vn`.`address` MODIFY COLUMN longitude decimal(11,7) DEFAULT NULL NULL COMMENT 'Indica la última longitud proporcionada por tabla delivery';
|
||||||
|
ALTER TABLE `vn`.`address` MODIFY COLUMN latitude decimal(11,7) DEFAULT NULL NULL COMMENT 'Indica la última latitud proporcionada por tabla delivery';
|
|
@ -0,0 +1,6 @@
|
||||||
|
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId) VALUES
|
||||||
|
('VnRole','*','READ','ALLOW','ROLE','employee'),
|
||||||
|
('VnRole','*','WRITE','ALLOW','ROLE','it');
|
||||||
|
|
||||||
|
DELETE FROM`salix`.`ACL` WHERE model='Role';
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
-- Definición de la tabla mailAliasACL
|
||||||
|
|
||||||
|
CREATE OR REPLACE TABLE `account`.`mailAliasAcl` (
|
||||||
|
`mailAliasFk` int(10) unsigned NOT NULL,
|
||||||
|
`roleFk` int(10) unsigned NOT NULL,
|
||||||
|
FOREIGN KEY (`mailAliasFk`) REFERENCES `account`.`mailAlias` (`id`),
|
||||||
|
FOREIGN KEY (`roleFk`) REFERENCES `account`.`role` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `vn`.`ticketTracking` CHANGE `workerFk` `userFk` int(10) unsigned DEFAULT NULL NULL;
|
|
@ -0,0 +1,4 @@
|
||||||
|
RENAME TABLE `vn`.`clientCreditLimit` TO `vn`.`roleCreditLimit`;
|
||||||
|
ALTER TABLE `vn`.`roleCreditLimit` DROP FOREIGN KEY `clientCreditLimit_FK`;
|
||||||
|
ALTER TABLE `vn`.`roleCreditLimit` ADD CONSTRAINT `roleCreditLimit_FK` FOREIGN KEY (`roleFk`) REFERENCES `account`.`role`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
ALTER TABLE `vn`.`invoiceCorrection` DROP FOREIGN KEY `cplusInvoiceTyoeFk`;
|
||||||
|
ALTER TABLE `vn`.`invoiceCorrection` DROP FOREIGN KEY `invoiceCorrectionType_Fk33`;
|
||||||
|
ALTER TABLE `vn`.`invoiceCorrection` DROP FOREIGN KEY `invoiceCorrection_ibfk_1`;
|
||||||
|
|
||||||
|
ALTER TABLE `vn`.`invoiceCorrection` ADD CONSTRAINT `siiTypeInvoiceOut_FK` FOREIGN KEY (`siiTypeInvoiceOutFk`) REFERENCES `vn`.`siiTypeInvoiceOut`(id) ON UPDATE CASCADE;
|
||||||
|
ALTER TABLE `vn`.`invoiceCorrection` ADD CONSTRAINT `invoiceCorrectionType_FK` FOREIGN KEY (`invoiceCorrectionTypeFk`) REFERENCES `vn`.`invoiceCorrectionType`(id) ON UPDATE CASCADE;
|
||||||
|
ALTER TABLE `vn`.`invoiceCorrection` ADD CONSTRAINT `cplusRectificationType_FK` FOREIGN KEY (`cplusRectificationTypeFk`) REFERENCES `vn`.`cplusRectificationType`(id) ON UPDATE CASCADE;
|
|
@ -0,0 +1,33 @@
|
||||||
|
DELIMITER $$
|
||||||
|
$$
|
||||||
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`getTaxBases`()
|
||||||
|
BEGIN
|
||||||
|
/**
|
||||||
|
* Calcula y devuelve en número de bases imponibles postivas y negativas
|
||||||
|
* Requiere la tabla temporal tmp.ticketToInvoice(id)
|
||||||
|
*
|
||||||
|
* returns tmp.taxBases
|
||||||
|
*/
|
||||||
|
|
||||||
|
CREATE OR REPLACE TEMPORARY TABLE tmp.ticket
|
||||||
|
(KEY (ticketFk))
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT id ticketFk
|
||||||
|
FROM tmp.ticketToInvoice;
|
||||||
|
|
||||||
|
CALL ticket_getTax(NULL);
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE IF EXISTS tmp.taxBases;
|
||||||
|
CREATE TEMPORARY TABLE tmp.taxBases
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT
|
||||||
|
SUM(taxableBase > 0) as positive,
|
||||||
|
SUM(taxableBase < 0) as negative
|
||||||
|
FROM(
|
||||||
|
SELECT SUM(taxableBase) taxableBase
|
||||||
|
FROM tmp.ticketTax
|
||||||
|
GROUP BY pgcFk
|
||||||
|
) t;
|
||||||
|
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -0,0 +1 @@
|
||||||
|
DELETE FROM `account`.`signInLog` where owner <> FALSE
|
|
@ -0,0 +1,30 @@
|
||||||
|
DELIMITER $$
|
||||||
|
$$
|
||||||
|
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`hasAnyPositiveBase`() RETURNS tinyint(1)
|
||||||
|
DETERMINISTIC
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcula si existe alguna base imponible positiva
|
||||||
|
* Requiere la tabla temporal tmp.ticketToInvoice(id) para getTaxBases()
|
||||||
|
*
|
||||||
|
* returns BOOLEAN
|
||||||
|
*/
|
||||||
|
|
||||||
|
DECLARE hasAnyPositiveBase BOOLEAN;
|
||||||
|
|
||||||
|
CALL getTaxBases();
|
||||||
|
|
||||||
|
SELECT positive INTO hasAnyPositiveBase
|
||||||
|
FROM tmp.taxBases
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE
|
||||||
|
tmp.ticketTax,
|
||||||
|
tmp.ticket,
|
||||||
|
tmp.taxBases;
|
||||||
|
|
||||||
|
RETURN hasAnyPositiveBase;
|
||||||
|
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,32 @@
|
||||||
|
DELIMITER $$
|
||||||
|
$$
|
||||||
|
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`hasAnyNegativeBase`() RETURNS tinyint(1)
|
||||||
|
DETERMINISTIC
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calcula si existe alguna base imponible negativa
|
||||||
|
* Requiere la tabla temporal tmp.ticketToInvoice(id) para getTaxBases()
|
||||||
|
*
|
||||||
|
* returns BOOLEAN
|
||||||
|
*/
|
||||||
|
|
||||||
|
DECLARE hasAnyNegativeBase BOOLEAN;
|
||||||
|
|
||||||
|
CALL getTaxBases();
|
||||||
|
|
||||||
|
SELECT negative INTO hasAnyNegativeBase
|
||||||
|
FROM tmp.taxBases
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE
|
||||||
|
tmp.ticketTax,
|
||||||
|
tmp.ticket,
|
||||||
|
tmp.taxBases;
|
||||||
|
|
||||||
|
RETURN hasAnyNegativeBase;
|
||||||
|
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
CREATE SCHEMA IF NOT EXISTS `vn2008`;
|
||||||
|
USE `vn`;
|
||||||
|
|
||||||
|
CREATE OR REPLACE DEFINER=`root`@`localhost`
|
||||||
|
SQL SECURITY DEFINER
|
||||||
|
VIEW `ticketState`
|
||||||
|
AS SELECT `tt`.`created` AS `updated`,
|
||||||
|
`tt`.`stateFk` AS `stateFk`,
|
||||||
|
`tt`.`userFk` AS `workerFk`,
|
||||||
|
`tls`.`ticketFk` AS `ticketFk`,
|
||||||
|
`s`.`id` AS `state`,
|
||||||
|
`s`.`order` AS `productionOrder`,
|
||||||
|
`s`.`alertLevel` AS `alertLevel`,
|
||||||
|
`s`.`code` AS `code`,
|
||||||
|
`tls`.`ticketFk` AS `ticket`,
|
||||||
|
`tt`.`userFk` AS `worker`,
|
||||||
|
`s`.`isPreviousPreparable` AS `isPreviousPreparable`,
|
||||||
|
`s`.`isPicked` AS `isPicked`
|
||||||
|
FROM (
|
||||||
|
(
|
||||||
|
`ticketLastState` `tls`
|
||||||
|
JOIN `ticketTracking` `tt` ON(`tt`.`id` = `tls`.`ticketTrackingFk`)
|
||||||
|
)
|
||||||
|
JOIN `state` `s` ON(`s`.`id` = `tt`.`stateFk`)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OR REPLACE DEFINER=`root`@`localhost`
|
||||||
|
SQL SECURITY DEFINER
|
||||||
|
VIEW `vn2008`.`v_inter`
|
||||||
|
AS SELECT `tt`.`id` AS `inter_id`,
|
||||||
|
`tt`.`stateFk` AS `state_id`,
|
||||||
|
`tt`.`notes` AS `nota`,
|
||||||
|
`tt`.`created` AS `odbc_date`,
|
||||||
|
`tt`.`ticketFk` AS `Id_Ticket`,
|
||||||
|
`tt`.`userFk` AS `Id_Trabajador`,
|
||||||
|
`tt`.`supervisorFk` AS `Id_supervisor`
|
||||||
|
FROM `vn`.`ticketTracking` `tt`;
|
||||||
|
|
||||||
|
CREATE OR REPLACE DEFINER=`root`@`localhost`
|
||||||
|
SQL SECURITY DEFINER
|
||||||
|
VIEW `ticketStateToday`
|
||||||
|
AS SELECT
|
||||||
|
`ts`.`ticket` AS `ticket`,
|
||||||
|
`ts`.`state` AS `state`,
|
||||||
|
`ts`.`productionOrder` AS `productionOrder`,
|
||||||
|
`ts`.`alertLevel` AS `alertLevel`,
|
||||||
|
`ts`.`worker` AS `worker`,
|
||||||
|
`ts`.`code` AS `code`,
|
||||||
|
`ts`.`updated` AS `updated`,
|
||||||
|
`ts`.`isPicked` AS `isPicked`
|
||||||
|
FROM
|
||||||
|
(`ticketState` `ts`
|
||||||
|
JOIN `ticket` `t` ON
|
||||||
|
(`t`.`id` = `ts`.`ticket`))
|
||||||
|
WHERE
|
||||||
|
`t`.`shipped` BETWEEN `util`.`VN_CURDATE`() AND `MIDNIGHT`(`util`.`VN_CURDATE`());
|
|
@ -0,0 +1,10 @@
|
||||||
|
-- vn.docuwareTablet definition
|
||||||
|
|
||||||
|
CREATE TABLE `vn`.`docuwareTablet` (
|
||||||
|
`tablet` varchar(100) NOT NULL PRIMARY KEY,
|
||||||
|
`description` varchar(255) DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `vn`.`userConfig`
|
||||||
|
ADD COLUMN tabletFk varchar(100) DEFAULT NULL,
|
||||||
|
ADD FOREIGN KEY (tabletFk) REFERENCES `vn`.`docuwareTablet`(tablet);
|
|
@ -0,0 +1,9 @@
|
||||||
|
ALTER TABLE `vn`.`clientSms` ADD `ticketFk` int(11) NULL;
|
||||||
|
ALTER TABLE `vn`.`clientSms` ADD CONSTRAINT `clientSms_FK_2` FOREIGN KEY (`ticketFk`) REFERENCES `vn`.`ticket`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
INSERT INTO`vn`.`clientSms` (`clientFk`, `smsFk`, `ticketFk`)
|
||||||
|
SELECT `t`.`clientFk`, `s`.`smsFk`, `s`.`ticketFk`
|
||||||
|
FROM `vn`.`clientSms` `s`
|
||||||
|
JOIN `vn`.`ticket` `t` ON `t`.`id` = `s`.`ticketFk`;
|
||||||
|
|
||||||
|
RENAME TABLE `vn`.`ticketSms` TO `vn`.`ticketSms__`;
|
|
@ -0,0 +1,17 @@
|
||||||
|
DELETE FROM `salix`.`ACL`
|
||||||
|
WHERE model = 'VnUser'
|
||||||
|
AND property = 'renewToken';
|
||||||
|
|
||||||
|
INSERT INTO `account`.`role` (name, description)
|
||||||
|
VALUES ('timeControl','Tablet para fichar');
|
||||||
|
|
||||||
|
INSERT INTO `account`.`roleInherit` (role, inheritsFrom)
|
||||||
|
VALUES (127, 11);
|
||||||
|
|
||||||
|
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||||
|
VALUES
|
||||||
|
('WorkerTimeControl', 'login', 'READ', 'ALLOW', 'ROLE', 'timeControl'),
|
||||||
|
('WorkerTimeControl', 'getClockIn', 'READ', 'ALLOW', 'ROLE', 'timeControl'),
|
||||||
|
('WorkerTimeControl', 'clockIn', 'WRITE', 'ALLOW', 'ROLE', 'timeControl');
|
||||||
|
|
||||||
|
CALL `account`.`role_sync`();
|
|
@ -5,10 +5,6 @@ SET DEFAULT ROLE 'salix' FOR 'root'@'%';
|
||||||
CREATE SCHEMA IF NOT EXISTS `vn2008`;
|
CREATE SCHEMA IF NOT EXISTS `vn2008`;
|
||||||
CREATE SCHEMA IF NOT EXISTS `tmp`;
|
CREATE SCHEMA IF NOT EXISTS `tmp`;
|
||||||
|
|
||||||
CREATE ROLE 'salix';
|
|
||||||
GRANT 'salix' TO 'root'@'%';
|
|
||||||
SET DEFAULT ROLE 'salix' FOR 'root'@'%';
|
|
||||||
|
|
||||||
UPDATE `util`.`config`
|
UPDATE `util`.`config`
|
||||||
SET `environment`= 'development';
|
SET `environment`= 'development';
|
||||||
|
|
||||||
|
@ -497,7 +493,7 @@ INSERT INTO `vn`.`clientCredit`(`clientFk`, `workerFk`, `amount`, `created`)
|
||||||
(1104, 9, 90 , util.VN_CURDATE()),
|
(1104, 9, 90 , util.VN_CURDATE()),
|
||||||
(1105, 9, 90 , util.VN_CURDATE());
|
(1105, 9, 90 , util.VN_CURDATE());
|
||||||
|
|
||||||
INSERT INTO `vn`.`clientCreditLimit`(`id`, `maxAmount`, `roleFk`)
|
INSERT INTO `vn`.`roleCreditLimit`(`id`, `maxAmount`, `roleFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 9999999, 20),
|
(1, 9999999, 20),
|
||||||
(2, 10000, 21),
|
(2, 10000, 21),
|
||||||
|
@ -610,6 +606,7 @@ INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaF
|
||||||
('T', 'Española rapida', 1, 'NATIONAL', 0, 'quick'),
|
('T', 'Española rapida', 1, 'NATIONAL', 0, 'quick'),
|
||||||
('V', 'Intracomunitaria global', 0, 'CEE', 1, 'global'),
|
('V', 'Intracomunitaria global', 0, 'CEE', 1, 'global'),
|
||||||
('M', 'Múltiple nacional', 1, 'NATIONAL', 0, 'quick'),
|
('M', 'Múltiple nacional', 1, 'NATIONAL', 0, 'quick'),
|
||||||
|
('R', 'Rectificativa', 1, 'NATIONAL', 0, NULL),
|
||||||
('E', 'Exportación rápida', 0, 'WORLD', 0, 'quick');
|
('E', 'Exportación rápida', 0, 'WORLD', 0, 'quick');
|
||||||
|
|
||||||
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`)
|
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`)
|
||||||
|
@ -617,7 +614,7 @@ INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `cr
|
||||||
(1, 'T', 1026.24, util.VN_CURDATE(), 1101, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
|
(1, 'T', 1026.24, util.VN_CURDATE(), 1101, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
|
||||||
(2, 'T', 121.36, util.VN_CURDATE(), 1102, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
|
(2, 'T', 121.36, util.VN_CURDATE(), 1102, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
|
||||||
(3, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
|
(3, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
|
||||||
(4, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
|
(4, 'T', 8.88, util.VN_CURDATE(), 1104, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
|
||||||
(5, 'A', 8.88, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 0);
|
(5, 'A', 8.88, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 0);
|
||||||
|
|
||||||
UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1;
|
UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1;
|
||||||
|
@ -723,7 +720,7 @@ INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agen
|
||||||
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `zonePrice`, `zoneBonus`, `created`, `weight`)
|
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `zonePrice`, `zoneBonus`, `created`, `weight`)
|
||||||
VALUES
|
VALUES
|
||||||
(1 , 3, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 121, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1),
|
(1 , 3, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 121, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1),
|
||||||
(2 , 1, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2),
|
(2 , 1, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 1, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2),
|
||||||
(3 , 1, 7, 1, 6, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 3, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), NULL),
|
(3 , 1, 7, 1, 6, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 3, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), NULL),
|
||||||
(4 , 3, 2, 1, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 9, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), NULL),
|
(4 , 3, 2, 1, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 9, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), NULL),
|
||||||
(5 , 3, 3, 3, 3, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 10, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), NULL),
|
(5 , 3, 3, 3, 3, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 10, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), NULL),
|
||||||
|
@ -775,7 +772,7 @@ INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `des
|
||||||
-- FIX for state hours on local, inter_afterInsert
|
-- FIX for state hours on local, inter_afterInsert
|
||||||
-- UPDATE vncontrol.inter SET odbc_date = DATE_ADD(util.VN_CURDATE(), INTERVAL -10 SECOND);
|
-- UPDATE vncontrol.inter SET odbc_date = DATE_ADD(util.VN_CURDATE(), INTERVAL -10 SECOND);
|
||||||
|
|
||||||
INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `workerFk`, `created`)
|
INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `userFk`, `created`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 16, 5 , DATE_ADD(util.VN_NOW(), INTERVAL -1 MONTH)),
|
(1, 16, 5 , DATE_ADD(util.VN_NOW(), INTERVAL -1 MONTH)),
|
||||||
(2, 16, 5 , DATE_ADD(util.VN_NOW(), INTERVAL -1 MONTH)),
|
(2, 16, 5 , DATE_ADD(util.VN_NOW(), INTERVAL -1 MONTH)),
|
||||||
|
@ -819,6 +816,7 @@ INSERT INTO `vn`.`config`(`id`, `mdbServer`, `fakeEmail`, `defaultersMaxAmount`,
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'beta-server', 'nightmare@mydomain.com', '200', DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH));
|
(1, 'beta-server', 'nightmare@mydomain.com', '200', DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH));
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`greugeType`(`id`, `name`, `code`)
|
INSERT INTO `vn`.`greugeType`(`id`, `name`, `code`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'Diff', 'diff'),
|
(1, 'Diff', 'diff'),
|
||||||
|
@ -2970,9 +2968,9 @@ INSERT INTO `vn`.`wagonTypeTray` (`id`, `typeFk`, `height`, `colorFk`)
|
||||||
(2, 1, 50, 2),
|
(2, 1, 50, 2),
|
||||||
(3, 1, 0, 3);
|
(3, 1, 0, 3);
|
||||||
|
|
||||||
INSERT INTO `salix`.`accessTokenConfig` (`id`, `renewPeriod`, `renewInterval`)
|
INSERT INTO `salix`.`accessTokenConfig` (`id`, `renewPeriod`, `courtesyTime`, `renewInterval`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 21600, 300);
|
(1, 21600, 60, 300);
|
||||||
|
|
||||||
INSERT INTO `vn`.`travelConfig` (`id`, `warehouseInFk`, `warehouseOutFk`, `agencyFk`, `companyFk`)
|
INSERT INTO `vn`.`travelConfig` (`id`, `warehouseInFk`, `warehouseOutFk`, `agencyFk`, `companyFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -3012,3 +3010,28 @@ INSERT INTO `vn`.`invoiceCorrectionType` (`id`, `description`)
|
||||||
(1, 'Error in VAT calculation'),
|
(1, 'Error in VAT calculation'),
|
||||||
(2, 'Error in sales details'),
|
(2, 'Error in sales details'),
|
||||||
(3, 'Error in customer data');
|
(3, 'Error in customer data');
|
||||||
|
|
||||||
|
INSERT INTO `account`.`mailAliasAcl` (`mailAliasFk`, `roleFk`)
|
||||||
|
VALUES
|
||||||
|
(1, 1),
|
||||||
|
(2, 9),
|
||||||
|
(3, 15);
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`docuwareTablet` (`tablet`,`description`)
|
||||||
|
VALUES
|
||||||
|
('Tablet1','Jarvis tablet'),
|
||||||
|
('Tablet2','Avengers tablet');
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`sms` (`id`, `senderFk`, `sender`, `destination`, `message`, `statusCode`, `status`, `created`)
|
||||||
|
VALUES (1, 66, '111111111', '0001111111111', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'OK', util.VN_CURDATE()),
|
||||||
|
(2, 66, '222222222', '0002222222222', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'PENDING', util.VN_CURDATE()),
|
||||||
|
(3, 66, '333333333', '0003333333333', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'ERROR', util.VN_CURDATE()),
|
||||||
|
(4, 66, '444444444', '0004444444444', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 0, 'OK', util.VN_CURDATE());
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`clientSms` (`id`, `clientFk`, `smsFk`, `ticketFk`)
|
||||||
|
VALUES(1, 1103, 1, NULL),
|
||||||
|
(2, 1103, 2, NULL),
|
||||||
|
(3, 1103, 3, 32),
|
||||||
|
(4, 1103, 4, 32),
|
||||||
|
(13, 1101, 1, NULL),
|
||||||
|
(14, 1101, 4, 27);
|
|
@ -26391,6 +26391,7 @@ CREATE TABLE `cplusCorrectingType` (
|
||||||
) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `cplusRectificationType`
|
-- Table structure for table `cplusRectificationType`
|
||||||
--
|
--
|
||||||
|
|
|
@ -1,123 +0,0 @@
|
||||||
const app = require('vn-loopback/server/server');
|
|
||||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
|
||||||
|
|
||||||
// 2277 solucionar problema al testear procedimiento con start transaction / rollback
|
|
||||||
xdescribe('ticket_componentMakeUpdate()', () => {
|
|
||||||
it('should recalculate the ticket components without make modifications', async() => {
|
|
||||||
let stmts = [];
|
|
||||||
let stmt;
|
|
||||||
|
|
||||||
let params = {
|
|
||||||
ticketId: 11,
|
|
||||||
clientId: 1102,
|
|
||||||
agencyModeId: 2,
|
|
||||||
addressId: 122,
|
|
||||||
zoneId: 3,
|
|
||||||
warehouseId: 1,
|
|
||||||
companyId: 442,
|
|
||||||
isDeleted: 0,
|
|
||||||
hasToBeUnrouted: 0,
|
|
||||||
componentOption: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
stmts.push('START TRANSACTION');
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL('SELECT * FROM vn.ticket WHERE id = ?', [
|
|
||||||
params.ticketId
|
|
||||||
]);
|
|
||||||
stmts.push(stmt);
|
|
||||||
|
|
||||||
let originalTicketIndex = stmts.push(stmt) - 1;
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL('CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, DATE_ADD(CURDATE(), INTERVAL +1 DAY), DATE_ADD(CURDATE(), INTERVAL +1 DAY), ?, ?, ?)', [
|
|
||||||
params.ticketId,
|
|
||||||
params.clientId,
|
|
||||||
params.agencyModeId,
|
|
||||||
params.addressId,
|
|
||||||
params.zoneId,
|
|
||||||
params.warehouseId,
|
|
||||||
params.companyId,
|
|
||||||
params.isDeleted,
|
|
||||||
params.hasToBeUnrouted,
|
|
||||||
params.componentOption
|
|
||||||
]);
|
|
||||||
stmts.push(stmt);
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL('SELECT * FROM vn.ticket WHERE id = ?', [
|
|
||||||
params.ticketId
|
|
||||||
]);
|
|
||||||
stmts.push(stmt);
|
|
||||||
|
|
||||||
let updatedTicketIndex = stmts.push(stmt) - 1;
|
|
||||||
|
|
||||||
stmts.push('ROLLBACK');
|
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
|
||||||
let result = await app.models.Ticket.rawStmt(sql);
|
|
||||||
|
|
||||||
let originalTicketData = result[originalTicketIndex];
|
|
||||||
let updatedTicketData = result[updatedTicketIndex];
|
|
||||||
|
|
||||||
expect(originalTicketData[0].isDeleted).toEqual(updatedTicketData[0].isDeleted);
|
|
||||||
expect(originalTicketData[0].routeFk).toEqual(updatedTicketData[0].routeFk);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should delete and unroute a ticket and recalculate the components', async() => {
|
|
||||||
let stmts = [];
|
|
||||||
let stmt;
|
|
||||||
|
|
||||||
let params = {
|
|
||||||
ticketId: 11,
|
|
||||||
clientId: 1102,
|
|
||||||
agencyModeId: 2,
|
|
||||||
addressId: 122,
|
|
||||||
zoneId: 3,
|
|
||||||
warehouseId: 1,
|
|
||||||
companyId: 442,
|
|
||||||
isDeleted: 1,
|
|
||||||
hasToBeUnrouted: 1,
|
|
||||||
componentOption: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
stmts.push('START TRANSACTION');
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL('SELECT * FROM vn.ticket WHERE id = ?', [
|
|
||||||
params.ticketId
|
|
||||||
]);
|
|
||||||
stmts.push(stmt);
|
|
||||||
|
|
||||||
let originalTicketIndex = stmts.push(stmt) - 1;
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL('CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, DATE_ADD(CURDATE(), INTERVAL +1 DAY), DATE_ADD(CURDATE(), INTERVAL +1 DAY), ?, ?, ?)', [
|
|
||||||
params.ticketId,
|
|
||||||
params.clientId,
|
|
||||||
params.agencyModeId,
|
|
||||||
params.addressId,
|
|
||||||
params.zoneId,
|
|
||||||
params.warehouseId,
|
|
||||||
params.companyId,
|
|
||||||
params.isDeleted,
|
|
||||||
params.hasToBeUnrouted,
|
|
||||||
params.componentOption
|
|
||||||
]);
|
|
||||||
stmts.push(stmt);
|
|
||||||
|
|
||||||
stmt = new ParameterizedSQL('SELECT * FROM vn.ticket WHERE id = ?', [
|
|
||||||
params.ticketId
|
|
||||||
]);
|
|
||||||
stmts.push(stmt);
|
|
||||||
|
|
||||||
let updatedTicketIndex = stmts.push(stmt) - 1;
|
|
||||||
|
|
||||||
stmts.push('ROLLBACK');
|
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
|
||||||
let result = await app.models.Ticket.rawStmt(sql);
|
|
||||||
|
|
||||||
let originalTicketData = result[originalTicketIndex];
|
|
||||||
let updatedTicketData = result[updatedTicketIndex];
|
|
||||||
|
|
||||||
expect(originalTicketData[0].isDeleted).not.toEqual(updatedTicketData[0].isDeleted);
|
|
||||||
expect(originalTicketData[0].routeFk).not.toEqual(updatedTicketData[0].routeFk);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -56,63 +56,6 @@ describe('Worker time control path', () => {
|
||||||
expect(result).toContain(month);
|
expect(result).toContain(month);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should return error when insert 'out' of first entry`, async() => {
|
|
||||||
pending('https://redmine.verdnatura.es/issues/4707');
|
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
|
||||||
await page.respondToDialog('accept');
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should insert 'in' monday`, async() => {
|
|
||||||
pending('https://redmine.verdnatura.es/issues/4707');
|
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
|
|
||||||
await page.respondToDialog('accept');
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual(eightAm);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should insert 'out' monday`, async() => {
|
|
||||||
pending('https://redmine.verdnatura.es/issues/4707');
|
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, fourPm);
|
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
|
||||||
await page.respondToDialog('accept');
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerTimeControl.secondEntryOfMonday, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual(fourPm);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should check Hank Pym worked 8:20 hours`, async() => {
|
|
||||||
pending('https://redmine.verdnatura.es/issues/4707');
|
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '08:20 h.');
|
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '08:20 h.');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove first entry of monday', async() => {
|
|
||||||
pending('https://redmine.verdnatura.es/issues/4707');
|
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.firstEntryOfMonday, eightAm);
|
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.secondEntryOfMonday, fourPm);
|
|
||||||
await page.waitToClick(selectors.workerTimeControl.firstEntryOfMondayDelete);
|
|
||||||
await page.respondToDialog('accept');
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Entry removed');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should be the 'out' the first entry of monday`, async() => {
|
|
||||||
pending('https://redmine.verdnatura.es/issues/4707');
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual(fourPm);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should change week of month', async() => {
|
it('should change week of month', async() => {
|
||||||
await page.click(selectors.workerTimeControl.thrirdWeekDay);
|
await page.click(selectors.workerTimeControl.thrirdWeekDay);
|
||||||
const result = await page.getProperty(selectors.workerTimeControl.mondayWorkedHours, 'innerText');
|
const result = await page.getProperty(selectors.workerTimeControl.mondayWorkedHours, 'innerText');
|
||||||
|
|
|
@ -188,17 +188,6 @@ describe('Ticket Edit sale path', () => {
|
||||||
expect(result).toContain('22.50');
|
expect(result).toContain('22.50');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check in the history that logs has been added', async() => {
|
|
||||||
pending('https://redmine.verdnatura.es/issues/5455');
|
|
||||||
await page.reload({waitUntil: ['networkidle0', 'domcontentloaded']});
|
|
||||||
await page.waitToClick(selectors.ticketSales.firstSaleHistoryButton);
|
|
||||||
await page.waitForSelector(selectors.ticketSales.firstSaleHistory);
|
|
||||||
const result = await page.countElement(selectors.ticketSales.firstSaleHistory);
|
|
||||||
|
|
||||||
expect(result).toBeGreaterThan(0);
|
|
||||||
await page.waitToClick(selectors.ticketSales.closeHistory);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should recalculate price of sales', async() => {
|
it('should recalculate price of sales', async() => {
|
||||||
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
|
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
|
||||||
await page.waitToClick(selectors.ticketSales.secondSaleCheckbox);
|
await page.waitToClick(selectors.ticketSales.secondSaleCheckbox);
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
|
||||||
|
|
||||||
// #2221 Local MySQL8 crashes when rest method Items/getBalance is called
|
|
||||||
xdescribe('Ticket diary path', () => {
|
|
||||||
let page;
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
|
||||||
page = (await getBrowser()).page;
|
|
||||||
await page.loginAndModule('employee', 'ticket');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async() => {
|
|
||||||
await page.browser().close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should navigate to item diary from ticket sale and check the lines`, async() => {
|
|
||||||
await page.accessToSearchResult('1');
|
|
||||||
await page.waitToClick(selectors.ticketSummary.firstSaleItemId);
|
|
||||||
await page.waitToClick(selectors.ticketSummary.popoverDiaryButton);
|
|
||||||
await page.waitForState('item.card.diary');
|
|
||||||
|
|
||||||
const secondIdClass = await page.getClassName(selectors.itemDiary.secondTicketId);
|
|
||||||
const fourthBalanceClass = await page.getClassName(selectors.itemDiary.fourthBalance);
|
|
||||||
const firstBalanceClass = await page.getClassName(selectors.itemDiary.firstBalance);
|
|
||||||
|
|
||||||
expect(secondIdClass).toContain('message');
|
|
||||||
expect(fourthBalanceClass).toContain('message');
|
|
||||||
expect(firstBalanceClass).toContain('balance');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -35,7 +35,7 @@ describe('Ticket index payout path', () => {
|
||||||
await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton);
|
await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton);
|
||||||
await page.write(selectors.ticketsIndex.advancedSearchClient, '1101');
|
await page.write(selectors.ticketsIndex.advancedSearchClient, '1101');
|
||||||
await page.keyboard.press('Enter');
|
await page.keyboard.press('Enter');
|
||||||
await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 9);
|
await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 10);
|
||||||
await page.waitToClick(selectors.ticketsIndex.firstTicketCheckbox);
|
await page.waitToClick(selectors.ticketsIndex.firstTicketCheckbox);
|
||||||
await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox);
|
await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox);
|
||||||
|
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
|
||||||
import getBrowser from '../../helpers/puppeteer.js';
|
|
||||||
|
|
||||||
// #1528 e2e claim/detail
|
|
||||||
xdescribe('Claim detail', () => {
|
|
||||||
let browser;
|
|
||||||
let page;
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
|
||||||
browser = await getBrowser();
|
|
||||||
page = browser.page;
|
|
||||||
await page.loginAndModule('salesPerson', 'claim');
|
|
||||||
await page.accessToSearchResult('1');
|
|
||||||
await page.accessToSection('claim.card.detail');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async() => {
|
|
||||||
await browser.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add the first claimable item from ticket to the claim', async() => {
|
|
||||||
await page.waitToClick(selectors.claimDetail.addItemButton);
|
|
||||||
await page.waitToClick(selectors.claimDetail.firstClaimableSaleFromTicket);
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should confirm the claim contains now two items', async() => {
|
|
||||||
const result = await page.countElement(selectors.claimDetail.claimDetailLine);
|
|
||||||
|
|
||||||
expect(result).toEqual(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should edit de first item claimed quantity', async() => {
|
|
||||||
await page.clearInput(selectors.claimDetail.firstItemQuantityInput); // selector deleted, find new upon fixes
|
|
||||||
await page.write(selectors.claimDetail.firstItemQuantityInput, '4'); // selector deleted, find new upon fixes
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should confirm the first item quantity, and the claimed total were correctly edited', async() => {
|
|
||||||
const claimedQuantity = page
|
|
||||||
.waitToGetProperty(selectors.claimDetail.firstItemQuantityInput, 'value'); // selector deleted, find new upon fixes
|
|
||||||
|
|
||||||
const totalClaimed = page
|
|
||||||
.waitToGetProperty(selectors.claimDetail.totalClaimed, 'innerText');
|
|
||||||
|
|
||||||
expect(claimedQuantity).toEqual('4');
|
|
||||||
expect(totalClaimed).toContain('€47.62');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should login as salesAssistant and navigate to the claim.detail section', async() => {
|
|
||||||
await page.loginAndModule('salesAssistant', 'claim');
|
|
||||||
await page.accessToSearchResult('1');
|
|
||||||
await page.accessToSection('claim.card.detail');
|
|
||||||
let url = await page.expectURL('/detail'); // replace with waitForState
|
|
||||||
|
|
||||||
expect(url).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should edit de second item claimed discount', async() => {
|
|
||||||
await page.waitToClick(selectors.claimDetail.secondItemDiscount);
|
|
||||||
await page.write(selectors.claimDetail.discount, '100');
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the mana is the expected one', async() => {
|
|
||||||
await page.waitToClick(selectors.claimDetail.secondItemDiscount);
|
|
||||||
const result = await page.waitToGetProperty(selectors.claimDetail.discoutPopoverMana, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toContain('MANÁ: €106');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should delete the second item from the claim', async() => {
|
|
||||||
await page.waitToClick(selectors.claimDetail.secondItemDeleteButton);
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should confirm the claim contains now one item', async() => {
|
|
||||||
const result = await page.countElement(selectors.claimDetail.claimDetailLine);
|
|
||||||
|
|
||||||
expect(result).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add the deleted ticket from to the claim', async() => {
|
|
||||||
await page.waitToClick(selectors.claimDetail.addItemButton);
|
|
||||||
await page.waitToClick(selectors.claimDetail.firstClaimableSaleFromTicket);
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should have been redirected to the next section in claims`, async() => {
|
|
||||||
let url = await page.expectURL('development'); // replace with waitForState
|
|
||||||
|
|
||||||
expect(url).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should navigate back to claim.detail to confirm the claim contains now two items', async() => {
|
|
||||||
await page.accessToSection('claim.card.detail');
|
|
||||||
await page.waitForSelector(selectors.claimDetail.claimDetailLine);
|
|
||||||
const result = await page.countElement(selectors.claimDetail.claimDetailLine);
|
|
||||||
|
|
||||||
expect(result).toEqual(2);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -26,7 +26,7 @@ describe('Route create path', () => {
|
||||||
await page.waitToClick(selectors.createRouteView.submitButton);
|
await page.waitToClick(selectors.createRouteView.submitButton);
|
||||||
const message = await page.waitForSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
expect(message.text).toContain('Access denied');
|
expect(message.text).toContain('Access Denied');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ describe('InvoiceOut summary path', () => {
|
||||||
|
|
||||||
it('should contain the tax breakdown', async() => {
|
it('should contain the tax breakdown', async() => {
|
||||||
const firstTax = await page.waitToGetProperty(selectors.invoiceOutSummary.taxOne, 'innerText');
|
const firstTax = await page.waitToGetProperty(selectors.invoiceOutSummary.taxOne, 'innerText');
|
||||||
|
|
||||||
const secondTax = await page.waitToGetProperty(selectors.invoiceOutSummary.taxTwo, 'innerText');
|
const secondTax = await page.waitToGetProperty(selectors.invoiceOutSummary.taxTwo, 'innerText');
|
||||||
|
|
||||||
expect(firstTax).toContain('10%');
|
expect(firstTax).toContain('10%');
|
||||||
|
@ -37,10 +36,9 @@ describe('InvoiceOut summary path', () => {
|
||||||
|
|
||||||
it('should contain the tickets info', async() => {
|
it('should contain the tickets info', async() => {
|
||||||
const firstTicket = await page.waitToGetProperty(selectors.invoiceOutSummary.ticketOne, 'innerText');
|
const firstTicket = await page.waitToGetProperty(selectors.invoiceOutSummary.ticketOne, 'innerText');
|
||||||
|
|
||||||
const secondTicket = await page.waitToGetProperty(selectors.invoiceOutSummary.ticketTwo, 'innerText');
|
const secondTicket = await page.waitToGetProperty(selectors.invoiceOutSummary.ticketTwo, 'innerText');
|
||||||
|
|
||||||
expect(firstTicket).toContain('Bat cave');
|
expect(firstTicket).toContain('Bat cave');
|
||||||
expect(secondTicket).toContain('Stark tower');
|
expect(secondTicket).toContain('Bat cave');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -105,17 +105,4 @@ describe('Travel basic data path', () => {
|
||||||
it(`should check the received checkbox was saved even tho it doesn't make sense`, async() => {
|
it(`should check the received checkbox was saved even tho it doesn't make sense`, async() => {
|
||||||
await page.waitForClassPresent(selectors.travelBasicData.received, 'checked');
|
await page.waitForClassPresent(selectors.travelBasicData.received, 'checked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should navigate to the travel logs', async() => {
|
|
||||||
pending('https://redmine.verdnatura.es/issues/5455');
|
|
||||||
await page.accessToSection('travel.card.log');
|
|
||||||
await page.waitForState('travel.card.log');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the 1st log contains details from the changes made', async() => {
|
|
||||||
pending('https://redmine.verdnatura.es/issues/5455');
|
|
||||||
const result = await page.waitToGetProperty(selectors.travelLog.firstLogFirstTD, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toContain('new reference!');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,18 +33,6 @@ describe('Component vnTreeview', () => {
|
||||||
$element.remove();
|
$element.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
// See how to test DOM element in Jest
|
|
||||||
xdescribe('undrop()', () => {
|
|
||||||
it(`should reset all drop events and properties`, () => {
|
|
||||||
controller.dropping = angular.element(`<vn-treeview-child class="dropping"></vn-treeview-child>`);
|
|
||||||
jest.spyOn(controller.dropping.classList, 'remove');
|
|
||||||
|
|
||||||
controller.undrop();
|
|
||||||
|
|
||||||
expect(controller.dropping).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('dragOver()', () => {
|
describe('dragOver()', () => {
|
||||||
it(`should set the dragClientY property`, () => {
|
it(`should set the dragClientY property`, () => {
|
||||||
const event = new Event('dragover');
|
const event = new Event('dragover');
|
||||||
|
|
|
@ -23,7 +23,6 @@ export function directive($translate, $window) {
|
||||||
let rule = $attrs.rule.split('.');
|
let rule = $attrs.rule.split('.');
|
||||||
let modelName = rule.shift();
|
let modelName = rule.shift();
|
||||||
let fieldName = rule.shift();
|
let fieldName = rule.shift();
|
||||||
|
|
||||||
let split = $attrs.ngModel.split('.');
|
let split = $attrs.ngModel.split('.');
|
||||||
if (!fieldName) fieldName = split.pop() || null;
|
if (!fieldName) fieldName = split.pop() || null;
|
||||||
if (!modelName) modelName = firstUpper(split.pop() || '');
|
if (!modelName) modelName = firstUpper(split.pop() || '');
|
||||||
|
|
|
@ -68,3 +68,4 @@ Load more results: Cargar más resultados
|
||||||
Send cau: Enviar cau
|
Send cau: Enviar cau
|
||||||
By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc
|
By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc
|
||||||
ExplainReason: Explique el motivo por el que no deberia aparecer este fallo
|
ExplainReason: Explique el motivo por el que no deberia aparecer este fallo
|
||||||
|
You already have the mailAlias: Ya tienes este alias de correo
|
||||||
|
|
|
@ -3,4 +3,4 @@ Could not contact the server: Could not contact the server, make sure you have a
|
||||||
Please enter your username: Please enter your username
|
Please enter your username: Please enter your username
|
||||||
It seems that the server has fall down: It seems that the server has fall down, wait a few minutes and try again
|
It seems that the server has fall down: It seems that the server has fall down, wait a few minutes and try again
|
||||||
Session has expired: Your session has expired, please login again
|
Session has expired: Your session has expired, please login again
|
||||||
Access denied: Access denied
|
Access Denied: Access Denied
|
|
@ -3,5 +3,5 @@ Could not contact the server: No se ha podido contactar con el servidor, asegura
|
||||||
Please enter your username: Por favor introduce tu nombre de usuario
|
Please enter your username: Por favor introduce tu nombre de usuario
|
||||||
It seems that the server has fall down: Parece que el servidor se ha caído, espera unos minutos e inténtalo de nuevo
|
It seems that the server has fall down: Parece que el servidor se ha caído, espera unos minutos e inténtalo de nuevo
|
||||||
Session has expired: Tu sesión ha expirado, por favor vuelve a iniciar sesión
|
Session has expired: Tu sesión ha expirado, por favor vuelve a iniciar sesión
|
||||||
Access denied: Acción no permitida
|
Access Denied: Acción no permitida
|
||||||
Direction not found: Dirección no encontrada
|
Direction not found: Dirección no encontrada
|
||||||
|
|
|
@ -82,7 +82,7 @@ export default class Token {
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
this.renewPeriod = data.renewPeriod;
|
this.renewPeriod = data.renewPeriod;
|
||||||
this.stopRenewer();
|
this.stopRenewer();
|
||||||
this.inservalId = setInterval(() => this.checkValidity(), data.renewInterval * 1000);
|
this.intervalId = setInterval(() => this.checkValidity(), data.renewInterval * 1000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,17 +103,13 @@ export default class Token {
|
||||||
const token = res.data;
|
const token = res.data;
|
||||||
this.set(token.id, now, token.ttl, this.remember);
|
this.set(token.id, now, token.ttl, this.remember);
|
||||||
})
|
})
|
||||||
.catch(res => {
|
|
||||||
if (res.data?.error?.code !== 'periodNotExceeded')
|
|
||||||
throw res;
|
|
||||||
})
|
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.checking = false;
|
this.checking = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
stopRenewer() {
|
stopRenewer() {
|
||||||
clearInterval(this.inservalId);
|
clearInterval(this.intervalId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token.$inject = ['vnInterceptor', '$http', '$rootScope'];
|
Token.$inject = ['vnInterceptor', '$http', '$rootScope'];
|
||||||
|
|
|
@ -18,7 +18,7 @@ Show summary: Mostrar vista previa
|
||||||
What is new: Novedades de la versión
|
What is new: Novedades de la versión
|
||||||
Settings: Ajustes
|
Settings: Ajustes
|
||||||
There is a new version, click here to reload: Hay una nueva versión, pulse aquí para recargar
|
There is a new version, click here to reload: Hay una nueva versión, pulse aquí para recargar
|
||||||
This ticket is locked.: Este ticket está bloqueado
|
This ticket is locked: Este ticket está bloqueado
|
||||||
|
|
||||||
# Actions
|
# Actions
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ function $exceptionHandler(vnApp, $window, $state, $injector) {
|
||||||
messageT = 'Invalid login';
|
messageT = 'Invalid login';
|
||||||
break;
|
break;
|
||||||
case 403:
|
case 403:
|
||||||
messageT = exception.data?.error?.message || 'Access denied';
|
messageT = exception.data?.error?.message || 'Access Denied';
|
||||||
break;
|
break;
|
||||||
case 502:
|
case 502:
|
||||||
messageT = 'It seems that the server has fall down';
|
messageT = 'It seems that the server has fall down';
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
async function handleObserve(ctx) {
|
||||||
|
ctx.options.httpCtx = LoopBackContext.getCurrentContext();
|
||||||
|
}
|
||||||
|
module.exports = function(Self) {
|
||||||
|
let Mixin = {
|
||||||
|
'before save': handleObserve,
|
||||||
|
'before delete': handleObserve,
|
||||||
|
};
|
||||||
|
for (const [listener, handler] of Object.entries(Mixin))
|
||||||
|
Self.observe(listener, handler);
|
||||||
|
};
|
|
@ -1,15 +0,0 @@
|
||||||
const LoopBackContext = require('loopback-context');
|
|
||||||
|
|
||||||
module.exports = function(Self) {
|
|
||||||
Self.setup = function() {
|
|
||||||
Self.super_.setup.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Self.observe('before save', async function(ctx) {
|
|
||||||
ctx.options.httpCtx = LoopBackContext.getCurrentContext();
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.observe('before delete', async function(ctx) {
|
|
||||||
ctx.options.httpCtx = LoopBackContext.getCurrentContext();
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Loggable",
|
|
||||||
"base": "VnModel",
|
|
||||||
"validateUpsert": true
|
|
||||||
}
|
|
|
@ -45,6 +45,7 @@
|
||||||
"Extension format is invalid": "Extension format is invalid",
|
"Extension format is invalid": "Extension format is invalid",
|
||||||
"NO_ZONE_FOR_THIS_PARAMETERS": "NO_ZONE_FOR_THIS_PARAMETERS",
|
"NO_ZONE_FOR_THIS_PARAMETERS": "NO_ZONE_FOR_THIS_PARAMETERS",
|
||||||
"This client can't be invoiced": "This client can't be invoiced",
|
"This client can't be invoiced": "This client can't be invoiced",
|
||||||
|
"You must provide the correction information to generate a corrective invoice": "You must provide the correction information to generate a corrective invoice",
|
||||||
"The introduced hour already exists": "The introduced hour already exists",
|
"The introduced hour already exists": "The introduced hour already exists",
|
||||||
"Invalid parameters to create a new ticket": "Invalid parameters to create a new ticket",
|
"Invalid parameters to create a new ticket": "Invalid parameters to create a new ticket",
|
||||||
"Concept cannot be blank": "Concept cannot be blank",
|
"Concept cannot be blank": "Concept cannot be blank",
|
||||||
|
@ -178,12 +179,13 @@
|
||||||
"The renew period has not been exceeded": "The renew period has not been exceeded",
|
"The renew period has not been exceeded": "The renew period has not been exceeded",
|
||||||
"You can not use the same password": "You can not use the same password",
|
"You can not use the same password": "You can not use the same password",
|
||||||
"Valid priorities": "Valid priorities: %d",
|
"Valid priorities": "Valid priorities: %d",
|
||||||
"Negative basis of tickets": "Negative basis of tickets: {{ticketsIds}}",
|
"hasAnyNegativeBase": "Negative basis of tickets: {{ticketsIds}}",
|
||||||
|
"hasAnyPositiveBase": "Positive basis of tickets: {{ticketsIds}}",
|
||||||
"This ticket cannot be left empty.": "This ticket cannot be left empty. %s",
|
"This ticket cannot be left empty.": "This ticket cannot be left empty. %s",
|
||||||
"Social name should be uppercase": "Social name should be uppercase",
|
"Social name should be uppercase": "Social name should be uppercase",
|
||||||
"Street should be uppercase": "Street should be uppercase",
|
"Street should be uppercase": "Street should be uppercase",
|
||||||
"You don't have enough privileges.": "You don't have enough privileges.",
|
"You don't have enough privileges.": "You don't have enough privileges.",
|
||||||
"This ticket is locked.": "This ticket is locked.",
|
"This ticket is locked": "This ticket is locked",
|
||||||
"This ticket is not editable.": "This ticket is not editable.",
|
"This ticket is not editable.": "This ticket is not editable.",
|
||||||
"The ticket doesn't exist.": "The ticket doesn't exist.",
|
"The ticket doesn't exist.": "The ticket doesn't exist.",
|
||||||
"The sales do not exists": "The sales do not exists",
|
"The sales do not exists": "The sales do not exists",
|
||||||
|
@ -200,5 +202,6 @@
|
||||||
"Try again": "Try again",
|
"Try again": "Try again",
|
||||||
"keepPrice": "keepPrice",
|
"keepPrice": "keepPrice",
|
||||||
"Cannot past travels with entries": "Cannot past travels with entries",
|
"Cannot past travels with entries": "Cannot past travels with entries",
|
||||||
"It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}"
|
"It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}",
|
||||||
|
"Incorrect pin": "Incorrect pin."
|
||||||
}
|
}
|
|
@ -72,6 +72,7 @@
|
||||||
"The secret can't be blank": "La contraseña no puede estar en blanco",
|
"The secret can't be blank": "La contraseña no puede estar en blanco",
|
||||||
"We weren't able to send this SMS": "No hemos podido enviar el SMS",
|
"We weren't able to send this SMS": "No hemos podido enviar el SMS",
|
||||||
"This client can't be invoiced": "Este cliente no puede ser facturado",
|
"This client can't be invoiced": "Este cliente no puede ser facturado",
|
||||||
|
"You must provide the correction information to generate a corrective invoice": "Debes informar la información de corrección para generar una factura rectificativa",
|
||||||
"This ticket can't be invoiced": "Este ticket no puede ser facturado",
|
"This ticket can't be invoiced": "Este ticket no puede ser facturado",
|
||||||
"You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado",
|
"You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado",
|
||||||
"This ticket can not be modified": "Este ticket no puede ser modificado",
|
"This ticket can not be modified": "Este ticket no puede ser modificado",
|
||||||
|
@ -305,14 +306,15 @@
|
||||||
"Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico",
|
"Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico",
|
||||||
"The renew period has not been exceeded": "El periodo de renovación no ha sido superado",
|
"The renew period has not been exceeded": "El periodo de renovación no ha sido superado",
|
||||||
"Valid priorities": "Prioridades válidas: %d",
|
"Valid priorities": "Prioridades válidas: %d",
|
||||||
"Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}",
|
"hasAnyNegativeBase": "Base negativa para los tickets: {{ticketsIds}}",
|
||||||
|
"hasAnyPositiveBase": "Base positivas para los tickets: {{ticketsIds}}",
|
||||||
"You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado",
|
"You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado",
|
||||||
"This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s",
|
"This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s",
|
||||||
"The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias",
|
"The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias",
|
||||||
"You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado",
|
"You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado",
|
||||||
"This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado",
|
"This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado",
|
||||||
"You don't have enough privileges.": "No tienes suficientes permisos.",
|
"You don't have enough privileges.": "No tienes suficientes permisos.",
|
||||||
"This ticket is locked.": "Este ticket está bloqueado.",
|
"This ticket is locked": "Este ticket está bloqueado.",
|
||||||
"This ticket is not editable.": "Este ticket no es editable.",
|
"This ticket is not editable.": "Este ticket no es editable.",
|
||||||
"The ticket doesn't exist.": "No existe el ticket.",
|
"The ticket doesn't exist.": "No existe el ticket.",
|
||||||
"Social name should be uppercase": "La razón social debe ir en mayúscula",
|
"Social name should be uppercase": "La razón social debe ir en mayúscula",
|
||||||
|
@ -329,5 +331,10 @@
|
||||||
"The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima",
|
"The amount cannot be less than the minimum": "La cantidad no puede ser menor que la cantidad mínima",
|
||||||
"quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima",
|
"quantityLessThanMin": "La cantidad no puede ser menor que la cantidad mínima",
|
||||||
"Cannot past travels with entries": "No se pueden pasar envíos con entradas",
|
"Cannot past travels with entries": "No se pueden pasar envíos con entradas",
|
||||||
"It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}"
|
"It was not able to remove the next expeditions:": "No se pudo eliminar las siguientes expediciones: {{expeditions}}",
|
||||||
|
"This user does not have an assigned tablet": "Este usuario no tiene tablet asignada",
|
||||||
|
"Incorrect pin": "Pin incorrecto.",
|
||||||
|
"You already have the mailAlias": "Ya tienes este alias de correo",
|
||||||
|
"The alias cant be modified": "Este alias de correo no puede ser modificado",
|
||||||
|
"No tickets to invoice": "No hay tickets para facturar"
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
module.exports = () => {
|
module.exports = () => {
|
||||||
Date.vnUTC = () => {
|
Date.vnUTC = (env = process.env.NODE_ENV) => {
|
||||||
const env = process.env.NODE_ENV;
|
|
||||||
if (!env || env === 'development')
|
if (!env || env === 'development')
|
||||||
return new Date(Date.UTC(2001, 0, 1, 11));
|
return new Date(Date.UTC(2001, 0, 1, 11));
|
||||||
|
|
||||||
|
|
|
@ -25,20 +25,19 @@
|
||||||
"FieldAcl": {
|
"FieldAcl": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"Role": {
|
|
||||||
"dataSource": "vn",
|
|
||||||
"options": {
|
|
||||||
"mysql": {
|
|
||||||
"table": "salix.Role"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"RoleMapping": {
|
"RoleMapping": {
|
||||||
"dataSource": "vn",
|
"dataSource": "vn",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "salix.RoleMapping"
|
"table": "salix.RoleMapping"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"role": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "VnRole",
|
||||||
|
"foreignKey": "roleId"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Schema": {
|
"Schema": {
|
||||||
|
|
|
@ -2,7 +2,7 @@ const {models} = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('account changePassword()', () => {
|
describe('account changePassword()', () => {
|
||||||
const userId = 70;
|
const userId = 70;
|
||||||
const unauthCtx = {
|
const unAuthCtx = {
|
||||||
req: {
|
req: {
|
||||||
headers: {},
|
headers: {},
|
||||||
connection: {
|
connection: {
|
||||||
|
@ -79,7 +79,7 @@ describe('account changePassword()', () => {
|
||||||
passExpired: yesterday
|
passExpired: yesterday
|
||||||
}
|
}
|
||||||
, options);
|
, options);
|
||||||
await models.VnUser.signIn(unauthCtx, 'trainee', 'nightmare', options);
|
await models.VnUser.signIn(unAuthCtx, 'trainee', 'nightmare', options);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.message != 'Pass expired')
|
if (e.message != 'Pass expired')
|
||||||
throw e;
|
throw e;
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
"MailAliasAccount": {
|
"MailAliasAccount": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"MailAliasAcl": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"MailConfig": {
|
"MailConfig": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
|
|
@ -239,7 +239,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
// Prepare data
|
// Prepare data
|
||||||
|
|
||||||
let roles = await $.Role.find({
|
let roles = await $.VnRole.find({
|
||||||
fields: ['id', 'name', 'description']
|
fields: ['id', 'name', 'description']
|
||||||
});
|
});
|
||||||
let roleRoles = await $.RoleRole.find({
|
let roleRoles = await $.RoleRole.find({
|
||||||
|
|
|
@ -2,54 +2,44 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
|
Self.rewriteDbError(function(err) {
|
||||||
|
if (err.code === 'ER_DUP_ENTRY')
|
||||||
|
return new UserError(`You already have the mailAlias`);
|
||||||
|
return err;
|
||||||
|
});
|
||||||
|
|
||||||
Self.observe('before save', async ctx => {
|
Self.observe('before save', async ctx => {
|
||||||
const changes = ctx.currentInstance || ctx.instance;
|
const changes = ctx.currentInstance || ctx.instance;
|
||||||
|
|
||||||
await Self.hasGrant(ctx, changes.mailAlias);
|
await checkModifyPermission(ctx, changes.mailAlias);
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.observe('before delete', async ctx => {
|
Self.observe('before delete', async ctx => {
|
||||||
const mailAliasAccount = await Self.findById(ctx.where.id);
|
const mailAliasAccount = await Self.findById(ctx.where.id);
|
||||||
|
|
||||||
await Self.hasGrant(ctx, mailAliasAccount.mailAlias);
|
await checkModifyPermission(ctx, mailAliasAccount.mailAlias);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
async function checkModifyPermission(ctx, mailAliasFk) {
|
||||||
* Checks if current user has
|
const userId = ctx.options.accessToken.userId;
|
||||||
* grant to add/remove alias
|
|
||||||
*
|
|
||||||
* @param {Object} ctx - Request context
|
|
||||||
* @param {Interger} mailAlias - mailAlias id
|
|
||||||
* @return {Boolean} True for user with grant
|
|
||||||
*/
|
|
||||||
Self.hasGrant = async function(ctx, mailAlias) {
|
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const accessToken = {req: {accessToken: ctx.options.accessToken}};
|
|
||||||
const userId = accessToken.req.accessToken.userId;
|
|
||||||
|
|
||||||
const canEditAlias = await models.ACL.checkAccessAcl(accessToken, 'MailAliasAccount', 'canEditAlias', 'WRITE');
|
const roles = await models.RoleMapping.find({
|
||||||
if (canEditAlias) return true;
|
fields: ['roleId'],
|
||||||
|
where: {principalId: userId}
|
||||||
|
});
|
||||||
|
|
||||||
const user = await models.VnUser.findById(userId, {fields: ['hasGrant']});
|
const availableMailAlias = await models.MailAliasAcl.findOne({
|
||||||
if (!user.hasGrant)
|
fields: ['mailAliasFk'],
|
||||||
throw new UserError(`You don't have grant privilege`);
|
include: {relation: 'mailAlias'},
|
||||||
|
where: {
|
||||||
const account = await models.Account.findById(userId, {
|
roleFk: {
|
||||||
fields: ['id'],
|
inq: roles.map(role => role.roleId),
|
||||||
include: {
|
},
|
||||||
relation: 'aliases',
|
mailAliasFk
|
||||||
scope: {
|
|
||||||
fields: ['mailAlias']
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const aliases = account.aliases().map(alias => alias.mailAlias);
|
if (!availableMailAlias) throw new UserError('The alias cant be modified');
|
||||||
|
}
|
||||||
const hasAlias = aliases.includes(mailAlias);
|
|
||||||
if (!hasAlias)
|
|
||||||
throw new UserError(`You cannot assign/remove an alias that you are not assigned to`);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"name": "MailAliasAcl",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "account.mailAliasAcl"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"mailAliasFk": {
|
||||||
|
"id": true,
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"roleFk": {
|
||||||
|
"id": true,
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"mailAlias": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "MailAlias",
|
||||||
|
"foreignKey": "mailAliasFk"
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Role",
|
||||||
|
"foreignKey": "roleFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,12 +15,12 @@
|
||||||
"relations": {
|
"relations": {
|
||||||
"owner": {
|
"owner": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "role"
|
"foreignKey": "role"
|
||||||
},
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "inheritsFrom"
|
"foreignKey": "inheritsFrom"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,12 @@
|
||||||
"relations": {
|
"relations": {
|
||||||
"owner": {
|
"owner": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "role"
|
"foreignKey": "role"
|
||||||
},
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "inheritsFrom"
|
"foreignKey": "inheritsFrom"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
label="Role"
|
label="Role"
|
||||||
ng-model="$ctrl.acl.principalId"
|
ng-model="$ctrl.acl.principalId"
|
||||||
url="Roles"
|
url="VnRoles"
|
||||||
id-field="name"
|
id-field="name"
|
||||||
value-field="name"
|
value-field="name"
|
||||||
vn-focus>
|
vn-focus>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
label="Role"
|
label="Role"
|
||||||
ng-model="filter.principalId"
|
ng-model="filter.principalId"
|
||||||
url="Roles"
|
url="VnRoles"
|
||||||
value-field="name">
|
value-field="name">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
label="Role"
|
label="Role"
|
||||||
ng-model="$ctrl.user.roleFk"
|
ng-model="$ctrl.user.roleFk"
|
||||||
url="Roles"
|
url="VnRoles"
|
||||||
rule="VnUser">
|
rule="VnUser">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
label="Role"
|
label="Role"
|
||||||
ng-model="$ctrl.user.roleFk"
|
ng-model="$ctrl.user.roleFk"
|
||||||
url="Roles">
|
url="VnRoles">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
<vn-watcher
|
<vn-watcher
|
||||||
vn-id="watcher"
|
vn-id="watcher"
|
||||||
url="Roles"
|
url="VnRoles"
|
||||||
data="$ctrl.role"
|
data="$ctrl.role"
|
||||||
form="form">
|
form="form">
|
||||||
</vn-watcher>
|
</vn-watcher>
|
||||||
<form
|
<form
|
||||||
name="form"
|
name="form"
|
||||||
ng-submit="watcher.submit()"
|
ng-submit="watcher.submit()"
|
||||||
|
|
||||||
class="vn-w-md">
|
class="vn-w-md">
|
||||||
<vn-card class="vn-pa-lg">
|
<vn-card class="vn-pa-lg">
|
||||||
<vn-vertical>
|
<vn-vertical>
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
label="Name"
|
label="Name"
|
||||||
ng-model="$ctrl.role.name"
|
ng-model="$ctrl.role.name"
|
||||||
rule
|
rule="VnRole.name"
|
||||||
vn-focus>
|
vn-focus>
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
label="Description"
|
label="Description"
|
||||||
ng-model="$ctrl.role.description"
|
ng-model="$ctrl.role.description"
|
||||||
rule>
|
rule="VnRole.description"
|
||||||
|
>
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import ModuleCard from 'salix/components/module-card';
|
||||||
|
|
||||||
class Controller extends ModuleCard {
|
class Controller extends ModuleCard {
|
||||||
reload() {
|
reload() {
|
||||||
this.$http.get(`Roles/${this.$params.id}`)
|
this.$http.get(`VnRoles/${this.$params.id}`)
|
||||||
.then(res => this.role = res.data);
|
.then(res => this.role = res.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import './index';
|
import './index';
|
||||||
|
|
||||||
describe('component vnRoleCard', () => {
|
fdescribe('component vnRoleCard', () => {
|
||||||
let controller;
|
let controller;
|
||||||
let $httpBackend;
|
let $httpBackend;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ describe('component vnRoleCard', () => {
|
||||||
it('should reload the controller data', () => {
|
it('should reload the controller data', () => {
|
||||||
controller.$params.id = 1;
|
controller.$params.id = 1;
|
||||||
|
|
||||||
$httpBackend.expectGET('Roles/1').respond('foo');
|
$httpBackend.expectGET('VnRoles/1').respond('foo');
|
||||||
controller.reload();
|
controller.reload();
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<vn-watcher
|
<vn-watcher
|
||||||
vn-id="watcher"
|
vn-id="watcher"
|
||||||
url="Roles"
|
url="VnRoles"
|
||||||
data="$ctrl.role"
|
data="$ctrl.role"
|
||||||
insert-mode="true"
|
insert-mode="true"
|
||||||
form="form">
|
form="form">
|
||||||
|
@ -14,13 +14,13 @@
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
label="Name"
|
label="Name"
|
||||||
ng-model="$ctrl.role.name"
|
ng-model="$ctrl.role.name"
|
||||||
rule
|
rule="VnRole.name"
|
||||||
vn-focus>
|
vn-focus>
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
label="Description"
|
label="Description"
|
||||||
ng-model="$ctrl.role.description"
|
ng-model="$ctrl.role.description"
|
||||||
rule>
|
rule="VnRole.description">
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
|
|
@ -11,7 +11,7 @@ class Controller extends Descriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
onDelete() {
|
onDelete() {
|
||||||
return this.$http.delete(`Roles/${this.id}`)
|
return this.$http.delete(`VnRoles/${this.id}`)
|
||||||
.then(() => this.$state.go('account.role'))
|
.then(() => this.$state.go('account.role'))
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('Role removed')));
|
.then(() => this.vnApp.showSuccess(this.$t('Role removed')));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import './index';
|
import './index';
|
||||||
|
|
||||||
describe('component vnRoleDescriptor', () => {
|
fdescribe('component vnRoleDescriptor', () => {
|
||||||
let controller;
|
let controller;
|
||||||
let $httpBackend;
|
let $httpBackend;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ describe('component vnRoleDescriptor', () => {
|
||||||
controller.$state.go = jest.fn();
|
controller.$state.go = jest.fn();
|
||||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
|
||||||
$httpBackend.expectDELETE('Roles/1').respond();
|
$httpBackend.expectDELETE('VnRoles/1').respond();
|
||||||
controller.onDelete();
|
controller.onDelete();
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="Roles"
|
url="VnRoles"
|
||||||
filter="::$ctrl.filter"
|
filter="::$ctrl.filter"
|
||||||
limit="20">
|
limit="20">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
label="Role"
|
label="Role"
|
||||||
ng-model="$ctrl.addData.inheritsFrom"
|
ng-model="$ctrl.addData.inheritsFrom"
|
||||||
url="Roles"
|
url="VnRoles"
|
||||||
vn-focus>
|
vn-focus>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</tpl-body>
|
</tpl-body>
|
||||||
|
|
|
@ -6,7 +6,7 @@ class Controller extends Component {
|
||||||
this._role = value;
|
this._role = value;
|
||||||
this.$.summary = null;
|
this.$.summary = null;
|
||||||
if (!value) return;
|
if (!value) return;
|
||||||
this.$http.get(`Roles/${value.id}`)
|
this.$http.get(`VnRoles/${value.id}`)
|
||||||
.then(res => this.$.summary = res.data);
|
.then(res => this.$.summary = res.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
vn-one
|
vn-one
|
||||||
label="Role"
|
label="Role"
|
||||||
ng-model="filter.roleFk"
|
ng-model="filter.roleFk"
|
||||||
url="Roles"
|
url="VnRoles"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
show-field="name">
|
show-field="name">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
|
|
|
@ -123,7 +123,7 @@ module.exports = Self => {
|
||||||
await models.TicketTracking.create({
|
await models.TicketTracking.create({
|
||||||
ticketFk: newRefundTicket.id,
|
ticketFk: newRefundTicket.id,
|
||||||
stateFk: state.id,
|
stateFk: state.id,
|
||||||
workerFk: worker.id
|
userFk: worker.id
|
||||||
}, myOptions);
|
}, myOptions);
|
||||||
|
|
||||||
const salesToRefund = await models.ClaimBeginning.find(salesFilter, myOptions);
|
const salesToRefund = await models.ClaimBeginning.find(salesFilter, myOptions);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('removeFile', {
|
Self.remoteMethodCtx('removeFile', {
|
||||||
description: 'Removes a claim document',
|
description: 'Removes a claim document',
|
||||||
|
@ -19,8 +21,8 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.removeFile = async(ctx, id, options) => {
|
Self.removeFile = async(ctx, id, options) => {
|
||||||
let tx;
|
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
@ -31,19 +33,18 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const models = Self.app.models;
|
const claimDms = await Self.findById(id, null, myOptions);
|
||||||
const targetClaimDms = await models.ClaimDms.findById(id, null, myOptions);
|
|
||||||
const targetDms = await models.Dms.findById(targetClaimDms.dmsFk, null, myOptions);
|
|
||||||
const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}}, myOptions);
|
|
||||||
|
|
||||||
await models.Dms.removeFile(ctx, targetClaimDms.dmsFk, myOptions);
|
const targetDms = await Self.app.models.Dms.removeFile(ctx, claimDms.dmsFk, myOptions);
|
||||||
await targetClaimDms.destroy(myOptions);
|
|
||||||
|
|
||||||
await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions);
|
if (!targetDms || ! claimDms)
|
||||||
|
throw new UserError('Try again');
|
||||||
|
|
||||||
|
const claimDmsDestroyed = await claimDms.destroy(myOptions);
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
return targetDms;
|
return claimDmsDestroyed;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (tx) await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
throw e;
|
throw e;
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
|
||||||
const fs = require('fs-extra');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('uploadFile', {
|
Self.remoteMethodCtx('uploadFile', {
|
||||||
|
@ -57,96 +54,33 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.uploadFile = async(ctx, id, options) => {
|
Self.uploadFile = async(ctx, id, options) => {
|
||||||
const tx = await Self.beginTransaction({});
|
const {Dms, ClaimDms} = Self.app.models;
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
if (!myOptions.transaction)
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
myOptions.transaction = tx;
|
myOptions.transaction = tx;
|
||||||
|
|
||||||
const models = Self.app.models;
|
|
||||||
const promises = [];
|
|
||||||
const TempContainer = models.TempContainer;
|
|
||||||
const ClaimContainer = models.ClaimContainer;
|
|
||||||
const fileOptions = {};
|
|
||||||
const args = ctx.args;
|
|
||||||
|
|
||||||
let srcFile;
|
|
||||||
try {
|
|
||||||
const hasWriteRole = await models.DmsType.hasWriteRole(ctx, args.dmsTypeId, myOptions);
|
|
||||||
if (!hasWriteRole)
|
|
||||||
throw new UserError(`You don't have enough privileges`);
|
|
||||||
|
|
||||||
// Upload file to temporary path
|
|
||||||
const tempContainer = await TempContainer.container('dms');
|
|
||||||
const uploaded = await TempContainer.upload(tempContainer.name, ctx.req, ctx.result, fileOptions);
|
|
||||||
const files = Object.values(uploaded.files).map(file => {
|
|
||||||
return file[0];
|
|
||||||
});
|
|
||||||
|
|
||||||
const addedDms = [];
|
|
||||||
for (const uploadedFile of files) {
|
|
||||||
const newDms = await createDms(ctx, uploadedFile, myOptions);
|
|
||||||
const pathHash = ClaimContainer.getHash(newDms.id);
|
|
||||||
|
|
||||||
const file = await TempContainer.getFile(tempContainer.name, uploadedFile.name);
|
|
||||||
srcFile = path.join(file.client.root, file.container, file.name);
|
|
||||||
|
|
||||||
const claimContainer = await ClaimContainer.container(pathHash);
|
|
||||||
const dstFile = path.join(claimContainer.client.root, pathHash, newDms.file);
|
|
||||||
|
|
||||||
await fs.move(srcFile, dstFile, {
|
|
||||||
overwrite: true
|
|
||||||
});
|
|
||||||
|
|
||||||
addedDms.push(newDms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addedDms.forEach(dms => {
|
try {
|
||||||
const newClaimDms = models.ClaimDms.create({
|
const uploadedFiles = await Dms.uploadFile(ctx, myOptions);
|
||||||
|
|
||||||
|
const promises = uploadedFiles.map(dms => ClaimDms.create({
|
||||||
claimFk: id,
|
claimFk: id,
|
||||||
dmsFk: dms.id
|
dmsFk: dms.id
|
||||||
}, myOptions);
|
}, myOptions));
|
||||||
|
await Promise.all(promises);
|
||||||
promises.push(newClaimDms);
|
|
||||||
});
|
|
||||||
const resolvedPromises = await Promise.all(promises);
|
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
return resolvedPromises;
|
return uploadedFiles;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (tx) await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
|
|
||||||
if (fs.existsSync(srcFile))
|
|
||||||
await fs.unlink(srcFile);
|
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async function createDms(ctx, file, myOptions) {
|
|
||||||
const models = Self.app.models;
|
|
||||||
const myUserId = ctx.req.accessToken.userId;
|
|
||||||
const args = ctx.args;
|
|
||||||
|
|
||||||
const newDms = await models.Dms.create({
|
|
||||||
workerFk: myUserId,
|
|
||||||
dmsTypeFk: args.dmsTypeId,
|
|
||||||
companyFk: args.companyId,
|
|
||||||
warehouseFk: args.warehouseId,
|
|
||||||
reference: args.reference,
|
|
||||||
description: args.description,
|
|
||||||
contentType: file.type,
|
|
||||||
hasFile: args.hasFile
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
let fileName = file.name;
|
|
||||||
const extension = models.DmsContainer.getFileExtension(fileName);
|
|
||||||
fileName = `${newDms.id}.${extension}`;
|
|
||||||
|
|
||||||
return newDms.updateAttribute('file', fileName, myOptions);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "ClaimBeginning",
|
"name": "ClaimBeginning",
|
||||||
"base": "Loggable",
|
"base": "VnModel",
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "claimBeginning"
|
"table": "claimBeginning"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "ClaimDevelopment",
|
"name": "ClaimDevelopment",
|
||||||
"base": "Loggable",
|
"base": "VnModel",
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "claimDevelopment"
|
"table": "claimDevelopment"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "ClaimDms",
|
"name": "ClaimDms",
|
||||||
"base": "Loggable",
|
"base": "VnModel",
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "claimDms"
|
"table": "claimDms"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "ClaimEnd",
|
"name": "ClaimEnd",
|
||||||
"base": "Loggable",
|
"base": "VnModel",
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "claimEnd"
|
"table": "claimEnd"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "ClaimObservation",
|
"name": "ClaimObservation",
|
||||||
"base": "Loggable",
|
"base": "VnModel",
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "claimObservation"
|
"table": "claimObservation"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "ClaimState",
|
"name": "ClaimState",
|
||||||
"base": "Loggable",
|
"base": "VnModel",
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "claimState"
|
"table": "claimState"
|
||||||
|
@ -32,7 +35,7 @@
|
||||||
"relations": {
|
"relations": {
|
||||||
"writeRole": {
|
"writeRole": {
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Role",
|
"model": "VnRole",
|
||||||
"foreignKey": "roleFk"
|
"foreignKey": "roleFk"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "Claim",
|
"name": "Claim",
|
||||||
"base": "Loggable",
|
"base": "VnModel",
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "claim"
|
"table": "claim"
|
||||||
|
|
|
@ -19,9 +19,8 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.removeFile = async(ctx, id, options) => {
|
Self.removeFile = async(ctx, id, options) => {
|
||||||
const models = Self.app.models;
|
|
||||||
let tx;
|
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
let tx;
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
@ -34,13 +33,16 @@ module.exports = Self => {
|
||||||
try {
|
try {
|
||||||
const clientDms = await Self.findById(id, null, myOptions);
|
const clientDms = await Self.findById(id, null, myOptions);
|
||||||
|
|
||||||
await models.Dms.removeFile(ctx, clientDms.dmsFk, myOptions);
|
const targetDms = await Self.app.models.Dms.removeFile(ctx, clientDms.dmsFk, myOptions);
|
||||||
|
|
||||||
const destroyedClient = await clientDms.destroy(myOptions);
|
if (!targetDms || !clientDms)
|
||||||
|
throw new UserError('Try again');
|
||||||
|
|
||||||
|
const clientDmsDestroyed = await clientDms.destroy(myOptions);
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
return destroyedClient;
|
return clientDmsDestroyed;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (tx) await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
throw e;
|
throw e;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = function(Self) {
|
module.exports = function(Self) {
|
||||||
Self.remoteMethodCtx('canBeInvoiced', {
|
Self.remoteMethod('canBeInvoiced', {
|
||||||
description: 'Change property isEqualizated in all client addresses',
|
description: 'Change property isEqualizated in all client addresses',
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [
|
accepts: [
|
||||||
|
|
|
@ -107,17 +107,29 @@ module.exports = Self => {
|
||||||
return {or: [
|
return {or: [
|
||||||
{'c.phone': {like: `%${value}%`}},
|
{'c.phone': {like: `%${value}%`}},
|
||||||
{'c.mobile': {like: `%${value}%`}},
|
{'c.mobile': {like: `%${value}%`}},
|
||||||
|
{'a.phone': {like: `%${value}%`}},
|
||||||
]};
|
]};
|
||||||
case 'zoneFk':
|
case 'zoneFk':
|
||||||
param = 'a.postalCode';
|
return {'a.postalCode': {inq: postalCode}};
|
||||||
return {[param]: {inq: postalCode}};
|
case 'city':
|
||||||
|
return {or: [
|
||||||
|
{'c.city': {like: `%${value}%`}},
|
||||||
|
{'a.city': {like: `%${value}%`}}
|
||||||
|
]};
|
||||||
|
case 'postcode':
|
||||||
|
return {or: [
|
||||||
|
{'c.postcode': value},
|
||||||
|
{'a.postalCode': value}
|
||||||
|
]};
|
||||||
|
case 'provinceFk':
|
||||||
|
return {or: [
|
||||||
|
{'p.id': value},
|
||||||
|
{'a.provinceFk': value}
|
||||||
|
]};
|
||||||
case 'name':
|
case 'name':
|
||||||
case 'salesPersonFk':
|
case 'salesPersonFk':
|
||||||
case 'fi':
|
case 'fi':
|
||||||
case 'socialName':
|
case 'socialName':
|
||||||
case 'city':
|
|
||||||
case 'postcode':
|
|
||||||
case 'provinceFk':
|
|
||||||
case 'email':
|
case 'email':
|
||||||
param = `c.${param}`;
|
param = `c.${param}`;
|
||||||
return {[param]: {like: `%${value}%`}};
|
return {[param]: {like: `%${value}%`}};
|
||||||
|
@ -134,24 +146,29 @@ module.exports = Self => {
|
||||||
c.fi,
|
c.fi,
|
||||||
c.socialName,
|
c.socialName,
|
||||||
c.phone,
|
c.phone,
|
||||||
|
a.phone,
|
||||||
c.mobile,
|
c.mobile,
|
||||||
c.city,
|
c.city,
|
||||||
|
a.city,
|
||||||
c.postcode,
|
c.postcode,
|
||||||
|
a.postalCode,
|
||||||
c.email,
|
c.email,
|
||||||
c.isActive,
|
c.isActive,
|
||||||
c.isFreezed,
|
c.isFreezed,
|
||||||
p.id AS provinceFk,
|
p.id AS provinceClientFk,
|
||||||
|
a.provinceFk AS provinceAddressFk,
|
||||||
p.name AS province,
|
p.name AS province,
|
||||||
u.id AS salesPersonFk,
|
u.id AS salesPersonFk,
|
||||||
u.name AS salesPerson
|
u.name AS salesPerson
|
||||||
FROM client c
|
FROM client c
|
||||||
LEFT JOIN account.user u ON u.id = c.salesPersonFk
|
LEFT JOIN account.user u ON u.id = c.salesPersonFk
|
||||||
LEFT JOIN province p ON p.id = c.provinceFk
|
LEFT JOIN province p ON p.id = c.provinceFk
|
||||||
JOIN vn.address a ON a.clientFk = c.id
|
JOIN address a ON a.clientFk = c.id
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
stmt.merge(conn.makeWhere(filter.where));
|
stmt.merge(conn.makeWhere(filter.where));
|
||||||
|
stmt.merge('GROUP BY c.id');
|
||||||
stmt.merge(conn.makePagination(filter));
|
stmt.merge(conn.makePagination(filter));
|
||||||
|
|
||||||
const clientsIndex = stmts.push(stmt) - 1;
|
const clientsIndex = stmts.push(stmt) - 1;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue