diff --git a/back/methods/dms/uploadFile.js b/back/methods/dms/uploadFile.js index c3065c3cc..d6540cbc5 100644 --- a/back/methods/dms/uploadFile.js +++ b/back/methods/dms/uploadFile.js @@ -110,11 +110,10 @@ module.exports = Self => { async function createDms(ctx, file, myOptions) { const models = Self.app.models; const myUserId = ctx.req.accessToken.userId; - const myWorker = await models.Worker.findOne({where: {userFk: myUserId}}, myOptions); const args = ctx.args; const newDms = await Self.create({ - workerFk: myWorker.id, + workerFk: myUserId, dmsTypeFk: args.dmsTypeId, companyFk: args.companyId, warehouseFk: args.warehouseId, diff --git a/db/changes/10281-valentineDay/00-ACL.sql b/db/changes/10281-valentineDay/00-ACL.sql index f2e0721f2..88a641a69 100644 --- a/db/changes/10281-valentineDay/00-ACL.sql +++ b/db/changes/10281-valentineDay/00-ACL.sql @@ -1,3 +1,4 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES - ('SupplierAccount', '*', '*', 'ALLOW', 'ROLE', 'administrative'); + ('SupplierAccount', '*', '*', 'ALLOW', 'ROLE', 'administrative'), + ('Entry', '*', '*', 'ALLOW', 'ROLE', 'administrative'); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 36b59fcf6..174a9e093 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -167,12 +167,12 @@ "You can't upload images on the test environment": "No puedes subir imágenes en el entorno de pruebas", "The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta", "Sorts whole route": "Reordena ruta entera", - "Invalid account": "Cuenta inválida", - "New ticket request has been created with price": "Se ha creado una nueva petición de compra *'{{description}}'* para el día *{{shipped}}*, con una cantidad de *{{quantity}}* y un precio de *{{price}} €*", - "New ticket request has been created": "Se ha creado una nueva petición de compra *'{{description}}'* para el día *{{shipped}}*, con una cantidad de *{{quantity}}*", + "New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día {{shipped}}, con una cantidad de {{quantity}} y un precio de {{price}} €", + "New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día {{shipped}}, con una cantidad de {{quantity}}", + "Swift / BIC cannot be empty": "Swift / BIC no puede estar vacío", + "This BIC already exist.": "Este BIC ya existe.", "That item doesn't exists": "Ese artículo no existe", "There's a new urgent ticket": "Hay un nuevo ticket urgente: [{{title}}](https://cau.verdnatura.es/WorkOrder.do?woMode=viewWO&woID={{issueId}})", - "Compensation account is empty": "La cuenta para compensar está vacia", - "Swift / BIC cannot be empty": "Swift / BIC cannot be empty", - "This BIC already exist.": "This BIC already exist." + "Invalid account": "Cuenta inválida", + "Compensation account is empty": "La cuenta para compensar está vacia" } \ No newline at end of file diff --git a/modules/client/back/methods/client/specs/createReceipt.spec.js b/modules/client/back/methods/client/specs/createReceipt.spec.js index 3bd560cdd..8d35064a2 100644 --- a/modules/client/back/methods/client/specs/createReceipt.spec.js +++ b/modules/client/back/methods/client/specs/createReceipt.spec.js @@ -1,4 +1,5 @@ const app = require('vn-loopback/server/server'); +const LoopBackContext = require('loopback-context'); describe('Client createReceipt', () => { const clientFk = 108; @@ -6,18 +7,34 @@ describe('Client createReceipt', () => { const companyFk = 442; const amountPaid = 12.50; const description = 'Receipt description'; + const activeCtx = { + accessToken: {userId: 5}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + const ctx = {req: activeCtx}; + activeCtx.http.req.__ = value => { + return value; + }; + + beforeEach(() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); it('should create a new receipt', async() => { const bankFk = 1; - let ctx = { - args: { - clientFk: clientFk, - payed: payed, - companyFk: companyFk, - bankFk: bankFk, - amountPaid: amountPaid, - description: description - } + ctx.args = { + clientFk: clientFk, + payed: payed, + companyFk: companyFk, + bankFk: bankFk, + amountPaid: amountPaid, + description: description }; const receipt = await app.models.Client.createReceipt(ctx); @@ -40,15 +57,14 @@ describe('Client createReceipt', () => { it('should throw Compensation account is empty', async() => { const bankFk = 3; - let ctx = { - args: { - clientFk: clientFk, - payed: payed, - companyFk: companyFk, - bankFk: bankFk, - amountPaid: amountPaid, - description: description - } + + ctx.args = { + clientFk: clientFk, + payed: payed, + companyFk: companyFk, + bankFk: bankFk, + amountPaid: amountPaid, + description: description }; try { @@ -64,16 +80,14 @@ describe('Client createReceipt', () => { it('should throw Invalid account if compensationAccount does not belongs to a client nor a supplier', async() => { let error; const bankFk = 3; - const ctx = { - args: { - clientFk: clientFk, - payed: payed, - companyFk: companyFk, - bankFk: bankFk, - amountPaid: amountPaid, - description: description, - compensationAccount: 'non existing account' - } + ctx.args = { + clientFk: clientFk, + payed: payed, + companyFk: companyFk, + bankFk: bankFk, + amountPaid: amountPaid, + description: description, + compensationAccount: 'non existing account' }; try { @@ -88,16 +102,15 @@ describe('Client createReceipt', () => { it('should create a new receipt with a compensation for a client', async() => { const bankFk = 3; - const ctx = { - args: { - clientFk: clientFk, - payed: payed, - companyFk: companyFk, - bankFk: bankFk, - amountPaid: amountPaid, - description: description, - compensationAccount: '4300000001' - } + + ctx.args = { + clientFk: clientFk, + payed: payed, + companyFk: companyFk, + bankFk: bankFk, + amountPaid: amountPaid, + description: description, + compensationAccount: '4300000001' }; const receipt = await app.models.Client.createReceipt(ctx); const receiptCompensated = await app.models.Receipt.findOne({ @@ -127,16 +140,16 @@ describe('Client createReceipt', () => { }); it('should create a new receipt with a compensation for a supplier', async() => { - const ctx = { - args: { - clientFk: clientFk, - payed: payed, - companyFk: companyFk, - bankFk: 3, - amountPaid: amountPaid, - description: description, - compensationAccount: '4100000001' - } + const bankFk = 3; + + ctx.args = { + clientFk: clientFk, + payed: payed, + companyFk: companyFk, + bankFk: bankFk, + amountPaid: amountPaid, + description: description, + compensationAccount: '4100000001' }; const receipt = await app.models.Client.createReceipt(ctx); diff --git a/modules/client/back/models/receipt.js b/modules/client/back/models/receipt.js index 88b7bfb5b..36a4a8952 100644 --- a/modules/client/back/models/receipt.js +++ b/modules/client/back/models/receipt.js @@ -1,3 +1,5 @@ +const LoopBackContext = require('loopback-context'); + module.exports = function(Self) { require('../methods/receipt/filter')(Self); @@ -23,13 +25,10 @@ module.exports = function(Self) { Self.observe('before save', async function(ctx) { if (ctx.isNewInstance) { - let token = ctx.options.accessToken; - let userId = token && token.userId; - - ctx.instance.workerFk = userId; - + const loopBackContext = LoopBackContext.getCurrentContext(); + ctx.instance.workerFk = loopBackContext.active.accessToken.userId; await Self.app.models.Till.create({ - workerFk: userId, + workerFk: ctx.instance.workerFk, bankFk: ctx.instance.bankFk, in: ctx.instance.amountPaid, concept: ctx.instance.description, diff --git a/modules/entry/front/routes.json b/modules/entry/front/routes.json index db12e95fd..1911f721c 100644 --- a/modules/entry/front/routes.json +++ b/modules/entry/front/routes.json @@ -31,19 +31,19 @@ "state": "entry.index", "component": "vn-entry-index", "description": "Entries", - "acl": ["buyer"] + "acl": ["buyer", "administrative"] }, { "url": "/latest-buys?q", "state": "entry.latestBuys", "component": "vn-entry-latest-buys", "description": "Latest buys", - "acl": ["buyer"] + "acl": ["buyer", "administrative"] }, { "url": "/create?supplierFk&travelFk&companyFk", "state": "entry.create", "component": "vn-entry-create", "description": "New entry", - "acl": ["buyer"] + "acl": ["buyer", "administrative"] }, { "url": "/:id", "state": "entry.card", diff --git a/modules/supplier/front/account/index.js b/modules/supplier/front/account/index.js index 2a2fa0069..26f4af988 100644 --- a/modules/supplier/front/account/index.js +++ b/modules/supplier/front/account/index.js @@ -19,7 +19,6 @@ class Controller extends Section { } onResponse(response) { - console.log(response); const data = this.$.model.data; const supplierAccount = data[this.currentRowIndex]; supplierAccount.bankEntityFk = response.id; diff --git a/modules/travel/back/methods/travel/getAverageDays.js b/modules/travel/back/methods/travel/getAverageDays.js new file mode 100644 index 000000000..bcc98dbe2 --- /dev/null +++ b/modules/travel/back/methods/travel/getAverageDays.js @@ -0,0 +1,32 @@ +module.exports = Self => { + Self.remoteMethod('getAverageDays', { + description: 'Returns the average days duration and the two warehouses of the travel.', + accessType: 'READ', + accepts: [{ + arg: 'agencyModeFk', + type: 'number', + required: true + }], + returns: { + type: 'number', + root: true + }, + http: { + path: `/getAverageDays`, + verb: 'GET' + } + }); + + Self.getAverageDays = async agencyModeFk => { + const query = ` + SELECT t.id, t.warehouseInFk, t.warehouseOutFk, + (SELECT ROUND(AVG(DATEDIFF(t.landed, t.shipped ))) + FROM travel t + WHERE t.agencyFk = ? LIMIT 50) AS dayDuration + FROM travel t + WHERE t.agencyFk = ? ORDER BY t.id DESC LIMIT 1;`; + + const [avgDays] = await Self.rawSql(query, [agencyModeFk, agencyModeFk]); + return avgDays; + }; +}; diff --git a/modules/travel/back/models/travel.js b/modules/travel/back/models/travel.js index 46d33b305..046153ee2 100644 --- a/modules/travel/back/models/travel.js +++ b/modules/travel/back/models/travel.js @@ -8,6 +8,7 @@ module.exports = Self => { require('../methods/travel/deleteThermograph')(Self); require('../methods/travel/updateThermograph')(Self); require('../methods/travel/extraCommunityFilter')(Self); + require('../methods/travel/getAverageDays')(Self); require('../methods/travel/cloneWithEntries')(Self); Self.rewriteDbError(function(err) { diff --git a/modules/travel/front/create/index.html b/modules/travel/front/create/index.html index 0931c322e..6c19e0e12 100644 --- a/modules/travel/front/create/index.html +++ b/modules/travel/front/create/index.html @@ -20,6 +20,7 @@ diff --git a/modules/travel/front/create/index.js b/modules/travel/front/create/index.js index 9a9c5ce9d..cf0b2f382 100644 --- a/modules/travel/front/create/index.js +++ b/modules/travel/front/create/index.js @@ -7,6 +7,31 @@ class Controller extends Section { this.travel = JSON.parse(this.$params.q); } + onShippedChange(value) { + let hasFilledProperties; + let hasAgencyMode; + if (this.travel) { + hasAgencyMode = Boolean(this.travel.agencyModeFk); + hasFilledProperties = this.travel.landed || this.travel.warehouseInFk || this.travel.warehouseOutFk; + } + if (!hasAgencyMode || hasFilledProperties) + return; + + const query = `travels/getAverageDays`; + const params = { + agencyModeFk: this.travel.agencyModeFk + }; + this.$http.get(query, {params}).then(res => { + const landed = new Date(value); + const futureDate = landed.getDate() + res.data.dayDuration; + landed.setDate(futureDate); + + this.travel.landed = landed; + this.travel.warehouseInFk = res.data.warehouseInFk; + this.travel.warehouseOutFk = res.data.warehouseOutFk; + }); + } + onSubmit() { return this.$.watcher.submit().then( res => this.$state.go('travel.card.basicData', {id: res.data.id}) diff --git a/modules/travel/front/create/index.spec.js b/modules/travel/front/create/index.spec.js index 99f52b322..b59530604 100644 --- a/modules/travel/front/create/index.spec.js +++ b/modules/travel/front/create/index.spec.js @@ -5,10 +5,12 @@ describe('Travel Component vnTravelCreate', () => { let $scope; let $state; let controller; + let $httpBackend; beforeEach(ngModule('travel')); - beforeEach(inject(($componentController, $rootScope, _$state_) => { + beforeEach(inject(($componentController, $rootScope, _$state_, _$httpBackend_) => { + $httpBackend = _$httpBackend_; $scope = $rootScope.$new(); $state = _$state_; $scope.watcher = watcher; @@ -38,4 +40,34 @@ describe('Travel Component vnTravelCreate', () => { expect(controller.travel).toEqual(json); }); }); + + describe('onShippedChange()', () => { + it(`should do nothing if there's no agencyModeFk in the travel.`, () => { + controller.travel = {}; + controller.onShippedChange(); + + expect(controller.travel.landed).toBeUndefined(); + expect(controller.travel.warehouseInFk).toBeUndefined(); + expect(controller.travel.warehouseOutFk).toBeUndefined(); + }); + + it(`should fill the fields when it's selected a date and agency.`, () => { + controller.travel = {agencyModeFk: 1}; + const tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + const expectedResponse = { + dayDuration: 2, + warehouseInFk: 1, + warehouseOutFk: 2 + }; + + const query = `travels/getAverageDays?agencyModeFk=${controller.travel.agencyModeFk}`; + $httpBackend.expectGET(query).respond(expectedResponse); + controller.onShippedChange(tomorrow); + $httpBackend.flush(); + + expect(controller.travel.warehouseInFk).toEqual(expectedResponse.warehouseInFk); + expect(controller.travel.warehouseOutFk).toEqual(expectedResponse.warehouseOutFk); + }); + }); });