Merge branch 'dev' into 6259-ticketSmsJoinClientSms
gitea/salix/pipeline/head There was a failure building this commit Details

This commit is contained in:
Pablo Natek 2023-12-20 09:57:18 +00:00
commit 2185b4ddc0
114 changed files with 2265 additions and 747 deletions

View File

@ -11,6 +11,9 @@
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"cSpell.words": [
"salix",
"fdescribe"

View File

@ -5,6 +5,12 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2352.01] - 2023-12-28
### Added
### Changed
### Fixed
## [2350.01] - 2023-12-14
### Added
@ -14,14 +20,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [2348.01] - 2023-11-30
### Added
- (Ticket -> Adelantar) Permite mover lineas sin generar negativos
- (Ticket -> Adelantar) Permite modificar la fecha de los tickets
- (Trabajadores -> Notificaciones) Nueva sección (lilium)
### Características Añadidas 🆕
- **Tickets → Adelantar:** Permite mover lineas sin generar negativos
- **Tickets → Adelantar:** Permite modificar la fecha de los tickets
- **Trabajadores → Notificaciones:** Nueva sección (lilium)
### Changed
### Fixed
- (Ticket -> RocketChat) Arreglada detección de cambios
### Correcciones 🛠️
- **Tickets → RocketChat:** Arreglada detección de cambios
## [2346.01] - 2023-11-16

View File

@ -22,8 +22,8 @@ module.exports = Self => {
Self.removeFile = async(ctx, id, options) => {
const models = Self.app.models;
let tx;
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<DeleteEnvio xmlns="http://82.223.6.71:82">
<IdCliente><%= viaexpressConfig.client %></IdCliente>
<Usuario><%= viaexpressConfig.user %></Usuario>
<Password><%= viaexpressConfig.password %></Password>
<etiqueta><%= externalId %></etiqueta>
</DeleteEnvio>
</soap12:Body>
</soap12:Envelope>

View File

@ -0,0 +1,45 @@
const axios = require('axios');
const {DOMParser} = require('xmldom');
module.exports = Self => {
Self.remoteMethod('deleteExpedition', {
description: 'Delete a shipment by providing the expedition ID, interacting with Viaexpress API',
accessType: 'WRITE',
accepts: [{
arg: 'expeditionFk',
type: 'number',
required: true
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/deleteExpedition`,
verb: 'POST'
}
});
Self.deleteExpedition = async expeditionFk => {
const models = Self.app.models;
const viaexpressConfig = await models.ViaexpressConfig.findOne({
fields: ['url']
});
const renderedXml = await models.ViaexpressConfig.deleteExpeditionRenderer(expeditionFk);
const response = await axios.post(`${viaexpressConfig.url}ServicioVxClientes.asmx`, renderedXml, {
headers: {
'Content-Type': 'application/soap+xml; charset=utf-8'
}
});
const xmlString = response.data;
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
const resultElement = xmlDoc.getElementsByTagName('DeleteEnvioResult')[0];
const result = resultElement.textContent;
return result;
};
};

View File

@ -0,0 +1,44 @@
const fs = require('fs');
const ejs = require('ejs');
module.exports = Self => {
Self.remoteMethod('deleteExpeditionRenderer', {
description: 'Renders the data from an XML',
accessType: 'READ',
accepts: [{
arg: 'expeditionFk',
type: 'number',
required: true
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/deleteExpeditionRenderer`,
verb: 'GET'
}
});
Self.deleteExpeditionRenderer = async expeditionFk => {
const models = Self.app.models;
const viaexpressConfig = await models.ViaexpressConfig.findOne({
fields: ['client', 'user', 'password']
});
const expedition = await models.Expedition.findOne({
fields: ['id', 'externalId'],
where: {id: expeditionFk}
});
const data = {
viaexpressConfig,
externalId: expedition.externalId
};
const template = fs.readFileSync(__dirname + '/deleteExpedition.ejs', 'utf-8');
const renderedXml = ejs.render(template, data);
return renderedXml;
};
};

View File

@ -1,5 +1,14 @@
const UserError = require('vn-loopback/util/user-error');
const {models} = require('vn-loopback/server/server');
const handlePromiseLogout = (Self, {id}, courtesyTime) => {
new Promise(res => {
setTimeout(() => {
res(Self.logout(id));
}
, courtesyTime * 1000);
});
};
module.exports = Self => {
Self.remoteMethodCtx('renewToken', {
description: 'Checks if the token has more than renewPeriod seconds to live and if so, renews it',
@ -16,23 +25,32 @@ module.exports = Self => {
});
Self.renewToken = async function(ctx) {
const models = Self.app.models;
const token = ctx.req.accessToken;
const {accessToken: token} = ctx.req;
const now = new Date();
const differenceMilliseconds = now - token.created;
const differenceSeconds = Math.floor(differenceMilliseconds / 1000);
// Check if current token is valid
const isValid = await validateToken(token);
if (isValid)
return token;
const fields = ['renewPeriod', 'courtesyTime'];
const accessTokenConfig = await models.AccessTokenConfig.findOne({fields});
const {courtesyTime} = await models.AccessTokenConfig.findOne({fields: ['courtesyTime']});
if (differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime)
throw new UserError(`The renew period has not been exceeded`, 'periodNotExceeded');
// Schedule to remove current token
handlePromiseLogout(Self, token, courtesyTime);
await Self.logout(token.id);
// Create new accessToken
const user = await Self.findById(token.userId);
const accessToken = await user.createAccessToken();
return {id: accessToken.id, ttl: accessToken.ttl};
};
async function validateToken(token) {
const accessTokenConfig = await models.AccessTokenConfig.findOne({fields: ['renewPeriod', 'courtesyTime']});
const now = Date.now();
const differenceMilliseconds = now - token.created;
const differenceSeconds = Math.floor(differenceMilliseconds / 1000);
const isValid = differenceSeconds < accessTokenConfig.renewPeriod - accessTokenConfig.courtesyTime;
return isValid;
}
};

View File

@ -49,13 +49,7 @@ module.exports = Self => {
if (vnUser.twoFactor)
throw new ForbiddenError(null, 'REQUIRES_2FA');
}
const validateLogin = await Self.validateLogin(user, password);
await Self.app.models.SignInLog.create({
token: validateLogin.token,
userFk: vnUser.id,
ip: ctx.req.ip
});
return validateLogin;
return Self.validateLogin(user, password, ctx);
};
Self.passExpired = async vnUser => {

View File

@ -0,0 +1,49 @@
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 process', async() => {
jasmine.clock().mockDate(new Date(startingTime + 21600000));
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);
});
});

View File

