diff --git a/.vscode/settings.json b/.vscode/settings.json index 40ec5c0d3..36b7e21d8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,7 @@ // Carácter predeterminado de final de línea. "files.eol": "\n", "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, "search.useIgnoreFiles": false, "editor.defaultFormatter": "dbaeumer.vscode-eslint", diff --git a/back/methods/docuware/specs/upload.spec.js b/back/methods/docuware/specs/upload.spec.js index 3b8c55a50..866499b66 100644 --- a/back/methods/docuware/specs/upload.spec.js +++ b/back/methods/docuware/specs/upload.spec.js @@ -24,15 +24,40 @@ describe('docuware upload()', () => { }); it('should try upload file', async() => { + const tx = await models.Docuware.beginTransaction({}); spyOn(ticketModel, 'deliveryNotePdf').and.returnValue(new Promise(resolve => resolve({}))); let error; try { - await models.Docuware.upload(ctx, ticketIds, fileCabinetName); + const options = {transaction: tx}; + const user = await models.UserConfig.findById(userId, null, options); + await user.updateAttribute('tabletFk', 'Tablet1', options); + await models.Docuware.upload(ctx, ticketIds, fileCabinetName, options); + + await tx.rollback(); } catch (e) { - error = e.message; + error = e; + await tx.rollback(); } - expect(error).toEqual('Action not allowed on the test environment'); + expect(error.message).toEqual('Action not allowed on the test environment'); + }); + + it('should throw error when not have tablet assigned', async() => { + const tx = await models.Docuware.beginTransaction({}); + spyOn(ticketModel, 'deliveryNotePdf').and.returnValue(new Promise(resolve => resolve({}))); + + let error; + try { + const options = {transaction: tx}; + await models.Docuware.upload(ctx, ticketIds, fileCabinetName, options); + + await tx.rollback(); + } catch (e) { + error = e; + await tx.rollback(); + } + + expect(error.message).toEqual('This user does not have an assigned tablet'); }); }); diff --git a/back/methods/docuware/upload.js b/back/methods/docuware/upload.js index 7055bf8d5..27be72295 100644 --- a/back/methods/docuware/upload.js +++ b/back/methods/docuware/upload.js @@ -29,12 +29,24 @@ module.exports = Self => { } }); - Self.upload = async function(ctx, ticketIds, fileCabinet) { + Self.upload = async function(ctx, ticketIds, fileCabinet, options) { delete ctx.args.ticketIds; const models = Self.app.models; const action = 'store'; - const options = await Self.getOptions(); + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const userConfig = await models.UserConfig.findById(ctx.req.accessToken.userId, { + fields: ['tabletFk'] + }, myOptions); + + if (!userConfig?.tabletFk) + throw new UserError('This user does not have an assigned tablet'); + + const docuwareOptions = await Self.getOptions(); const fileCabinetId = await Self.getFileCabinet(fileCabinet); const dialogId = await Self.getDialog(fileCabinet, action, fileCabinetId); @@ -45,7 +57,7 @@ module.exports = Self => { const deliveryNote = await models.Ticket.deliveryNotePdf(ctx, { id, type: 'deliveryNote' - }); + }, myOptions); // get ticket data const ticket = await models.Ticket.findById(id, { include: [{ @@ -54,7 +66,7 @@ module.exports = Self => { fields: ['id', 'name', 'fi'] } }] - }); + }, myOptions); // upload file const templateJson = { @@ -102,7 +114,7 @@ module.exports = Self => { { 'FieldName': 'FILTRO_TABLET', 'ItemElementName': 'string', - 'Item': 'Tablet1', + 'Item': userConfig.tabletFk, } ] }; @@ -116,11 +128,11 @@ module.exports = Self => { const deleteJson = { 'Field': [{'FieldName': 'ESTADO', 'Item': 'Pendiente eliminar', 'ItemElementName': 'String'}] }; - const deleteUri = `${options.url}/FileCabinets/${fileCabinetId}/Documents/${docuwareFile.id}/Fields`; - await axios.put(deleteUri, deleteJson, options.headers); + const deleteUri = `${docuwareOptions.url}/FileCabinets/${fileCabinetId}/Documents/${docuwareFile.id}/Fields`; + await axios.put(deleteUri, deleteJson, docuwareOptions.headers); } - const uploadUri = `${options.url}/FileCabinets/${fileCabinetId}/Documents?StoreDialogId=${dialogId}`; + const uploadUri = `${docuwareOptions.url}/FileCabinets/${fileCabinetId}/Documents?StoreDialogId=${dialogId}`; const FormData = require('form-data'); const data = new FormData(); @@ -130,7 +142,7 @@ module.exports = Self => { headers: { 'Content-Type': 'multipart/form-data', 'X-File-ModifiedDate': Date.vnNew(), - 'Cookie': options.headers.headers.Cookie, + 'Cookie': docuwareOptions.headers.headers.Cookie, ...data.getHeaders() }, }; @@ -141,11 +153,11 @@ module.exports = Self => { const $t = ctx.req.__; const message = $t('Failed to upload delivery note', {id}); if (uploaded.length) - await models.TicketTracking.setDelivered(ctx, uploaded); + await models.TicketTracking.setDelivered(ctx, uploaded, myOptions); throw new UserError(message); } uploaded.push(id); } - return models.TicketTracking.setDelivered(ctx, ticketIds); + return models.TicketTracking.setDelivered(ctx, ticketIds, myOptions); }; }; diff --git a/back/methods/vn-user/specs/renew-token.spec.js b/back/methods/vn-user/specs/renew-token.spec.js index 674ce36f4..8d9bbf11c 100644 --- a/back/methods/vn-user/specs/renew-token.spec.js +++ b/back/methods/vn-user/specs/renew-token.spec.js @@ -27,8 +27,9 @@ describe('Renew Token', () => { jasmine.clock().uninstall(); }); - it('should renew process', async() => { - jasmine.clock().mockDate(new Date(startingTime + 21600000)); + it('should renew token', async() => { + const mockDate = new Date(startingTime + 26600000); + jasmine.clock().mockDate(mockDate); const {id} = await models.VnUser.renewToken(ctx); expect(id).not.toEqual(ctx.req.accessToken.id); diff --git a/back/methods/vn-user/specs/sign-in.spec.js b/back/methods/vn-user/specs/sign-in.spec.js index 1c4b4af51..a14dd301e 100644 --- a/back/methods/vn-user/specs/sign-in.spec.js +++ b/back/methods/vn-user/specs/sign-in.spec.js @@ -20,10 +20,7 @@ describe('VnUser Sign-in()', () => { 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(); + expect(signInLog.length).toEqual(0); await VnUser.logout(ctx.req.accessToken.id); }); diff --git a/back/models/docuwareTablet.json b/back/models/docuwareTablet.json new file mode 100644 index 000000000..dbbf62f56 --- /dev/null +++ b/back/models/docuwareTablet.json @@ -0,0 +1,17 @@ +{ + "name": "docuwareTablet", + "base": "VnModel", + "options": { + "mysql": { + "table": "docuwareTablet" + } + }, + "properties": { + "tablet": { + "type": "string" + }, + "description": { + "type": "string" + } + } +} diff --git a/back/models/user-config.json b/back/models/user-config.json index 52125dc01..5c5df1b9e 100644 --- a/back/models/user-config.json +++ b/back/models/user-config.json @@ -26,6 +26,9 @@ }, "darkMode": { "type": "boolean" + }, + "tabletFk": { + "type": "string" } }, "relations": { @@ -43,6 +46,11 @@ "type": "belongsTo", "model": "VnUser", "foreignKey": "userFk" - } + }, + "Tablet": { + "type": "belongsTo", + "model": "docuwareTablet", + "foreignKey": "tabletFk" + } } } diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 80287de5b..b1d09f0c0 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -134,15 +134,16 @@ module.exports = function(Self) { Self.signInValidate = async(user, userToken, token, ctx) => { const [[key, value]] = Object.entries(Self.userUses(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'); + if (!isOwner) { + await Self.app.models.SignInLog.create({ + userName: user, + token: token.id, + userFk: userToken.id, + ip: ctx.req.ip, + owner: isOwner + }); + throw new UserError('Try again'); + } }; /** diff --git a/db/changes/240001/00-truncate-where-signInLog.sql b/db/changes/240001/00-truncate-where-signInLog.sql new file mode 100644 index 000000000..93d80d716 --- /dev/null +++ b/db/changes/240001/00-truncate-where-signInLog.sql @@ -0,0 +1 @@ +DELETE FROM `account`.`signInLog` where owner <> FALSE diff --git a/db/changes/240201/00-tabletDocuware.sql b/db/changes/240201/00-tabletDocuware.sql new file mode 100644 index 000000000..ffa0226b3 --- /dev/null +++ b/db/changes/240201/00-tabletDocuware.sql @@ -0,0 +1,10 @@ +-- vn.docuwareTablet definition + +CREATE TABLE `vn`.`docuwareTablet` ( + `tablet` varchar(100) NOT NULL PRIMARY KEY, + `description` varchar(255) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; + +ALTER TABLE `vn`.`userConfig` +ADD COLUMN tabletFk varchar(100) DEFAULT NULL, +ADD FOREIGN KEY (tabletFk) REFERENCES `vn`.`docuwareTablet`(tablet); diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 8997e40b1..479704dd9 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -3009,3 +3009,8 @@ INSERT INTO `vn`.`invoiceCorrectionType` (`id`, `description`) (1, 'Error in VAT calculation'), (2, 'Error in sales details'), (3, 'Error in customer data'); + +INSERT INTO `vn`.`docuwareTablet` (`tablet`,`description`) + VALUES + ('Tablet1','Jarvis tablet'), + ('Tablet2','Avengers tablet'); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index fad630bbe..bf61f06c8 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -329,8 +329,8 @@ "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", - "provinceFk must be unique": "provinceFk must be unique", - "fi cannot be empty": "fi cannot be empty", - "countryFk cannot be empty": "countryFk cannot be empty", + "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}}", + "This user does not have an assigned tablet": "Este usuario no tiene tablet asignada", "Field are invalid": "El campo '{{tag}}' no es válido" } diff --git a/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js b/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js index ae9c404af..96c789316 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js +++ b/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js @@ -90,7 +90,7 @@ module.exports = Self => { AND t.refFk IS NULL AND c.typeFk IN ('normal','trust') GROUP BY t.clientFk, negativeBase.taxableBase - HAVING amount <> 0`, [args.from, args.to])); + HAVING amount < 0`, [args.from, args.to])); stmt = new ParameterizedSQL(` SELECT f.* diff --git a/modules/item/back/locale/item-shelving/en.yml b/modules/item/back/locale/item-shelving/en.yml new file mode 100644 index 000000000..997815b2c --- /dev/null +++ b/modules/item/back/locale/item-shelving/en.yml @@ -0,0 +1,13 @@ +name: itemShelving +columns: + id: id + itemFk: item + shelvingFk: shelving + visible: visible + created: created + grouping: grouping + packing: packing + packagingFk: package + userFk: user + isChecked: isChecked + buyFk: buy diff --git a/modules/item/back/locale/item-shelving/es.yml b/modules/item/back/locale/item-shelving/es.yml new file mode 100644 index 000000000..f00dfd6c5 --- /dev/null +++ b/modules/item/back/locale/item-shelving/es.yml @@ -0,0 +1,13 @@ +name: artículo del carro +columns: + id: id + itemFk: artículo + shelvingFk: matrícula carro + visible: visible + created: creado + grouping: grouping + packing: packing + packagingFk: embalaje + userFk: usuario + isChecked: está revisado + buyFk: compra \ No newline at end of file