@ -2,7 +2,7 @@ const {models} = require('vn-loopback/server/server');
describe('VnUser Sign-in()', () => {
const employeeId = 1;
const unauthCtx = {
const unAuthCtx = {
req: {
headers: {},
connection: {
@ -15,20 +15,21 @@ describe('VnUser Sign-in()', () => {
const {VnUser, AccessToken, SignInLog} = models;
describe('when credentials are correct', () => {
it('should return the token if user uses email', async() => {
let login = await VnUser.signIn(unauthCtx, 'salesAssistant@mydomain.com', 'nightmare');
let login = await VnUser.signIn(unAuthCtx, 'salesAssistant@mydomain.com', 'nightmare');
let accessToken = await AccessToken.findById(login.token);
let ctx = {req: {accessToken: accessToken}};
let signInLog = await SignInLog.find({where: {token: accessToken.id}});
expect(signInLog.length).toEqual(1);
expect(signInLog[0].userFk).toEqual(accessToken.userId);
expect(signInLog[0].owner).toEqual(true);
expect(login.token).toBeDefined();
await VnUser.logout(ctx.req.accessToken.id);
});
it('should return the token', async() => {
let login = await VnUser.signIn(unauthCtx, 'salesAssistant', 'nightmare');
let login = await VnUser.signIn(unAuthCtx, 'salesAssistant', 'nightmare');
let accessToken = await AccessToken.findById(login.token);
let ctx = {req: {accessToken: accessToken}};
@ -38,7 +39,7 @@ describe('VnUser Sign-in()', () => {
});
it('should return the token if the user doesnt exist but the client does', async() => {
let login = await VnUser.signIn(unauthCtx, 'PetterParker', 'nightmare');
let login = await VnUser.signIn(unAuthCtx, 'PetterParker', 'nightmare');
let accessToken = await AccessToken.findById(login.token);
let ctx = {req: {accessToken: accessToken}};
@ -53,7 +54,7 @@ describe('VnUser Sign-in()', () => {
let error;
try {
await VnUser.signIn(unauthCtx, 'IDontExist', 'TotallyWrongPassword');
await VnUser.signIn(unAuthCtx, 'IDontExist', 'TotallyWrongPassword');
} catch (e) {
error = e;
}
@ -74,7 +75,7 @@ describe('VnUser Sign-in()', () => {
const options = {transaction: tx};
await employee.updateAttribute('twoFactor', 'email', options);
await VnUser.signIn(unauthCtx, 'employee', 'nightmare', options);
await VnUser.signIn(unAuthCtx, 'employee', 'nightmare', options);
await tx.rollback();
} catch (e) {
await tx.rollback();
@ -99,7 +100,7 @@ describe('VnUser Sign-in()', () => {
const options = {transaction: tx};
await employee.updateAttribute('passExpired', yesterday, options);
await VnUser.signIn(unauthCtx, 'employee', 'nightmare', options);
await VnUser.signIn(unAuthCtx, 'employee', 'nightmare', options);
await tx.rollback();
} catch (e) {
await tx.rollback();

View File

@ -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;
};
};

View File

@ -1,4 +1,6 @@
module.exports = Self => {
require('../methods/viaexpress-config/internationalExpedition')(Self);
require('../methods/viaexpress-config/renderer')(Self);
require('../methods/viaexpress-config/deleteExpedition')(Self);
require('../methods/viaexpress-config/deleteExpeditionRenderer')(Self);
};

View File

@ -10,7 +10,6 @@ module.exports = function(Self) {
require('../methods/vn-user/sign-in')(Self);
require('../methods/vn-user/acl')(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/validate-auth')(Self);
require('../methods/vn-user/renew-token')(Self);
@ -124,20 +123,42 @@ module.exports = function(Self) {
return email.send();
});
Self.signInValidate = (user, userToken) => {
/**
* Sign-in validate
* @param {String} user The user
* @param {Object} userToken Options
* @param {Object} token accessToken
* @param {Object} ctx context
*/
Self.signInValidate = async(user, userToken, token, ctx) => {
const [[key, value]] = Object.entries(Self.userUses(user));
if (userToken[key].toLowerCase().trim() !== value.toLowerCase().trim()) {
console.error('ERROR!!! - Signin with other user', userToken, user);
const isOwner = Self.rawSql(`SELECT ? = ? `, [userToken[key], value]);
await Self.app.models.SignInLog.create({
userName: user,
token: token.id,
userFk: userToken.id,
ip: ctx.req.ip,
owner: isOwner
});
if (!isOwner)
throw new UserError('Try again');
}
};
Self.validateLogin = async function(user, password) {
/**
* Validate login params
* @param {String} user The user
* @param {String} password
* @param {Object} ctx context
*/
Self.validateLogin = async function(user, password, ctx) {
const loginInfo = Object.assign({password}, Self.userUses(user));
const token = await Self.login(loginInfo, 'user');
const userToken = await token.user.get();
Self.signInValidate(user, userToken);
if (ctx)
await Self.signInValidate(user, userToken, token, ctx);
try {
await Self.app.models.Account.sync(userToken.name, password);
@ -187,8 +208,8 @@ module.exports = function(Self) {
};
Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls =
Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls
.filter(acl => acl.property != 'changePassword');
Self.sharedClass._methods.find(method => method.name == 'changePassword').ctor.settings.acls
.filter(acl => acl.property != 'changePassword');
Self.userSecurity = async(ctx, userId, options) => {
const models = Self.app.models;
@ -226,10 +247,12 @@ module.exports = function(Self) {
const env = process.env.NODE_ENV;
const liliumUrl = await Self.app.models.Url.findOne({
where: {and: [
{appName: 'lilium'},
{environment: env}
]}
where: {
and: [
{appName: 'lilium'},
{environment: env}
]
}
});
class Mailer {

View File

@ -104,13 +104,6 @@
"permission": "ALLOW"
},
{
"property": "validateToken",
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW"
},
{
"property": "validateAuth",
"accessType": "EXECUTE",
"principalType": "ROLE",

View File

@ -7,6 +7,10 @@ process.on('warning', warning => {
console.log(warning.stack);
});
process.on('SIGUSR2', async() => {
if (container) await container.rm();
});
process.on('exit', async function() {
if (container) await container.rm();
});

View File

@ -118,13 +118,13 @@ BEGIN
SELECT 'UPDATE', account.myUser_getId(), ti.id, CONCAT('Crea factura ', vNewRef)
FROM tmp.ticketToInvoice ti;
CALL invoiceExpenceMake(vNewInvoiceId);
CALL invoiceExpenseMake(vNewInvoiceId);
CALL invoiceTaxMake(vNewInvoiceId,vTaxArea);
UPDATE invoiceOut io
JOIN (
SELECT SUM(amount) AS total
FROM invoiceOutExpence
FROM invoiceOutExpense
WHERE invoiceOutFk = vNewInvoiceId
) base
JOIN (
@ -166,18 +166,18 @@ BEGIN
SET @vTaxableBaseServices := 0.00;
SET @vTaxCodeGeneral := NULL;
INSERT INTO vn.invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
SELECT vNewInvoiceInId, @vTaxableBaseServices, sub.expenceFk, sub.taxTypeSageFk , sub.transactionTypeSageFk
INSERT INTO vn.invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk)
SELECT vNewInvoiceInId, @vTaxableBaseServices, sub.expenseFk, sub.taxTypeSageFk , sub.transactionTypeSageFk
FROM (
SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase, i.expenceFk, i.taxTypeSageFk , i.transactionTypeSageFk, @vTaxCodeGeneral := i.taxClassCodeFk
SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase, i.expenseFk, i.taxTypeSageFk , i.transactionTypeSageFk, @vTaxCodeGeneral := i.taxClassCodeFk
FROM tmp.ticketServiceTax tst
JOIN vn.invoiceOutTaxConfig i ON i.taxClassCodeFk = tst.code
WHERE i.isService
HAVING taxableBase
) sub;
INSERT INTO vn.invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
SELECT vNewInvoiceInId, SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral, @vTaxableBaseServices, 0) taxableBase, i.expenceFk, i.taxTypeSageFk , i.transactionTypeSageFk
INSERT INTO vn.invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk)
SELECT vNewInvoiceInId, SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral, @vTaxableBaseServices, 0) taxableBase, i.expenseFk, i.taxTypeSageFk , i.transactionTypeSageFk
FROM tmp.ticketTax tt
JOIN vn.invoiceOutTaxConfig i ON i.taxClassCodeFk = tt.code
WHERE !i.isService

View File

@ -139,13 +139,13 @@ BEGIN
SELECT 'UPDATE', account.myUser_getId(), ti.id, CONCAT('Crea factura ', vNewRef)
FROM tmp.ticketToInvoice ti;
CALL invoiceExpenceMake(vNewInvoiceId);
CALL invoiceExpenseMake(vNewInvoiceId);
CALL invoiceTaxMake(vNewInvoiceId,vTaxArea);
UPDATE invoiceOut io
JOIN (
SELECT SUM(amount) total
FROM invoiceOutExpence
FROM invoiceOutExpense
WHERE invoiceOutFk = vNewInvoiceId
) base
JOIN (
@ -182,15 +182,15 @@ BEGIN
SET @vTaxableBaseServices := 0.00;
SET @vTaxCodeGeneral := NULL;
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk)
SELECT vNewInvoiceInFk,
@vTaxableBaseServices,
sub.expenceFk,
sub.expenseFk,
sub.taxTypeSageFk,
sub.transactionTypeSageFk
FROM (
SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase,
i.expenceFk,
i.expenseFk,
i.taxTypeSageFk,
i.transactionTypeSageFk,
@vTaxCodeGeneral := i.taxClassCodeFk
@ -200,11 +200,11 @@ BEGIN
HAVING taxableBase
) sub;
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk)
SELECT vNewInvoiceInFk,
SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral,
@vTaxableBaseServices, 0) taxableBase,
i.expenceFk,
i.expenseFk,
i.taxTypeSageFk ,
i.transactionTypeSageFk
FROM tmp.ticketTax tt

View File

@ -135,13 +135,13 @@ BEGIN
INSERT INTO ticketTracking(stateFk,ticketFk,workerFk)
SELECT * FROM tmp.updateInter;
CALL invoiceExpenceMake(vNewInvoiceId);
CALL invoiceExpenseMake(vNewInvoiceId);
CALL invoiceTaxMake(vNewInvoiceId,vTaxArea);
UPDATE invoiceOut io
JOIN (
SELECT SUM(amount) total
FROM invoiceOutExpence
FROM invoiceOutExpense
WHERE invoiceOutFk = vNewInvoiceId
) base
JOIN (
@ -178,15 +178,15 @@ BEGIN
SET @vTaxableBaseServices := 0.00;
SET @vTaxCodeGeneral := NULL;
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk)
SELECT vNewInvoiceInFk,
@vTaxableBaseServices,
sub.expenceFk,
sub.expenseFk,
sub.taxTypeSageFk,
sub.transactionTypeSageFk
FROM (
SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase,
i.expenceFk,
i.expenseFk,
i.taxTypeSageFk,
i.transactionTypeSageFk,
@vTaxCodeGeneral := i.taxClassCodeFk
@ -196,11 +196,11 @@ BEGIN
HAVING taxableBase
) sub;
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk)
SELECT vNewInvoiceInFk,
SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral,
@vTaxableBaseServices, 0) taxableBase,
i.expenceFk,
i.expenseFk,
i.taxTypeSageFk ,
i.transactionTypeSageFk
FROM tmp.ticketTax tt

View File

@ -0,0 +1,4 @@
-- Auto-generated SQL script #202311061003
UPDATE salix.accessTokenConfig
SET courtesyTime=60
WHERE id=1;

View File

@ -1,5 +1,4 @@
--
-- Table structure for table `signInLog`
-- Description: log to debug cross-login error
@ -13,7 +12,9 @@ CREATE TABLE `account`.`signInLog` (
`token` varchar(255) NOT NULL ,
`userFk` int(10) unsigned DEFAULT NULL,
`creationDate` timestamp NULL DEFAULT current_timestamp(),
`userName` varchar(30) NOT NULL,
`ip` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`owner` tinyint(1) DEFAULT 1,
KEY `userFk` (`userFk`),
CONSTRAINT `signInLog_ibfk_1` FOREIGN KEY (`userFk`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);

View File

@ -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';

View File

View File

@ -0,0 +1 @@
ALTER TABLE `vn`.`ticketTracking` CHANGE `workerFk` `userFk` int(10) unsigned DEFAULT NULL NULL;

View File

@ -0,0 +1,4 @@
RENAME TABLE `vn`.`clientCreditLimit` TO `vn`.`roleCreditLimit`;
ALTER TABLE `vn`.`clientCreditLimit` 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;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn`.`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 (
(
`vn`.`ticketLastState` `tls`
JOIN `vn`.`ticketTracking` `tt` ON(`tt`.`id` = `tls`.`ticketTrackingFk`)
)
JOIN `vn`.`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
ALGORITHM = UNDEFINED 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`());

View File

@ -1,3 +1,7 @@
CREATE ROLE 'salix';
GRANT 'salix' TO 'root'@'%';
SET DEFAULT ROLE 'salix' FOR 'root'@'%';
CREATE SCHEMA IF NOT EXISTS `vn2008`;
CREATE SCHEMA IF NOT EXISTS `tmp`;
@ -362,7 +366,7 @@ INSERT INTO `vn`.`contactChannel`(`id`, `name`)
INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city`,`postcode`,`phone`,`mobile`,`isRelevant`,`email`,`iban`,`dueDay`,`accountingAccount`,`isEqualizated`,`provinceFk`,`hasToInvoice`,`credit`,`countryFk`,`isActive`,`gestdocFk`,`quality`,`payMethodFk`,`created`,`isToBeMailed`,`contactChannelFk`,`hasSepaVnl`,`hasCoreVnl`,`hasCoreVnh`,`riskCalculated`,`clientTypeFk`, `hasToInvoiceByAddress`,`isTaxDataChecked`,`isFreezed`,`creditInsurance`,`isCreatedAsServed`,`hasInvoiceSimplified`,`salesPersonFk`,`isVies`,`eypbc`, `businessTypeFk`,`typeFk`)
VALUES
(1101, 'Bruce Wayne', '84612325V', 'BATMAN', 'Alfred', '1007 MOUNTAIN DRIVE, GOTHAM', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist','loses'),
(1101, 'Bruce Wayne', '84612325V', 'BATMAN', 'Alfred', '1007 MOUNTAIN DRIVE, GOTHAM', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist','normal'),
(1102, 'Petter Parker', '87945234L', 'SPIDER MAN', 'Aunt May', '20 INGRAM STREET, QUEENS, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist','normal'),
(1103, 'Clark Kent', '06815934E', 'SUPER MAN', 'lois lane', '344 CLINTON STREET, APARTAMENT 3-D', 'Gotham', 46460, 1111111111, 222222222, 1, 'ClarkKent@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 0, 19, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist','normal'),
(1104, 'Tony Stark', '06089160W', 'IRON MAN', 'Pepper Potts', '10880 MALIBU POINT, 90265', 'Gotham', 46460, 1111111111, 222222222, 1, 'TonyStark@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist','normal'),
@ -372,8 +376,8 @@ INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city
(1108, 'Charles Xavier', '22641921P', 'PROFESSOR X', 'Beast', '3800 VICTORY PKWY, CINCINNATI, OH 45207, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 5, 1, 300, 13, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1, 'florist','normal'),
(1109, 'Bruce Banner', '16104829E', 'HULK', 'Black widow', 'SOMEWHERE IN NEW YORK', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, 9, 0, 1, 'florist','normal'),
(1110, 'Jessica Jones', '58282869H', 'JESSICA JONES', 'Luke Cage', 'NYCC 2015 POSTER', 'Gotham', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, NULL, 0, 1, 'florist','normal'),
(1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','normal'),
(1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','normal');
(1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','loses'),
(1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','loses');
INSERT INTO `vn`.`client`(`id`, `name`, `fi`, `socialName`, `contact`, `street`, `city`, `postcode`, `isRelevant`, `email`, `iban`,`dueDay`,`accountingAccount`, `isEqualizated`, `provinceFk`, `hasToInvoice`, `credit`, `countryFk`, `isActive`, `gestdocFk`, `quality`, `payMethodFk`,`created`, `isTaxDataChecked`)
SELECT id, name, CONCAT(RPAD(CONCAT(id,9),8,id),'A'), CONCAT(name, 'Social'), CONCAT(name, 'Contact'), CONCAT(name, 'Street'), 'GOTHAM', 46460, 1, CONCAT(name,'@mydomain.com'), NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5, util.VN_CURDATE(), 1
@ -489,7 +493,7 @@ INSERT INTO `vn`.`clientCredit`(`clientFk`, `workerFk`, `amount`, `created`)
(1104, 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
(1, 9999999, 20),
(2, 10000, 21),
@ -630,7 +634,7 @@ INSERT INTO `vn`.`invoiceOutTax` (`invoiceOutFk`, `taxableBase`, `vat`, `pgcFk`)
(4, 8.07, 0.81, 4770000010),
(5, 8.07, 0.81, 4770000010);
INSERT INTO `vn`.`expence`(`id`, `name`, `isWithheld`)
INSERT INTO `vn`.`expense`(`id`, `name`, `isWithheld`)
VALUES
(2000000000, 'Inmovilizado pendiente', 0),
(2000000001, 'Compra de bienes de inmovilizado', 0),
@ -642,7 +646,7 @@ INSERT INTO `vn`.`expence`(`id`, `name`, `isWithheld`)
(7050000000, 'Prestacion de servicios', 1);
INSERT INTO `vn`.`invoiceOutExpence`(`id`, `invoiceOutFk`, `amount`, `expenceFk`, `created`)
INSERT INTO `vn`.`invoiceOutExpense`(`id`, `invoiceOutFk`, `amount`, `expenseFk`, `created`)
VALUES
(1, 1, 813.06, 2000000000, util.VN_CURDATE()),
(2, 1, 33.80, 4751000000, util.VN_CURDATE()),
@ -767,7 +771,7 @@ INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `des
-- FIX for state hours on local, inter_afterInsert
-- 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
(1, 16, 5 , DATE_ADD(util.VN_NOW(), INTERVAL -1 MONTH)),
(2, 16, 5 , DATE_ADD(util.VN_NOW(), INTERVAL -1 MONTH)),
@ -811,6 +815,7 @@ INSERT INTO `vn`.`config`(`id`, `mdbServer`, `fakeEmail`, `defaultersMaxAmount`,
VALUES
(1, 'beta-server', 'nightmare@mydomain.com', '200', DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH));
INSERT INTO `vn`.`greugeType`(`id`, `name`, `code`)
VALUES
(1, 'Diff', 'diff'),
@ -922,7 +927,7 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`)
('SER', 'Services'),
('VT', 'Sales');
INSERT INTO `vn`.`item`(`id`, `typeFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`,
INSERT INTO `vn`.`item`(`id`, `typeFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenseFk`,
`comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`, `genericFk`, `itemPackingTypeFk`, `hasMinPrice`, `packingShelve`, `weightByPiece`)
VALUES
(1, 2, 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'EMB', 0, NULL, 'V', 0, 15,3),
@ -1939,7 +1944,7 @@ INSERT INTO `vn`.`ticketRequest`(`id`, `description`, `requesterFk`, `attenderFk
(4, 'Melee weapon combat first 15cm', 18, 35, 15, NULL, 1.30, NULL, NULL, 11, util.VN_CURDATE()),
(5, 'Melee weapon combat first 15cm', 18, 35, 15, 4, 1.30, 0, NULL, 18, util.VN_CURDATE());
INSERT INTO `vn`.`ticketServiceType`(`id`, `name`, `expenceFk`)
INSERT INTO `vn`.`ticketServiceType`(`id`, `name`, `expenseFk`)
VALUES
(1, 'Porte Agencia', 7001000000),
(2, 'Portes Retorno', 7001000000),
@ -2343,9 +2348,11 @@ INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `weekDays`)
(8, 'indefinitely', 'mon,tue,wed,thu,fri,sat,sun'),
(10, 'indefinitely', 'mon,tue,wed,thu,fri,sat,sun');
INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `started`, `ended`)
INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `started`, `ended`, `weekDays`)
VALUES
(9, 'range', DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR), DATE_ADD(util.VN_CURDATE(), INTERVAL +1 YEAR));
(9, 'range', DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR), DATE_ADD(util.VN_CURDATE(), INTERVAL +1 YEAR), 'mon'),
(9, 'range', util.VN_CURDATE(), NULL, 'tue'),
(9, 'range', NULL, util.VN_CURDATE(), 'wed');
INSERT INTO `vn`.`workerTimeControl`(`userFk`, `timed`, `manual`, `direction`, `isSendMail`)
VALUES
@ -2561,7 +2568,7 @@ INSERT INTO `vn`.`duaInvoiceIn`(`id`, `duaFk`, `invoiceInFk`)
(9, 9, 9),
(10, 10, 10);
INSERT INTO `vn`.`invoiceInTax` (`invoiceInFk`, `taxableBase`, `expenceFk`, `foreignValue`, `taxTypeSageFk`, `transactionTypeSageFk`)
INSERT INTO `vn`.`invoiceInTax` (`invoiceInFk`, `taxableBase`, `expenseFk`, `foreignValue`, `taxTypeSageFk`, `transactionTypeSageFk`)
VALUES
(1, 99.99, '2000000000', NULL, NULL, NULL),
(2, 999.99, '2000000000', NULL, NULL, NULL),
@ -2960,9 +2967,9 @@ INSERT INTO `vn`.`wagonTypeTray` (`id`, `typeFk`, `height`, `colorFk`)
(2, 1, 50, 2),
(3, 1, 0, 3);
INSERT INTO `salix`.`accessTokenConfig` (`id`, `renewPeriod`, `renewInterval`)
INSERT INTO `salix`.`accessTokenConfig` (`id`, `renewPeriod`, `courtesyTime`, `renewInterval`)
VALUES
(1, 21600, 300);
(1, 21600, 60, 300);
INSERT INTO `vn`.`travelConfig` (`id`, `warehouseInFk`, `warehouseOutFk`, `agencyFk`, `companyFk`)
VALUES

View File

@ -9692,7 +9692,7 @@ proc: BEGIN
`name`,
longName,
subName,
expenceFk,
expenseFk,
typeFk,
intrastatFk,
originFk,
@ -10080,7 +10080,7 @@ BEGIN
`name`,
longName,
subName,
expenceFk,
expenseFk,
typeFk,
intrastatFk,
originFk,
@ -17338,7 +17338,7 @@ BEGIN
JOIN vn.XDiario x ON x.id = mci.id
JOIN vn.supplier s ON s.id = supplierFk
JOIN vn.invoiceInTax iit ON iit.invoiceInFk = ii.id
JOIN vn.expence e ON e.id = iit.expenceFk
JOIN vn.expense e ON e.id = iit.expenseFk
JOIN TiposRetencion t ON t.CodigoRetencion = ii.withholdingSageFk
LEFT JOIN tmp.invoiceDua id ON id.id = mci.id
JOIN (SELECT SUM(x2.BASEEURO) taxableBase, SUM(x2.EURODEBE) taxBase
@ -17441,7 +17441,7 @@ BEGIN
i.serial COLLATE utf8mb3_unicode_ci serial,
i.supplierFk,
i.issued,
IF(expenceFkDeductible, FALSE, i.isVatDeductible) isVatDeductible,
IF(expenseFkDeductible, FALSE, i.isVatDeductible) isVatDeductible,
IF(c.code = 'EUR', '',c.`code`) currencyFk
FROM vn.invoiceIn i
JOIN vn.currency c ON c.id = i.currencyFk
@ -17949,7 +17949,7 @@ BEGIN
e.id accountFk,
UCASE(e.name),
''
FROM vn.expence e
FROM vn.expense e
UNION
SELECT company_getCode(vCompanyFk),
b.account,
@ -22010,7 +22010,7 @@ DROP TABLE IF EXISTS `agencyTermConfig`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `agencyTermConfig` (
`expenceFk` varchar(10) DEFAULT NULL,
`expenseFk` varchar(10) DEFAULT NULL,
`vatAccountSupported` varchar(15) DEFAULT NULL,
`vatPercentage` decimal(28,10) DEFAULT NULL,
`transaction` varchar(50) DEFAULT NULL
@ -29097,19 +29097,19 @@ SET character_set_client = utf8;
SET character_set_client = @saved_cs_client;
--
-- Table structure for table `expence`
-- Table structure for table `expense`
--
DROP TABLE IF EXISTS `expence`;
DROP TABLE IF EXISTS `expense`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `expence` (
CREATE TABLE `expense` (
`id` varchar(10) NOT NULL,
`name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT NULL,
`isWithheld` tinyint(4) NOT NULL DEFAULT 0,
`code` varchar(25) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `expence_UN` (`code`)
UNIQUE KEY `expense_UN` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
@ -29862,7 +29862,7 @@ CREATE TABLE `invoiceIn` (
`bookEntried` date DEFAULT NULL COMMENT 'Fecha Asiento',
`isVatDeductible` tinyint(1) NOT NULL DEFAULT 1,
`withholdingSageFk` smallint(6) DEFAULT NULL COMMENT 'Tipos de retención SAGE',
`expenceFkDeductible` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
`expenseFkDeductible` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
`editorFk` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `proveedor_id` (`supplierFk`),
@ -29877,12 +29877,12 @@ CREATE TABLE `invoiceIn` (
KEY `recibida_ibfk_6` (`cplusRectificationTypeFk`),
KEY `recibida_ibfk_7` (`siiTrascendencyInvoiceInFk`),
KEY `invoiceIn_withholdingFk_idx` (`withholdingSageFk`),
KEY `invoiceIn_expenceFkDeductible_idx` (`expenceFkDeductible`),
KEY `invoiceIn_expenseFkDeductible_idx` (`expenseFkDeductible`),
KEY `invoiceIn_fk_editor` (`editorFk`),
KEY `invoiceIn_FK` (`currencyFk`),
CONSTRAINT `invoiceInCompany_Fk` FOREIGN KEY (`companyFk`) REFERENCES `company` (`id`) ON UPDATE CASCADE,
CONSTRAINT `invoiceIn_FK` FOREIGN KEY (`currencyFk`) REFERENCES `currency` (`id`) ON UPDATE CASCADE,
CONSTRAINT `invoiceIn_expenceFkDeductible` FOREIGN KEY (`expenceFkDeductible`) REFERENCES `expence` (`id`) ON UPDATE CASCADE,
CONSTRAINT `invoiceIn_expenseFkDeductible` FOREIGN KEY (`expenseFkDeductible`) REFERENCES `expense` (`id`) ON UPDATE CASCADE,
CONSTRAINT `invoiceIn_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`),
CONSTRAINT `invoiceIn_ibfk_3` FOREIGN KEY (`cplusSubjectOpFk`) REFERENCES `cplusSubjectOp` (`id`) ON UPDATE CASCADE,
CONSTRAINT `invoiceIn_ibfk_4` FOREIGN KEY (`cplusTaxBreakFk`) REFERENCES `cplusTaxBreak` (`id`) ON UPDATE CASCADE,
@ -30283,7 +30283,7 @@ CREATE TABLE `invoiceInSage` (
`taxTypeSageFk` smallint(6) NOT NULL,
`transactionTypeSageFk` tinyint(4) NOT NULL,
`isService` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Para diferenciar producto de servicio',
`expenceFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`expenseFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`withholdingSageFk` smallint(6) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `invoiceInSafe_unique` (`taxClassFk`,`invoiceInSerialFk`,`isService`,`withholdingSageFk`),
@ -30292,8 +30292,8 @@ CREATE TABLE `invoiceInSage` (
KEY `invoiceInSage_invoiceInSerialFk` (`invoiceInSerialFk`),
KEY `invoiceInSage_taxTypeSageFk` (`taxTypeSageFk`),
KEY `invoiceInSage_transactionTypeSageFk` (`transactionTypeSageFk`),
KEY `invoiceInSage_idx` (`expenceFk`),
CONSTRAINT `invoiceInSage_expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `expence` (`id`) ON UPDATE CASCADE,
KEY `invoiceInSage_idx` (`expenseFk`),
CONSTRAINT `invoiceInSage_expenseFk` FOREIGN KEY (`expenseFk`) REFERENCES `expense` (`id`) ON UPDATE CASCADE,
CONSTRAINT `invoiceInSage_invoiceInSerialFk` FOREIGN KEY (`invoiceInSerialFk`) REFERENCES `invoiceInSerial` (`code`) ON UPDATE CASCADE,
CONSTRAINT `invoiceInSage_taxClassFk` FOREIGN KEY (`taxClassFk`) REFERENCES `taxClass` (`code`) ON UPDATE CASCADE,
CONSTRAINT `invoiceInSage_taxTypeSageFk` FOREIGN KEY (`taxTypeSageFk`) REFERENCES `sage`.`TiposIva` (`CodigoIva`) ON UPDATE CASCADE,
@ -30334,7 +30334,7 @@ CREATE TABLE `invoiceInTax` (
`invoiceInFk` mediumint(8) unsigned NOT NULL,
`taxCodeFk` int(10) DEFAULT NULL,
`taxableBase` decimal(10,2) NOT NULL,
`expenceFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`expenseFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`foreignValue` decimal(10,2) DEFAULT NULL,
`taxTypeSageFk` smallint(6) DEFAULT NULL COMMENT 'Tipo de IVA SAGE',
`transactionTypeSageFk` tinyint(4) DEFAULT NULL COMMENT 'Tipo de transacción SAGE',
@ -30345,9 +30345,9 @@ CREATE TABLE `invoiceInTax` (
KEY `recibida_iva_ibfk_2` (`taxCodeFk`),
KEY `recibida_iva_taxTypeSageFk` (`taxTypeSageFk`),
KEY `invoiceInTax_transactionTypeSageFk_idx` (`transactionTypeSageFk`),
KEY `invoiceInTax_idx` (`expenceFk`),
KEY `invoiceInTax_idx` (`expenseFk`),
KEY `invoiceInTax_fk_editor` (`editorFk`),
CONSTRAINT `invoiceInTax_expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `expence` (`id`) ON UPDATE CASCADE,
CONSTRAINT `invoiceInTax_expenseFk` FOREIGN KEY (`expenseFk`) REFERENCES `expense` (`id`) ON UPDATE CASCADE,
CONSTRAINT `invoiceInTax_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`),
CONSTRAINT `invoiceInTax_ibfk_5` FOREIGN KEY (`invoiceInFk`) REFERENCES `invoiceIn` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `invoiceInTax_transactionTypeSageFk` FOREIGN KEY (`transactionTypeSageFk`) REFERENCES `sage`.`TiposTransacciones` (`CodigoTransaccion`) ON UPDATE CASCADE,
@ -30615,23 +30615,23 @@ CREATE TABLE `invoiceOutConfig` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `invoiceOutExpence`
-- Table structure for table `invoiceOutExpense`
--
DROP TABLE IF EXISTS `invoiceOutExpence`;
DROP TABLE IF EXISTS `invoiceOutExpense`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `invoiceOutExpence` (
CREATE TABLE `invoiceOutExpense` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`invoiceOutFk` int(10) unsigned NOT NULL,
`amount` decimal(10,2) NOT NULL DEFAULT 0.00,
`expenceFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`expenseFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`created` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `invoiceOutExpence_FK_1_idx` (`invoiceOutFk`),
KEY `invoiceOutExpence_expenceFk_idx` (`expenceFk`),
CONSTRAINT `invoiceOutExpence_FK_1` FOREIGN KEY (`invoiceOutFk`) REFERENCES `invoiceOut` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `invoiceOutExpence_expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `expence` (`id`) ON UPDATE CASCADE
KEY `invoiceOutExpense_FK_1_idx` (`invoiceOutFk`),
KEY `invoiceOutExpense_expenseFk_idx` (`expenseFk`),
CONSTRAINT `invoiceOutExpense_FK_1` FOREIGN KEY (`invoiceOutFk`) REFERENCES `invoiceOut` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `invoiceOutExpense_expenseFk` FOREIGN KEY (`expenseFk`) REFERENCES `expense` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Desglosa la base imponible de una factura en funcion del tipo de gasto/venta';
/*!40101 SET character_set_client = @saved_cs_client */;
@ -30694,7 +30694,7 @@ CREATE TABLE `invoiceOutTaxConfig` (
`taxTypeSageFk` smallint(6) DEFAULT NULL,
`transactionTypeSageFk` tinyint(4) DEFAULT NULL,
`isService` tinyint(1) DEFAULT 0,
`expenceFk` varchar(10) DEFAULT NULL,
`expenseFk` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `invoiceOutTaxConfig_FK` (`taxClassCodeFk`),
KEY `invoiceOutTaxConfig_FK_1` (`taxTypeSageFk`),
@ -30737,7 +30737,7 @@ CREATE TABLE `item` (
`description` varchar(1000) DEFAULT NULL,
`density` int(11) NOT NULL DEFAULT 167 COMMENT 'Almacena la densidad en kg/m3 para el calculo de los portes, si no se especifica se pone por defecto la del tipo en un trigger',
`relevancy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'La web ordena de forma descendiente por este campo para mostrar los artículos',
`expenceFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '7001000000',
`expenseFk` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '7001000000',
`isActive` tinyint(1) NOT NULL DEFAULT 1,
`longName` varchar(50) DEFAULT NULL,
`subName` varchar(50) DEFAULT NULL,
@ -30792,11 +30792,11 @@ CREATE TABLE `item` (
KEY `item_size_IDX` (`size`) USING BTREE,
KEY `item_size_IDX2` (`longName`) USING BTREE,
KEY `item_lastUsed_IDX` (`lastUsed`) USING BTREE,
KEY `item_expenceFk_idx` (`expenceFk`),
KEY `item_expenseFk_idx` (`expenseFk`),
KEY `item_fk_editor` (`editorFk`),
CONSTRAINT `item_FK` FOREIGN KEY (`genericFk`) REFERENCES `item` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `item_FK_1` FOREIGN KEY (`typeFk`) REFERENCES `itemType` (`id`),
CONSTRAINT `item_expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `expence` (`id`) ON UPDATE CASCADE,
CONSTRAINT `item_expenseFk` FOREIGN KEY (`expenseFk`) REFERENCES `expense` (`id`) ON UPDATE CASCADE,
CONSTRAINT `item_family` FOREIGN KEY (`family`) REFERENCES `itemFamily` (`code`) ON UPDATE CASCADE,
CONSTRAINT `item_fk_editor` FOREIGN KEY (`editorFk`) REFERENCES `account`.`user` (`id`),
CONSTRAINT `item_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `origin` (`id`) ON UPDATE CASCADE,
@ -40606,10 +40606,10 @@ DROP TABLE IF EXISTS `ticketServiceType`;
CREATE TABLE `ticketServiceType` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL,
`expenceFk` varchar(10) NOT NULL DEFAULT '7050000000',
`expenseFk` varchar(10) NOT NULL DEFAULT '7050000000',
PRIMARY KEY (`id`),
KEY `ticketServiceType_expenceFk_idx` (`expenceFk`),
CONSTRAINT `ticketServiceType_expenceFk` FOREIGN KEY (`expenceFk`) REFERENCES `expence` (`id`) ON UPDATE CASCADE
KEY `ticketServiceType_expenseFk_idx` (`expenseFk`),
CONSTRAINT `ticketServiceType_expenseFk` FOREIGN KEY (`expenseFk`) REFERENCES `expense` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDBDEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci COMMENT='Lista de los posibles servicios a elegir';
/*!40101 SET character_set_client = @saved_cs_client */;
@ -46533,7 +46533,7 @@ BEGIN
WHERE io.ref = vInvoiceRef
UNION ALL
SELECT ioe.amount
FROM invoiceOutExpence ioe
FROM invoiceOutExpense ioe
JOIN invoiceOut io ON io.id = ioe.invoiceOutFk
WHERE io.ref = vInvoiceRef
) t1;
@ -57741,7 +57741,7 @@ DELIMITER ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
/*!50003 DROP PROCEDURE IF EXISTS `invoiceExpenceMake` */;
/*!50003 DROP PROCEDURE IF EXISTS `invoiceExpenseMake` */;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -57749,28 +57749,28 @@ DELIMITER ;
/*!50003 SET character_set_results = utf8mb4 */ ;
/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceExpenceMake`(IN vInvoice INT)
CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceExpenseMake`(IN vInvoice INT)
BEGIN
/* Inserta las partidas de gasto correspondientes a la factura
* REQUIERE tabla tmp.ticketToInvoice
* @param vInvoice Numero de factura
*/
DELETE FROM invoiceOutExpence
DELETE FROM invoiceOutExpense
WHERE invoiceOutFk = vInvoice;
INSERT INTO invoiceOutExpence(invoiceOutFk, expenceFk, amount)
INSERT INTO invoiceOutExpense(invoiceOutFk, expenseFk, amount)
SELECT vInvoice,
expenceFk,
expenseFk,
SUM(ROUND(quantity * price * (100 - discount)/100,2)) amount
FROM tmp.ticketToInvoice t
JOIN sale s ON s.ticketFk = t.id
JOIN item i ON i.id = s.itemFk
GROUP BY i.expenceFk
GROUP BY i.expenseFk
HAVING amount != 0;
INSERT INTO invoiceOutExpence(invoiceOutFk, expenceFk, amount)
INSERT INTO invoiceOutExpense(invoiceOutFk, expenseFk, amount)
SELECT vInvoice,
tst.expenceFk,
tst.expenseFk,
SUM(ROUND(ts.quantity * ts.price ,2)) amount
FROM tmp.ticketToInvoice t
JOIN ticketService ts ON ts.ticketFk = t.id
@ -58125,7 +58125,7 @@ CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceInTax_getFromEntries`(IN vId
BEGIN
DECLARE vRate DOUBLE DEFAULT 1;
DECLARE vDated DATE;
DECLARE vExpenceFk VARCHAR(10);
DECLARE vExpenseFk VARCHAR(10);
SELECT MAX(rr.dated) INTO vDated
FROM referenceRate rr
@ -58139,8 +58139,8 @@ BEGIN
WHERE dated = vDated;
END IF;
SELECT id INTO vExpenceFk
FROM vn.expence
SELECT id INTO vExpenseFk
FROM vn.expense
WHERE `name` = 'Adquisición mercancia Extracomunitaria'
GROUP BY id
LIMIT 1;
@ -58148,10 +58148,10 @@ BEGIN
DELETE FROM invoiceInTax
WHERE invoiceInFk = vId;
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, foreignValue, taxTypeSageFk, transactionTypeSageFk)
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, foreignValue, taxTypeSageFk, transactionTypeSageFk)
SELECT ii.id,
SUM(b.buyingValue * b.quantity) / IFNULL(vRate,1) taxableBase,
vExpenceFk,
vExpenseFk,
IF(ii.currencyFk = 1,NULL,SUM(b.buyingValue * b.quantity )) divisa,
taxTypeSageFk,
transactionTypeSageFk
@ -58188,7 +58188,7 @@ BEGIN
SELECT ii.bookEntried,
iit.foreignValue,
ii.companyFk,
ii.expenceFkDeductible,
ii.expenseFkDeductible,
iit.taxableBase,
iit.transactionTypeSageFk,
ii.serial,
@ -58218,8 +58218,8 @@ BEGIN
cit.id invoicesCount,
e.code,
e.isWithheld,
e.id expenceFk,
e.name expenceName
e.id expenseFk,
e.name expenseName
FROM invoiceIn ii
JOIN supplier s ON s.id = ii.supplierFk
LEFT JOIN province p ON p.id = s.provinceFk
@ -58231,7 +58231,7 @@ BEGIN
JOIN siiTypeInvoiceIn cit ON cit.id = ii.siiTypeInvoiceInFk
LEFT JOIN invoiceInTax iit ON iit.invoiceInFk = ii.id
LEFT JOIN sage.TiposTransacciones ttr ON ttr.CodigoTransaccion = iit.transactionTypeSageFk
LEFT JOIN expence e ON e.id = iit.expenceFk
LEFT JOIN expense e ON e.id = iit.expenseFk
LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
LEFT JOIN sage.taxType tt ON tt.id = ti.CodigoIva
WHERE ii.id = vSelf;
@ -58286,7 +58286,7 @@ BEGIN
empresa_id)
SELECT vBookNumber ASIEN,
tii.bookEntried FECHA,
IF(tii.isWithheld, LPAD(RIGHT(tii.supplierAccount, 5), 10, tii.expenceFk),tii.expenceFk) SUBCTA,
IF(tii.isWithheld, LPAD(RIGHT(tii.supplierAccount, 5), 10, tii.expenseFk),tii.expenseFk) SUBCTA,
tii.supplierAccount CONTRA,
IF(tii.isWithheld AND tii.taxableBase < 0, NULL, ROUND(SUM(tii.taxableBase),2)) EURODEBE,
IF(tii.isWithheld AND tii.taxableBase < 0, ROUND(SUM(-tii.taxableBase), 2), NULL) EUROHABER,
@ -58301,7 +58301,7 @@ BEGIN
tii.companyFk empresa_id
FROM tInvoiceIn tii
WHERE tii.code IS NULL OR tii.code <> 'suplido'
GROUP BY tii.expenceFk;
GROUP BY tii.expenseFk;
-- Líneas de IVA
INSERT INTO XDiario(
@ -58335,11 +58335,11 @@ BEGIN
empresa_id)
SELECT vBookNumber ASIEN,
tii.bookEntried FECHA,
IF(tii.expenceFkDeductible>0, tii.expenceFkDeductible, tii.CuentaIvaSoportado) SUBCTA,
IF(tii.expenseFkDeductible>0, tii.expenseFkDeductible, tii.CuentaIvaSoportado) SUBCTA,
tii.supplierAccount CONTRA,
SUM(ROUND(tii.PorcentajeIva * tii.taxableBase / 100, 2)) EURODEBE,
SUM(tii.taxableBase) BASEEURO,
GROUP_CONCAT(DISTINCT tii.expenceName SEPARATOR ', ') CONCEPTO,
GROUP_CONCAT(DISTINCT tii.expenseName SEPARATOR ', ') CONCEPTO,
vSelf FACTURA,
tii.PorcentajeIva IVA,
IF(tii.isUeeMember AND eWithheld.id IS NULL, '', '*') AUXILIAR,
@ -58365,13 +58365,13 @@ BEGIN
LEFT JOIN (
SELECT e.id
FROM tInvoiceIn tii
JOIN expence e ON e.id = tii.expenceFk
JOIN expense e ON e.id = tii.expenseFk
WHERE e.isWithheld
LIMIT 1
) eWithheld ON TRUE
WHERE tii.taxTypeSageFk IS NOT NULL
AND (tii.taxCode IS NULL OR tii.taxCode NOT IN ('import10', 'import21'))
GROUP BY tii.PorcentajeIva, tii.expenceFk;
GROUP BY tii.PorcentajeIva, tii.expenseFk;
-- Línea iva inversor sujeto pasivo
INSERT INTO XDiario(
@ -58408,7 +58408,7 @@ BEGIN
tii.supplierAccount CONTRA,
SUM(ROUND(tii.PorcentajeIva * tii.taxableBase / 100,2)) EUROHABER,
ROUND(SUM(tii.taxableBase),2) BASEEURO,
GROUP_CONCAT(DISTINCT tii.expenceName SEPARATOR ', ') CONCEPTO,
GROUP_CONCAT(DISTINCT tii.expenseName SEPARATOR ', ') CONCEPTO,
vSelf FACTURA,
tii.PorcentajeIva IVA,
'*' AUXILIAR,
@ -58436,7 +58436,7 @@ BEGIN
AND NOT(tii.isVies
AND c.nontaxableTransactionTypeFk = tii.transactionTypeSageFk
AND tii.taxCode = 'nonTaxable')
GROUP BY tii.PorcentajeIva, tii.expenceFk;
GROUP BY tii.PorcentajeIva, tii.expenseFk;
-- Actualización del registro original
UPDATE invoiceIn ii
@ -58509,14 +58509,14 @@ BEGIN
FROM ticket
WHERE refFk = vInvoiceRef;
CALL invoiceExpenceMake(vInvoiceFk);
CALL invoiceExpenseMake(vInvoiceFk);
CALL invoiceTaxMake(vInvoiceFk,vTaxArea);
UPDATE invoiceOut io
JOIN (
SELECT SUM(amount) AS total
FROM invoiceOutExpence
FROM invoiceOutExpense
WHERE invoiceOutFk = vInvoiceFk
) base
JOIN (
@ -58552,7 +58552,7 @@ BEGIN
* param vInvoice factura_id
*/
DECLARE vBookNumber INT;
DECLARE vExpenceConcept VARCHAR(50);
DECLARE vExpenseConcept VARCHAR(50);
DECLARE vSpainCountryFk INT;
DECLARE vOldBookNumber INT;
@ -58644,7 +58644,7 @@ BEGIN
SELECT
vBookNumber AS ASIEN,
rs.FECHA,
ioe.expenceFk AS SUBCTA,
ioe.expenseFk AS SUBCTA,
rs.clientBookingAccount AS CONTRA,
ioe.amount AS EUROHABER,
rs.Concept AS CONCEPTO,
@ -58652,13 +58652,13 @@ BEGIN
rs.FECHA_OP,
rs.companyFk AS empresa_id
FROM rs
JOIN invoiceOutExpence ioe
JOIN invoiceOutExpense ioe
WHERE ioe.invoiceOutFk = vInvoice;
SELECT GROUP_CONCAT(`name` SEPARATOR ',')
INTO vExpenceConcept
FROM expence e
JOIN invoiceOutExpence ioe ON ioe.expenceFk = e.id
INTO vExpenseConcept
FROM expense e
JOIN invoiceOutExpense ioe ON ioe.expenseFk = e.id
WHERE ioe.invoiceOutFk = vInvoice;
-- Lineas de IVA
@ -58701,7 +58701,7 @@ BEGIN
rs.clientBookingAccount AS CONTRA,
iot.vat AS EUROHABER,
iot.taxableBase AS BASEEURO,
CONCAT(vExpenceConcept,' : ',rs.Concept) AS CONCEPTO,
CONCAT(vExpenseConcept,' : ',rs.Concept) AS CONCEPTO,
rs.invoiceNum AS FACTURA,
IF(pe2.equFk,0,pgc.rate) AS IVA,
IF(pe2.equFk,0,pgce.rate) AS RECEQUIV,
@ -58844,7 +58844,7 @@ DELIMITER ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
/*!50003 DROP PROCEDURE IF EXISTS `invoiceOutTaxAndExpence` */;
/*!50003 DROP PROCEDURE IF EXISTS `invoiceOutTaxAndExpense` */;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
@ -58852,7 +58852,7 @@ DELIMITER ;
/*!50003 SET character_set_results = utf8mb4 */ ;
/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceOutTaxAndExpence`()
CREATE DEFINER=`root`@`localhost` PROCEDURE `invoiceOutTaxAndExpense`()
BEGIN
/* Para tickets ya facturados, vuelve a repetir el proceso de facturación.
@ -58906,7 +58906,7 @@ BEGIN
FROM ticket
WHERE refFk = vInvoiceRef;
CALL invoiceExpenceMake(vInvoice);
CALL invoiceExpenseMake(vInvoice);
CALL invoiceTaxMake(vInvoice,vCountry,vTaxArea);
FETCH rs INTO vInvoice ,vInvoiceRef;
@ -59140,13 +59140,13 @@ BEGIN
INSERT INTO ticketTracking(stateFk,ticketFk,workerFk)
SELECT * FROM tmp.updateInter;
CALL invoiceExpenceMake(vNewInvoiceId);
CALL invoiceExpenseMake(vNewInvoiceId);
CALL invoiceTaxMake(vNewInvoiceId,vTaxArea);
UPDATE invoiceOut io
JOIN (
SELECT SUM(amount) total
FROM invoiceOutExpence
FROM invoiceOutExpense
WHERE invoiceOutFk = vNewInvoiceId
) base
JOIN (
@ -59183,15 +59183,15 @@ BEGIN
SET @vTaxableBaseServices := 0.00;
SET @vTaxCodeGeneral := NULL;
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk)
SELECT vNewInvoiceInFk,
@vTaxableBaseServices,
sub.expenceFk,
sub.expenseFk,
sub.taxTypeSageFk,
sub.transactionTypeSageFk
FROM (
SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase,
i.expenceFk,
i.expenseFk,
i.taxTypeSageFk,
i.transactionTypeSageFk,
@vTaxCodeGeneral := i.taxClassCodeFk
@ -59201,11 +59201,11 @@ BEGIN
HAVING taxableBase
) sub;
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenseFk, taxTypeSageFk, transactionTypeSageFk)
SELECT vNewInvoiceInFk,
SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral,
@vTaxableBaseServices, 0) taxableBase,
i.expenceFk,
i.expenseFk,
i.taxTypeSageFk ,
i.transactionTypeSageFk
FROM tmp.ticketTax tt

View File

@ -26,7 +26,7 @@ describe('Route create path', () => {
await page.waitToClick(selectors.createRouteView.submitButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Access denied');
expect(message.text).toContain('Access Denied');
});
});

View File

@ -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
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
Access denied: Access denied
Access Denied: Access Denied

View File

@ -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
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
Access denied: Acción no permitida
Access Denied: Acción no permitida
Direction not found: Dirección no encontrada

View File

@ -82,7 +82,7 @@ export default class Token {
if (!data) return;
this.renewPeriod = data.renewPeriod;
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;
this.set(token.id, now, token.ttl, this.remember);
})
.catch(res => {
if (res.data?.error?.code !== 'periodNotExceeded')
throw res;
})
.finally(() => {
this.checking = false;
});
}
stopRenewer() {
clearInterval(this.inservalId);
clearInterval(this.intervalId);
}
}
Token.$inject = ['vnInterceptor', '$http', '$rootScope'];

View File

@ -18,6 +18,7 @@ Show summary: Mostrar vista previa
What is new: Novedades de la versión
Settings: Ajustes
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
# Actions

View File

@ -120,7 +120,7 @@ function $exceptionHandler(vnApp, $window, $state, $injector) {
messageT = 'Invalid login';
break;
case 403:
messageT = 'Access denied';
messageT = exception.data?.error?.message || 'Access Denied';
break;
case 502:
messageT = 'It seems that the server has fall down';

View File

@ -199,5 +199,6 @@
"You can only add negative amounts in refund tickets": "You can only add negative amounts in refund tickets",
"Try again": "Try again",
"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}}"
}

View File

@ -328,5 +328,6 @@
"User disabled": "Usuario desactivado",
"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",
"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}}"
}

View File

@ -1,6 +1,5 @@
module.exports = () => {
Date.vnUTC = () => {
const env = process.env.NODE_ENV;
Date.vnUTC = (env = process.env.NODE_ENV) => {
if (!env || env === 'development')
return new Date(Date.UTC(2001, 0, 1, 11));

View File

@ -39,7 +39,7 @@
"./middleware/salix-version": {}
},
"parse": {
"body-parser#json":{}
"body-parser#json":{}
},
"routes": {
"loopback#rest": {

View File

@ -1,3 +1,4 @@
const NotFoundError = require('vn-loopback/util/not-found-error');
module.exports = Self => {
Self.remoteMethod('test', {
@ -9,7 +10,8 @@ module.exports = Self => {
});
Self.test = async function() {
let connector = await Self.getSynchronizer();
const connector = await Self.getLinker();
if (!connector) throw new NotFoundError('Linker not configured');
await connector.test();
};
};

View File

@ -2,7 +2,7 @@ const {models} = require('vn-loopback/server/server');
describe('account changePassword()', () => {
const userId = 70;
const unauthCtx = {
const unAuthCtx = {
req: {
headers: {},
connection: {
@ -79,7 +79,7 @@ describe('account changePassword()', () => {
passExpired: yesterday
}
, options);
await models.VnUser.signIn(unauthCtx, 'trainee', 'nightmare', options);
await models.VnUser.signIn(unAuthCtx, 'trainee', 'nightmare', options);
} catch (e) {
if (e.message != 'Pass expired')
throw e;

View File

@ -26,24 +26,46 @@ module.exports = Self => {
});
Self.sync = async function(userName, password, force, options) {
const models = Self.app.models;
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
const models = Self.app.models;
const user = await models.VnUser.findOne({
fields: ['id', 'password'],
where: {name: userName}
}, myOptions);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
};
if (user && password && !await user.hasPassword(password))
throw new ForbiddenError('Wrong password');
try {
const user = await models.VnUser.findOne({
fields: ['id', 'password'],
where: {name: userName}
}, myOptions);
const isSync = !await models.UserSync.exists(userName, myOptions);
if (user && password && !await user.hasPassword(password))
throw new ForbiddenError('Wrong password');
if (!force && isSync && user) return;
await models.AccountConfig.syncUser(userName, password);
await models.UserSync.destroyById(userName, myOptions);
const isSync = !await models.UserSync.exists(userName, myOptions);
if (!force && isSync && user) {
if (tx) await tx.rollback();
return;
}
await Self.rawSql(`
SELECT id
FROM account.user
WHERE id = ?
FOR UPDATE`, [user.id], myOptions);
await models.AccountConfig.syncUser(userName, password);
await models.UserSync.destroyById(userName, myOptions);
if (tx) await tx.commit();
} catch (err) {
if (tx) await tx.rollback();
throw err;
}
};
};

View File

@ -3,14 +3,14 @@ const app = require('vn-loopback/server/server');
const UserError = require('vn-loopback/util/user-error');
module.exports = function(Self, options) {
require('../methods/account-synchronizer/test')(Self);
require('../methods/account-linker/test')(Self);
Self.once('attached', function() {
app.models.AccountConfig.addSynchronizer(Self);
app.models.AccountConfig.addLinker(Self);
});
/**
* Mixin for user synchronizers.
* Mixin for account linkers.
*
* @property {Array<Model>} $
* @property {Object} accountConfig
@ -18,12 +18,12 @@ module.exports = function(Self, options) {
*/
let Mixin = {
/**
* Initalizes the synchronizer.
* Initalizes the linker.
*/
async init() {},
/**
* Deinitalizes the synchronizer.
* Deinitalizes the linker.
*/
async deinit() {},
@ -57,7 +57,7 @@ module.exports = function(Self, options) {
async syncRoles() {},
/**
* Tests synchronizer configuration.
* Tests linker configuration.
*/
async test() {
try {

View File

@ -3,94 +3,85 @@ const models = require('vn-loopback/server/server').models;
module.exports = Self => {
Object.assign(Self, {
synchronizers: [],
linkers: [],
addSynchronizer(synchronizer) {
this.synchronizers.push(synchronizer);
addLinker(linker) {
this.linkers.push(linker);
},
async getInstance() {
let instance = await Self.findOne({
async initEngine() {
const accountConfig = await Self.findOne({
fields: ['homedir', 'shell', 'idBase']
});
await instance.synchronizerInit();
return instance;
const mailConfig = await models.MailConfig.findOne({
fields: ['domain']
});
const linkers = [];
for (const Linker of Self.linkers) {
const linker = await Linker.getLinker();
if (!linker) continue;
Object.assign(linker, {accountConfig});
await linker.init();
linkers.push(linker);
}
Object.assign(accountConfig, {
linkers,
domain: mailConfig.domain
});
return {
accountConfig,
linkers
};
},
async deinitEngine(engine) {
for (const linker of engine.linkers)
await linker.deinit();
},
async syncUser(userName, password) {
const engine = await Self.initEngine();
try {
await Self.syncUserBase(engine, userName, password, true);
} finally {
await Self.deinitEngine(engine);
}
},
async syncUsers() {
let instance = await Self.getInstance();
const engine = await Self.initEngine();
let usersToSync = new Set();
for (const linker of engine.linkers)
await linker.getUsers(usersToSync);
let usersToSync = await instance.synchronizerGetUsers();
usersToSync = Array.from(usersToSync.values())
.sort((a, b) => a.localeCompare(b));
for (let userName of usersToSync) {
try {
// eslint-disable-next-line no-console
console.log(`Synchronizing user '${userName}'`);
await instance.synchronizerSyncUser(userName);
await Self.syncUserBase(engine, userName);
// eslint-disable-next-line no-console
console.log(` -> User '${userName}' sinchronized`);
} catch (err) {
// eslint-disable-next-line no-console
console.error(` -> User '${userName}' synchronization error:`, err.message);
}
}
await instance.synchronizerDeinit();
await Self.deinitEngine(engine);
await Self.syncRoles();
},
async syncUser(userName, password) {
let instance = await Self.getInstance();
try {
await instance.synchronizerSyncUser(userName, password, true);
} finally {
await instance.synchronizerDeinit();
}
},
async syncRoles() {
let instance = await Self.getInstance();
try {
await instance.synchronizerSyncRoles();
} finally {
await instance.synchronizerDeinit();
}
},
async getSynchronizer() {
return await Self.findOne();
}
});
Object.assign(Self.prototype, {
async synchronizerInit() {
let mailConfig = await models.MailConfig.findOne({
fields: ['domain']
});
let synchronizers = [];
for (let Synchronizer of Self.synchronizers) {
let synchronizer = await Synchronizer.getSynchronizer();
if (!synchronizer) continue;
Object.assign(synchronizer, {
accountConfig: this
});
await synchronizer.init();
synchronizers.push(synchronizer);
}
Object.assign(this, {
synchronizers,
domain: mailConfig.domain
});
},
async synchronizerDeinit() {
for (let synchronizer of this.synchronizers)
await synchronizer.deinit();
},
async synchronizerSyncUser(userName, password, syncGroups) {
async syncUserBase(engine, userName, password, syncGroups) {
if (!userName) return;
userName = userName.toLowerCase();
@ -98,7 +89,7 @@ module.exports = Self => {
if (['administrator', 'root'].indexOf(userName) >= 0)
return;
let user = await models.VnUser.findOne({
const user = await models.VnUser.findOne({
where: {name: userName},
fields: [
'id',
@ -130,27 +121,28 @@ module.exports = Self => {
]
});
let info = {
const info = {
user,
hasAccount: false
};
if (user) {
let exists = await models.Account.exists(user.id);
const exists = await models.Account.exists(user.id);
const {accountConfig} = engine;
Object.assign(info, {
hasAccount: user.active && exists,
corporateMail: `${userName}@${this.domain}`,
uidNumber: this.idBase + user.id
corporateMail: `${userName}@${accountConfig.domain}`,
uidNumber: accountConfig.idBase + user.id
});
}
let errs = [];
const errs = [];
for (let synchronizer of this.synchronizers) {
for (const linker of engine.linkers) {
try {
await synchronizer.syncUser(userName, info, password);
await linker.syncUser(userName, info, password);
if (syncGroups)
await synchronizer.syncUserGroups(userName, info);
await linker.syncUserGroups(userName, info);
} catch (err) {
errs.push(err);
}
@ -159,18 +151,16 @@ module.exports = Self => {
if (errs.length) throw errs[0];
},
async synchronizerGetUsers() {
let usersToSync = new Set();
async syncRoles() {
const engine = await Self.initEngine();
try {
await Self.rawSql(`CALL account.role_sync`);
for (let synchronizer of this.synchronizers)
await synchronizer.getUsers(usersToSync);
return usersToSync;
},
async synchronizerSyncRoles() {
for (let synchronizer of this.synchronizers)
await synchronizer.syncRoles();
for (const linker of engine.linkers)
await linker.syncRoles();
} finally {
await Self.deinitEngine(engine);
}
}
});
};

View File

@ -7,7 +7,7 @@ const nthash = require('smbhash').nthash;
module.exports = Self => {
const shouldSync = process.env.NODE_ENV !== 'test';
Self.getSynchronizer = async function() {
Self.getLinker = async function() {
return await Self.findOne({
fields: [
'server',
@ -24,6 +24,7 @@ module.exports = Self => {
this.client = ldap.createClient({
url: this.server
});
this.client.on('error', () => {});
await this.client.bind(this.rdn, this.password);
},

View File

@ -7,7 +7,7 @@
}
},
"mixins": {
"AccountSynchronizer": {}
"AccountLinker": {}
},
"properties": {
"id": {

View File

@ -1,6 +1,6 @@
module.exports = Self => {
Self.getSynchronizer = async function() {
Self.getLinker = async function() {
let NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV || NODE_ENV == 'development')
return null;
@ -45,6 +45,7 @@ module.exports = Self => {
}
if (!isUpdatable) {
// eslint-disable-next-line no-console
console.warn(`RoleConfig.syncUser(): User '${userName}' cannot be updated, not managed by me`);
return;
}
@ -82,6 +83,7 @@ module.exports = Self => {
[mysqlUser, this.userHost]);
} catch (err) {
if (err.code == 'ER_REVOKE_GRANTS')
// eslint-disable-next-line no-console
console.warn(`${err.code}: ${err.sqlMessage}: ${err.sql}`);
else
throw err;

View File

@ -7,7 +7,7 @@
}
},
"mixins": {
"AccountSynchronizer": {}
"AccountLinker": {}
},
"properties": {
"id": {

View File

@ -9,7 +9,7 @@ module.exports = Self => {
Self.observe(hook, async() => {
try {
await Self.rawSql(`
CREATE EVENT account.role_sync
CREATE DEFINER = CURRENT_ROLE EVENT account.role_sync
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 5 SECOND
DO CALL role_sync;
`);

View File

@ -13,7 +13,7 @@ const UserAccountControlFlags = {
module.exports = Self => {
const shouldSync = process.env.NODE_ENV !== 'test';
Self.getSynchronizer = async function() {
Self.getLinker = async function() {
return await Self.findOne({
fields: [
'host',
@ -39,6 +39,7 @@ module.exports = Self => {
url: `ldaps://${this.adController}:636`,
tlsOptions: {rejectUnauthorized: this.verifyCert}
});
adClient.on('error', () => {});
await adClient.bind(bindDn, this.adPassword);
Object.assign(this, {
adClient,

View File

@ -7,7 +7,7 @@
}
},
"mixins": {
"AccountSynchronizer": {}
"AccountLinker": {}
},
"properties": {
"id": {

View File

@ -25,7 +25,15 @@
"type": "number"
},
"ip": {
"type": "string"
"type": "string"
},
"userName": {
"type": "string"
},
"owner": {
"type": "boolean",
"required": true,
"default": true
}
},
"relations": {

View File

@ -2,7 +2,7 @@
const app = require('vn-loopback/server/server');
module.exports = Self => {
Self.getSynchronizer = async function() {
Self.getLinker = async function() {
return await Self.findOne({fields: ['id']});
};

View File

@ -7,7 +7,7 @@
}
},
"mixins": {
"AccountSynchronizer": {}
"AccountLinker": {}
},
"properties": {
"id": {
@ -16,4 +16,3 @@
}
}
}

View File

@ -68,7 +68,6 @@
Deactivate user
</vn-item>
<vn-item
ng-if="$ctrl.user.active"
ng-click="syncUser.show()"
name="synchronizeUser"
vn-acl="it"
@ -166,7 +165,7 @@
vn-id="syncUser"
on-accept="$ctrl.onSync()"
on-close="$ctrl.onSyncClose()">
<tpl-title ng-translate>
<tpl-title translate>
Do you want to synchronize user?
</tpl-title>
<tpl-body>

View File

@ -123,7 +123,7 @@ module.exports = Self => {
await models.TicketTracking.create({
ticketFk: newRefundTicket.id,
stateFk: state.id,
workerFk: worker.id
userFk: worker.id
}, myOptions);
const salesToRefund = await models.ClaimBeginning.find(salesFilter, myOptions);

View File

@ -1,3 +1,5 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('removeFile', {
description: 'Removes a claim document',
@ -19,8 +21,8 @@ module.exports = Self => {
});
Self.removeFile = async(ctx, id, options) => {
let tx;
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
@ -31,19 +33,18 @@ module.exports = Self => {
}
try {
const models = Self.app.models;
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);
const claimDms = await Self.findById(id, null, myOptions);
await models.Dms.removeFile(ctx, targetClaimDms.dmsFk, myOptions);
await targetClaimDms.destroy(myOptions);
const targetDms = await Self.app.models.Dms.removeFile(ctx, claimDms.dmsFk, 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();
return targetDms;
return claimDmsDestroyed;
} catch (e) {
if (tx) await tx.rollback();
throw e;

View File

@ -1,6 +1,3 @@
const UserError = require('vn-loopback/util/user-error');
const fs = require('fs-extra');
const path = require('path');
module.exports = Self => {
Self.remoteMethodCtx('uploadFile', {
@ -57,96 +54,33 @@ module.exports = Self => {
});
Self.uploadFile = async(ctx, id, options) => {
const tx = await Self.beginTransaction({});
const {Dms, ClaimDms} = Self.app.models;
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction)
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
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`);
const uploadedFiles = await Dms.uploadFile(ctx, myOptions);
// 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 => {
const newClaimDms = models.ClaimDms.create({
claimFk: id,
dmsFk: dms.id
}, myOptions);
promises.push(newClaimDms);
});
const resolvedPromises = await Promise.all(promises);
const promises = uploadedFiles.map(dms => ClaimDms.create({
claimFk: id,
dmsFk: dms.id
}, myOptions));
await Promise.all(promises);
if (tx) await tx.commit();
return resolvedPromises;
return uploadedFiles;
} catch (e) {
if (tx) await tx.rollback();
if (fs.existsSync(srcFile))
await fs.unlink(srcFile);
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);
}
};

View File

@ -19,9 +19,8 @@ module.exports = Self => {
});
Self.removeFile = async(ctx, id, options) => {
const models = Self.app.models;
let tx;
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
@ -34,13 +33,16 @@ module.exports = Self => {
try {
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();
return destroyedClient;
return clientDmsDestroyed;
} catch (e) {
if (tx) await tx.rollback();
throw e;

View File

@ -107,17 +107,29 @@ module.exports = Self => {
return {or: [
{'c.phone': {like: `%${value}%`}},
{'c.mobile': {like: `%${value}%`}},
{'a.phone': {like: `%${value}%`}},
]};
case 'zoneFk':
param = 'a.postalCode';
return {[param]: {inq: postalCode}};
return {'a.postalCode': {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 'salesPersonFk':
case 'fi':
case 'socialName':
case 'city':
case 'postcode':
case 'provinceFk':
case 'email':
param = `c.${param}`;
return {[param]: {like: `%${value}%`}};
@ -134,24 +146,29 @@ module.exports = Self => {
c.fi,
c.socialName,
c.phone,
a.phone,
c.mobile,
c.city,
a.city,
c.postcode,
a.postalCode,
c.email,
c.isActive,
c.isFreezed,
p.id AS provinceFk,
p.id AS provinceClientFk,
a.provinceFk AS provinceAddressFk,
p.name AS province,
u.id AS salesPersonFk,
u.name AS salesPerson
FROM client c
LEFT JOIN account.user u ON u.id = c.salesPersonFk
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('GROUP BY c.id');
stmt.merge(conn.makePagination(filter));
const clientsIndex = stmts.push(stmt) - 1;

View File

@ -55,9 +55,9 @@ module.exports = Self => {
});
Self.uploadFile = async(ctx, id, options) => {
const models = Self.app.models;
let tx;
const {Dms, ClientDms} = Self.app.models;
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
@ -67,23 +67,20 @@ module.exports = Self => {
myOptions.transaction = tx;
}
const promises = [];
try {
const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions);
uploadedFiles.forEach(dms => {
const newClientDms = models.ClientDms.create({
const uploadedFiles = await Dms.uploadFile(ctx, myOptions);
const promises = uploadedFiles.map(dms =>
ClientDms.create({
clientFk: id,
dmsFk: dms.id
}, myOptions);
}, myOptions)
promises.push(newClientDms);
});
const resolvedPromises = await Promise.all(promises);
);
await Promise.all(promises);
if (tx) await tx.commit();
return resolvedPromises;
return uploadedFiles;
} catch (e) {
if (tx) await tx.rollback();
throw e;

View File

@ -29,7 +29,7 @@
"ClientCredit": {
"dataSource": "vn"
},
"ClientCreditLimit": {
"RoleCreditLimit": {
"dataSource": "vn"
},
"ClientConsumptionQueue": {

View File

@ -463,7 +463,7 @@ module.exports = Self => {
throw new UserError(`You can't change the credit set to zero from a financialBoss`);
}
const creditLimits = await models.ClientCreditLimit.find({
const creditLimits = await models.RoleCreditLimit.find({
fields: ['roleFk'],
where: {
maxAmount: {gte: changes.credit}

View File

@ -1,9 +1,9 @@
{
"name": "ClientCreditLimit",
"name": "RoleCreditLimit",
"base": "VnModel",
"options": {
"mysql": {
"table": "clientCreditLimit"
"table": "roleCreditLimit"
}
},
"properties": {

View File

@ -62,7 +62,7 @@
<vn-worker-autocomplete
vn-one
ng-model="$ctrl.client.salesPersonFk"
departments="['VT']"
departments="['VT', 'shopping']"
show-field="nickname"
label="Salesperson"
vn-acl="salesAssistant">

View File

@ -16,5 +16,5 @@ columns:
bookEntried: book entried
isVatDeductible: is VAT deductible
withholdingSageFk: withholding
expenceFkDeductible: expence deductible
expenseFkDeductible: expense deductible
editorFk: editor

View File

@ -16,5 +16,5 @@ columns:
bookEntried: fecha asiento
isVatDeductible: impuesto deducible
withholdingSageFk: código de retención
expenceFkDeductible: gasto deducible
expenseFkDeductible: gasto deducible
editorFk: editor

View File

@ -4,7 +4,7 @@ columns:
invoiceInFk: invoice in
taxCodeFk: tax
taxableBase: taxable base
expenceFk: expence
expenseFk: expense
foreignValue: foreign amount
taxTypeSageFk: tax type
transactionTypeSageFk: transaction type

View File

@ -4,7 +4,7 @@ columns:
invoiceInFk: factura recibida
taxCodeFk: código IVA
taxableBase: base imponible
expenceFk: código gasto
expenseFk: código gasto
foreignValue: importe divisa
taxTypeSageFk: código impuesto
transactionTypeSageFk: código transacción

View File

@ -146,7 +146,7 @@ module.exports = Self => {
ii.docFk AS dmsFk,
dm.file,
ii.supplierFk,
ii.expenceFkDeductible deductibleExpenseFk,
ii.expenseFkDeductible deductibleExpenseFk,
s.name AS supplierName,
s.account,
SUM(iid.amount) AS amount,

View File

@ -29,15 +29,18 @@ module.exports = Self => {
SELECT iit.*,
SUM(iidd.amount) totalDueDay
FROM vn.invoiceIn ii
LEFT JOIN (SELECT SUM(iit.taxableBase) totalTaxableBase,
CAST(SUM(iit.taxableBase * (1 + (ti.PorcentajeIva / 100))) AS DECIMAL(10,2)) totalVat
LEFT JOIN (
SELECT SUM(iit.taxableBase) totalTaxableBase,
CAST(
SUM(IFNULL(iit.taxableBase * (1 + (ti.PorcentajeIva / 100)), iit.taxableBase))
AS DECIMAL(10, 2)
) totalVat
FROM vn.invoiceInTax iit
LEFT JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
WHERE iit.invoiceInFk = ?) iit ON TRUE
WHERE iit.invoiceInFk = ?
) iit ON TRUE
LEFT JOIN vn.invoiceInDueDay iidd ON iidd.invoiceInFk = ii.id
WHERE
ii.id = ?`, [id, id]);
WHERE ii.id = ?`, [id, id]);
return result;
};
};

View File

@ -112,7 +112,7 @@ module.exports = Self => {
{
relation: 'taxTypeSage',
scope: {
fields: ['vat']
fields: ['vat', 'rate']
}
}]
}

View File

@ -19,10 +19,7 @@
"type": "number"
},
"expenseFk": {
"type": "number",
"mysql": {
"columnName": "expenceFk"
}
"type": "number"
},
"created": {
"type": "date"

View File

@ -51,7 +51,7 @@
"deductibleExpenseFk": {
"type": "number",
"mysql": {
"columnName": "expenceFkDeductible"
"columnName": "expenseFkDeductible"
}
}
},

View File

@ -3,7 +3,7 @@
"base": "VnModel",
"options": {
"mysql": {
"table": "expence"
"table": "expense"
}
},
"properties": {

View File

@ -117,10 +117,7 @@
"description": "The item family"
},
"expenseFk": {
"type": "number",
"mysql": {
"columnName": "expenceFk"
}
"type": "number"
},
"minPrice": {
"type": "number"
@ -131,9 +128,6 @@
"nonRecycledPlastic": {
"type": "number"
},
"minQuantity": {
"type": "number"
},
"packingOut": {
"type": "number"
},

View File

@ -105,7 +105,7 @@
url="Expenses"
label="Expense"
ng-model="$ctrl.item.expenseFk"
vn-name="expence"
vn-name="expense"
initial-data="$ctrl.item.expense">
</vn-autocomplete>
</vn-horizontal>

View File

@ -151,7 +151,7 @@ describe('SalesMonitor salesFilter()', () => {
const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
const firstRow = result[0];
expect(result.length).toEqual(15);
expect(result.length).toEqual(12);
expect(firstRow.alertLevel).not.toEqual(0);
await tx.rollback();

View File

@ -54,7 +54,7 @@ module.exports = Self => {
dmsFk: firstDms.id,
}, myOptions);
const expence = await models.AgencyTermConfig.findOne(null, myOptions);
const expense = await models.AgencyTermConfig.findOne(null, myOptions);
const [taxTypeSage] = await Self.rawSql(`
SELECT IFNULL(s.taxTypeSageFk, CodigoIva) value
@ -78,7 +78,7 @@ module.exports = Self => {
await models.InvoiceInTax.create({
invoiceInFk: newInvoiceIn.id,
taxableBase: firstRow.totalPrice,
expenseFk: expence.expenceFk,
expenseFk: expense.expenseFk,
taxTypeSageFk: taxTypeSage.value,
transactionTypeSageFk: transactionTypeSage.value
}, myOptions);

View File

@ -130,13 +130,15 @@ module.exports = Self => {
am.name agencyName,
u.name AS workerUserName,
v.numberPlate AS vehiclePlateNumber,
Date_format(r.time, '%H:%i') hour
Date_format(r.time, '%H:%i') hour,
eu.email
FROM route r
LEFT JOIN agencyMode am ON am.id = r.agencyModeFk
LEFT JOIN agency a ON a.id = am.agencyFk
LEFT JOIN vehicle v ON v.id = r.vehicleFk
LEFT JOIN worker w ON w.id = r.workerFk
LEFT JOIN account.user u ON u.id = w.id`
LEFT JOIN account.user u ON u.id = w.id
LEFT JOIN account.emailUser eu ON eu.userFk = r.workerFk`
);
stmt.merge(conn.makeSuffix(filter));

View File

@ -0,0 +1,64 @@
module.exports = Self => {
Self.remoteMethod('getExpeditionSummary', {
description: 'Get summary of expeditions for a given route',
accepts: [
{
arg: 'routeFk',
type: 'number',
required: true,
description: 'Foreign key for Route'
}
],
returns: {
type: 'object',
root: true
},
http: {
path: '/getExpeditionSummary',
verb: 'get'
}
});
Self.getExpeditionSummary = async(routeFk, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = `
SELECT routeFk,
addressFk,
SUM(total) total,
SUM(delivery) delivery,
SUM(lost) lost,
SUM(delivered) delivered,
GROUP_CONCAT(totalPacking ORDER BY total DESC SEPARATOR ' ') itemPackingType
FROM (
SELECT r.id AS routeFk,
t.addressFk,
CONCAT (IFNULL(e.itemPackingTypeFk,'-'), '', COUNT(*)) totalPacking,
COUNT(*) total,
SUM(est.code = 'ON DELIVERY') delivery,
SUM(est.code = 'LOST') lost,
SUM(est.code = 'DELIVERED') delivered,
t.priority
FROM vn.ticket t
JOIN vn.route r ON r.id = t.routeFk
JOIN vn.expedition e ON e.ticketFk = t.id
LEFT JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk
JOIN vn.agencyMode am ON am.id = r.agencyModeFk
JOIN vn.agency ag ON ag.id = am.agencyFk
LEFT JOIN vn.userConfig uc ON uc.userFk = account.myUser_getId()
WHERE (r.created = util.VN_CURDATE() OR r.created = util.yesterday())
AND t.routeFk = ?
GROUP BY t.addressFk, e.itemPackingTypeFk
) sub
GROUP BY addressFk
ORDER BY priority DESC
`;
const results = await Self.rawSql(query, [routeFk], myOptions);
return results;
};
};

View File

@ -3,99 +3,101 @@ const buildFilter = require('vn-loopback/util/filter').buildFilter;
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
module.exports = Self => {
Self.remoteMethod('getExternalCmrs', {
description: 'Returns an array of external cmrs',
accessType: 'READ',
accepts: [
{
arg: 'filter',
type: 'object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
},
{
arg: 'cmrFk',
type: 'integer',
description: 'Searchs the route by id',
},
{
arg: 'ticketFk',
type: 'integer',
description: 'The worker id',
},
{
arg: 'routeFk',
type: 'integer',
description: 'The route id',
},
{
arg: 'country',
type: 'string',
description: 'The agencyMode id',
},
{
arg: 'clientFk',
type: 'integer',
description: 'The vehicle id',
},
{
arg: 'hasCmrDms',
type: 'boolean',
description: 'The vehicle id',
},
{
arg: 'shipped',
type: 'date',
description: 'The to date filter',
},
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/getExternalCmrs`,
verb: 'GET'
}
});
Self.remoteMethod('getExternalCmrs', {
description: 'Returns an array of external cmrs',
accessType: 'READ',
accepts: [
{
arg: 'filter',
type: 'object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
},
{
arg: 'cmrFk',
type: 'integer',
description: 'Searchs the route by id',
},
{
arg: 'ticketFk',
type: 'integer',
description: 'The worker id',
},
{
arg: 'routeFk',
type: 'integer',
description: 'The route id',
},
{
arg: 'country',
type: 'string',
description: 'The agencyMode id',
},
{
arg: 'clientFk',
type: 'integer',
description: 'The vehicle id',
},
{
arg: 'hasCmrDms',
type: 'boolean',
description: 'The vehicle id',
},
{
arg: 'shipped',
type: 'date',
description: 'The to date filter',
},
],
returns: {
type: ['object'],
root: true
},
http: {
path: `/getExternalCmrs`,
verb: 'GET'
}
});
Self.getExternalCmrs = async(
filter,
cmrFk,
ticketFk,
routeFk,
country,
clientFk,
hasCmrDms,
shipped,
options
) => {
const params = {
cmrFk,
ticketFk,
routeFk,
country,
clientFk,
hasCmrDms,
shipped,
};
const conn = Self.dataSource.connector;
Self.getExternalCmrs = async(
filter,
cmrFk,
ticketFk,
routeFk,
country,
clientFk,
hasCmrDms,
shipped,
options
) => {
const params = {
cmrFk,
ticketFk,
routeFk,
country,
clientFk,
hasCmrDms,
shipped,
};
const conn = Self.dataSource.connector;
let where = buildFilter(params, (param, value) => {return {[param]: value}});
filter = mergeFilters(filter, {where});
let where = buildFilter(params, (param, value) => {
return {[param]: value};
});
filter = mergeFilters(filter, {where});
if (!filter.where) {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
filter.where = {'shipped': yesterday.toISOString().split('T')[0]}
}
if (!filter.where) {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
filter.where = {'shipped': yesterday.toISOString().split('T')[0]};
}
const myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (typeof options == 'object')
Object.assign(myOptions, options);
let stmts = [];
const stmt = new ParameterizedSQL(`
let stmts = [];
const stmt = new ParameterizedSQL(`
SELECT *
FROM (
SELECT t.cmrFk,
@ -129,13 +131,13 @@ module.exports = Self => {
AND dm.code = 'DELIVERY'
AND t.cmrFk
) sub
`);
`);
stmt.merge(conn.makeSuffix(filter));
const itemsIndex = stmts.push(stmt) - 1;
stmt.merge(conn.makeSuffix(filter));
const itemsIndex = stmts.push(stmt) - 1;
const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql);
return itemsIndex === 0 ? result : result[itemsIndex];
};
const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql);
return itemsIndex === 0 ? result : result[itemsIndex];
};
};

View File

@ -3,7 +3,7 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethod('getTickets', {
description: 'Return the tickets information displayed on the route module',
description: 'Find all instances of the model matched by filter from the data source.',
accessType: 'READ',
accepts: [
{
@ -40,22 +40,32 @@ module.exports = Self => {
t.clientFk,
t.priority,
t.addressFk,
st.code AS ticketStateCode,
st.name AS ticketStateName,
wh.name AS warehouseName,
tob.description AS ticketObservation,
st.code ticketStateCode,
st.name ticketStateName,
wh.name warehouseName,
tob.description ticketObservation,
a.street,
a.postalCode,
a.city,
am.name AS agencyModeName,
u.nickname AS userNickname,
vn.ticketTotalVolume(t.id) AS volume,
am.name agencyModeName,
u.nickname userNickname,
vn.ticketTotalVolume(t.id) volume,
tob.description,
GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt
GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt,
c.phone clientPhone,
c.mobile clientMobile,
a.phone addressPhone,
a.mobile addressMobile,
a.longitude,
a.latitude,
wm.mediaValue salePersonPhone,
t.cmrFk,
t.isSigned signed
FROM vn.route r
JOIN ticket t ON t.routeFk = r.id
JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
JOIN client c ON t.clientFk = c.id
LEFT JOIN vn.sale s ON s.ticketFk = t.id
LEFT JOIN vn.item i ON i.id = s.itemFk
LEFT JOIN ticketState ts ON ts.ticketFk = t.id
LEFT JOIN state st ON st.id = ts.stateFk
LEFT JOIN warehouse wh ON wh.id = t.warehouseFk
@ -65,7 +75,8 @@ module.exports = Self => {
LEFT JOIN address a ON a.id = t.addressFk
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
LEFT JOIN account.user u ON u.id = r.workerFk
LEFT JOIN vehicle v ON v.id = r.vehicleFk`
LEFT JOIN vehicle v ON v.id = r.vehicleFk
LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk`
);
if (!filter.where) filter.where = {};

View File

@ -0,0 +1,10 @@
const app = require('vn-loopback/server/server');
describe('route getExpeditionSummary()', () => {
const routeId = 1;
it('should return a summary of expeditions for a route', async() => {
const result = await app.models.Route.getExpeditionSummary(routeId);
expect(result.every(route => route.id = routeId)).toBeTruthy();
});
});

View File

@ -7,7 +7,7 @@
}
},
"properties": {
"expenceFk": {
"expenseFk": {
"type": "string",
"id": true
},

View File

@ -17,6 +17,7 @@ module.exports = Self => {
require('../methods/route/cmr')(Self);
require('../methods/route/getExternalCmrs')(Self);
require('../methods/route/downloadCmrsZip')(Self);
require('../methods/route/getExpeditionSummary')(Self);
require('../methods/route/getByWorker')(Self);
Self.validate('kmStart', validateDistance, {

View File

@ -1,6 +1,7 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('deleteExpeditions', {
Self.remoteMethodCtx('deleteExpeditions', {
description: 'Delete the selected expeditions',
accessType: 'WRITE',
accepts: [{
@ -9,44 +10,59 @@ module.exports = Self => {
required: true,
description: 'The expeditions ids to delete'
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/deleteExpeditions`,
verb: 'POST'
},
returns: {
type: ['object'],
root: true
}
});
Self.deleteExpeditions = async(expeditionIds, options) => {
Self.deleteExpeditions = async(ctx, expeditionIds) => {
const models = Self.app.models;
const myOptions = {};
let tx;
const $t = ctx.req.__;
const notDeletedExpeditions = [];
const deletedExpeditions = [];
if (typeof options == 'object')
Object.assign(myOptions, options);
for (let expeditionId of expeditionIds) {
const filter = {
fields: [],
where: {
id: expeditionId
},
include: [
{
relation: 'agencyMode',
scope: {
fields: ['code'],
}
}
]
};
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
const expedition = await models.Expedition.findOne(filter);
const {code} = expedition.agencyMode();
try {
const promises = [];
for (let expeditionId of expeditionIds) {
const deletedExpedition = models.Expedition.destroyById(expeditionId, myOptions);
promises.push(deletedExpedition);
if (code && code.toLowerCase().substring(0, 10) == 'viaexpress') {
const isDeleted = await models.ViaexpressConfig.deleteExpedition(expeditionId);
if (isDeleted === 'true') {
const deletedExpedition = await models.Expedition.destroyById(expeditionId);
deletedExpeditions.push(deletedExpedition);
} else notDeletedExpeditions.push(expeditionId);
} else {
const deletedExpedition = await models.Expedition.destroyById(expeditionId);
deletedExpeditions.push(deletedExpedition);
}
const deletedExpeditions = await Promise.all(promises);
if (tx) await tx.commit();
return deletedExpeditions;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
if (notDeletedExpeditions.length) {
throw new UserError(
$t(`It was not able to remove the next expeditions:`, {expeditions: notDeletedExpeditions.join()})
);
}
return deletedExpeditions;
};
};

View File

@ -2,17 +2,16 @@ const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('ticket deleteExpeditions()', () => {
let ctx;
beforeAll(async() => {
const activeCtx = {
ctx = {
accessToken: {userId: 9},
http: {
req: {
headers: {origin: 'http://localhost'}
}
req: {
headers: {origin: 'http://localhost'}
}
};
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
active: ctx
});
});
@ -23,7 +22,7 @@ describe('ticket deleteExpeditions()', () => {
const options = {transaction: tx};
const expeditionIds = [12, 13];
const result = await models.Expedition.deleteExpeditions(expeditionIds, options);
const result = await models.Expedition.deleteExpeditions(ctx, expeditionIds, options);
expect(result.length).toEqual(2);

View File

@ -19,7 +19,6 @@ module.exports = Self => {
});
Self.removeFile = async(ctx, id, options) => {
const models = Self.app.models;
const myOptions = {};
let tx;
@ -32,18 +31,18 @@ module.exports = Self => {
}
try {
const targetTicketDms = await models.TicketDms.findById(id, null, myOptions);
const targetDms = await models.Dms.findById(targetTicketDms.dmsFk, null, myOptions);
const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}}, myOptions);
const ticketDms = await Self.findById(id, null, myOptions);
await models.Dms.removeFile(ctx, targetTicketDms.dmsFk, myOptions);
await targetTicketDms.destroy(myOptions);
const targetDms = await Self.app.models.Dms.removeFile(ctx, ticketDms.dmsFk, myOptions);
await targetDms.updateAttribute('dmsTypeFk', trashDmsType.id, myOptions);
if (!targetDms || !ticketDms)
throw new UserError('Try again');
const ticketDmsDestroyed = await ticketDms.destroy(myOptions);
if (tx) await tx.commit();
return targetDms;
return ticketDmsDestroyed;
} catch (e) {
if (tx) await tx.rollback();
throw e;

View File

@ -63,7 +63,7 @@ module.exports = Self => {
const isAvailable = itemStock.available > 0;
if (!isAvailable)
if (!isAvailable || !ctx.args.quantity)
throw new UserError(`This item is not available`);
if (request.saleFk)

View File

@ -68,7 +68,7 @@ describe('ticket filter()', () => {
const filter = {};
const result = await models.Ticket.filter(ctx, filter, options);
expect(result.length).toEqual(9);
expect(result.length).toEqual(6);
await tx.rollback();
} catch (e) {
@ -141,7 +141,6 @@ describe('ticket filter()', () => {
});
it('should return the tickets that are not pending', async() => {
pending('#6010 test intermitente');
const tx = await models.Ticket.beginTransaction({});
try {

View File

@ -9,7 +9,7 @@ describe('ticket getSalesPersonMana()', () => {
const mana = await models.Ticket.getSalesPersonMana(1, options);
expect(mana).toEqual(73);
expect(mana).toEqual(124);
await tx.rollback();
} catch (e) {

View File

@ -94,10 +94,10 @@ describe('ticket state()', () => {
const ticketTracking = await models.Ticket.state(ctx, params, options);
expect(ticketTracking.__data.ticketFk).toBe(params.ticketFk);
expect(ticketTracking.__data.stateFk).toBe(params.stateFk);
expect(ticketTracking.__data.workerFk).toBe(49);
expect(ticketTracking.__data.id).toBeDefined();
expect(ticketTracking.ticketFk).toBe(params.ticketFk);
expect(ticketTracking.stateFk).toBe(params.stateFk);
expect(ticketTracking.userFk).toBe(49);
expect(ticketTracking.id).toBeDefined();
await tx.rollback();
} catch (e) {
@ -116,14 +116,14 @@ describe('ticket state()', () => {
const ticket = await models.Ticket.create(sampleTicket, options);
const ctx = {req: {accessToken: {userId: 18}}};
const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options);
const params = {ticketFk: ticket.id, stateFk: assignedState.id, workerFk: 1};
const params = {ticketFk: ticket.id, stateFk: assignedState.id, userFk: 1};
const res = await models.Ticket.state(ctx, params, options);
expect(res.__data.ticketFk).toBe(params.ticketFk);
expect(res.__data.stateFk).toBe(params.stateFk);
expect(res.__data.workerFk).toBe(params.workerFk);
expect(res.__data.workerFk).toBe(1);
expect(res.__data.id).toBeDefined();
expect(res.ticketFk).toBe(params.ticketFk);
expect(res.stateFk).toBe(params.stateFk);
expect(res.userFk).toBe(params.userFk);
expect(res.userFk).toBe(1);
expect(res.id).toBeDefined();
await tx.rollback();
} catch (e) {

View File

@ -51,12 +51,12 @@ module.exports = Self => {
params.stateFk = state.id;
}
if (!params.workerFk) {
if (!params.userFk) {
const worker = await models.Worker.findOne({
where: {id: userId}
}, myOptions);
params.workerFk = worker.id;
params.userFk = worker.id;
}
const ticketState = await models.TicketState.findById(params.ticketFk, {

View File

@ -47,7 +47,7 @@ module.exports = Self => {
});
Self.uploadFile = async(ctx, id, options) => {
const models = Self.app.models;
const {Dms, TicketDms} = Self.app.models;
const myOptions = {};
let tx;
@ -59,22 +59,19 @@ module.exports = Self => {
myOptions.transaction = tx;
}
const promises = [];
try {
const uploadedFiles = await models.Dms.uploadFile(ctx, myOptions);
uploadedFiles.forEach(dms => {
const newTicketDms = models.TicketDms.create({
ticketFk: id,
dmsFk: dms.id
}, myOptions);
const uploadedFiles = await Dms.uploadFile(ctx, myOptions);
promises.push(newTicketDms);
});
const resolvedPromises = await Promise.all(promises);
const promises = uploadedFiles.map(dms => TicketDms.create({
ticketFk: id,
dmsFk: dms.id
}, myOptions));
await Promise.all(promises);
if (tx) await tx.commit();
return resolvedPromises;
return uploadedFiles;
} catch (e) {
if (tx) await tx.rollback();
throw e;

View File

@ -24,5 +24,12 @@
"userFk": {
"type": "number"
}
},
"relations": {
"expeditionStateType": {
"type": "belongsTo",
"model": "ExpeditionStateType",
"foreignKey": "typeFk"
}
}
}

View File

@ -20,6 +20,9 @@
},
"counter": {
"type": "number"
},
"externalId": {
"type": "string"
}
},
"relations": {
@ -30,7 +33,7 @@
},
"agencyMode": {
"type": "belongsTo",
"model": "agency-mode",
"model": "AgencyMode",
"foreignKey": "agencyModeFk"
},
"worker": {

View File

@ -18,7 +18,7 @@
"expenseFk": {
"type": "number",
"mysql": {
"columnName": "expenceFk"
"columnName": "expenseFk"
}
}
},

View File

@ -33,9 +33,9 @@
"model": "State",
"foreignKey": "stateFk"
},
"worker": {
"user": {
"type": "belongsTo",
"model": "Worker",
"model": "VnUser",
"foreignKey": "workerFk"
}
}

View File

@ -2,5 +2,5 @@ module.exports = function(Self) {
require('../methods/ticket-tracking/setDelivered')(Self);
Self.validatesPresenceOf('stateFk', {message: 'State cannot be blank'});
Self.validatesPresenceOf('workerFk', {message: 'Worker cannot be blank'});
Self.validatesPresenceOf('userFk', {message: 'Worker cannot be blank'});
};

View File

@ -8,21 +8,21 @@
},
"properties": {
"id": {
"id": true,
"type": "number",
"forceId": false
"id": true,
"type": "number",
"forceId": false
},
"created": {
"type": "date"
"type": "date"
},
"ticketFk": {
"type": "number"
"type": "number"
},
"stateFk": {
"type": "number"
"type": "number"
},
"workerFk": {
"type": "number"
"userFk": {
"type": "number"
}
},
"relations": {
@ -36,10 +36,10 @@
"model": "State",
"foreignKey": "stateFk"
},
"worker": {
"user": {
"type": "belongsTo",
"model": "Worker",
"foreignKey": "workerFk"
"model": "VnUser",
"foreignKey": "userFk"
}
}
}

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