+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/front/salix/components/bank-entity/index.js b/front/salix/components/bank-entity/index.js
index 192ebe046..261018017 100644
--- a/front/salix/components/bank-entity/index.js
+++ b/front/salix/components/bank-entity/index.js
@@ -1,35 +1,24 @@
import ngModule from '../../module';
-import Component from 'core/lib/component';
+import Dialog from 'core/components/dialog';
import './style.scss';
-class Controller extends Component {
- open() {
- this.$.bankEntityDialog.show();
- }
+class Controller extends Dialog {
+ responseHandler(response) {
+ if (response !== 'accept')
+ return super.responseHandler(response);
- resetData() {
- this.data = {};
- }
+ if (!this.data.countryFk)
+ throw new Error(`The country can't be empty`);
- onAccept() {
- try {
- if (!this.data.countryFk)
- throw new Error(`The country can't be empty`);
-
- this.$http.post(`bankEntities`, this.data).then(res => {
- this.vnApp.showMessage(this.$t('The bank entity has been created. You can save the data now'));
- this.emit('response', {$response: res.data});
- });
- } catch (e) {
- this.vnApp.showError(this.$t(e.message));
- return false;
- }
- return true;
+ return this.$http.post(`bankEntities`, this.data)
+ .then(res => this.data.id = res.data.id)
+ .then(() => super.responseHandler(response))
+ .then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
}
}
ngModule.vnComponent('vnNewBankEntity', {
- template: require('./index.html'),
+ slotTemplate: require('./index.html'),
controller: Controller,
bindings: {
data: '<',
diff --git a/front/salix/components/bank-entity/index.spec.js b/front/salix/components/bank-entity/index.spec.js
index c288c3052..f93325231 100644
--- a/front/salix/components/bank-entity/index.spec.js
+++ b/front/salix/components/bank-entity/index.spec.js
@@ -5,49 +5,35 @@ describe('Salix Component vnNewBankEntity', () => {
let $httpBackend;
let $scope;
let $element;
- let vnApp;
beforeEach(ngModule('salix'));
- beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _vnApp_) => {
+ beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
- vnApp = _vnApp_;
- jest.spyOn(vnApp, 'showError');
$scope = $rootScope.$new();
- $element = angular.element('');
- controller = $componentController('vnNewBankEntity', {$element, $scope});
+ $element = angular.element('');
+ const $transclude = {
+ $$boundTransclude: {
+ $$slots: []
+ }
+ };
+ controller = $componentController('vnNewBankEntity', {$element, $scope, $transclude});
+ controller.vnApp = {showSuccess: jest.fn()};
}));
- describe('resetData()', () => {
- it('should reset the location in the controller', () => {
- expect(controller.data).toBeUndefined();
-
- controller.resetData();
-
- expect(controller.data).toEqual({});
- });
- });
-
- describe('onAccept()', () => {
- it('should throw an error if there is no country id in the location', () => {
- jest.spyOn(controller.vnApp, 'showMessage');
-
- controller.data = {};
-
- controller.onAccept();
-
- expect(controller.vnApp.showError).toHaveBeenCalledWith(`The country can't be empty`);
- });
-
- it('should do add the new bank entity', () => {
+ describe('responseHandler()', () => {
+ it('should show a success message after the query to bankEntities', () => {
controller.data = {
countryFk: 1
};
- $httpBackend.expectPOST('bankEntities', controller.data).respond(200, controller.data);
+ $httpBackend.expectPOST('bankEntities', controller.data).respond({id: 1});
- controller.onAccept();
+ controller.responseHandler('accept');
$httpBackend.flush();
+
+ expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
+ expect(controller.data.id).toEqual(1);
});
});
});
diff --git a/front/salix/components/bank-entity/locale/es.yml b/front/salix/components/bank-entity/locale/es.yml
index fe5160572..874a42393 100644
--- a/front/salix/components/bank-entity/locale/es.yml
+++ b/front/salix/components/bank-entity/locale/es.yml
@@ -9,4 +9,5 @@ The country can't be empty: El país no puede quedar vacío
The postcode has been created. You can save the data now: Se ha creado el código postal. Ahora puedes guardar los datos
The city has been created: Se ha creado la ciudad
The province has been created: Se ha creado la provincia
-The bank entity has been created. You can save the data now: Se ha creado la entidad bancaria. Puedes guardar los datos ahora
\ No newline at end of file
+The bank entity has been created. You can save the data now: Se ha creado la entidad bancaria. Puedes guardar los datos ahora
+Entity code: Código de la entidad
\ No newline at end of file
diff --git a/front/salix/components/upload-photo/index.html b/front/salix/components/upload-photo/index.html
index 09b36d531..3dd6cdb27 100644
--- a/front/salix/components/upload-photo/index.html
+++ b/front/salix/components/upload-photo/index.html
@@ -4,7 +4,7 @@
message="Edit photo">
-
+
-
+
+
+
+
+
+
+
@@ -37,6 +51,14 @@
+
+
+
+ this.editor.bind({url: e.target.result});
- reader.readAsDataURL(value[0]);
+ if (this.uploadMethod == 'computer') {
+ const reader = new FileReader();
+ reader.onload = e => this.editor.bind({url: e.target.result});
+ reader.readAsDataURL(value);
+ } else if (this.uploadMethod == 'URL')
+ this.editor.bind({url: value});
}
}
diff --git a/front/salix/components/upload-photo/index.spec.js b/front/salix/components/upload-photo/index.spec.js
index e8ac05fd4..f2aad6a5c 100644
--- a/front/salix/components/upload-photo/index.spec.js
+++ b/front/salix/components/upload-photo/index.spec.js
@@ -24,17 +24,30 @@ describe('Salix', () => {
});
describe('viewportSelection()', () => {
- it('should call to displayEditor() and updatePhotoPreview() methods', () => {
- controller.displayEditor = jest.fn();
+ it('should call to the updatePhotoPreview() method when uploadMethod property is set to "computer"', () => {
controller.updatePhotoPreview = jest.fn();
const files = [{name: 'test.jpg'}];
controller.newPhoto.files = files;
+ controller.uploadMethod = 'computer';
controller.viewportSelection = {code: 'normal'};
- expect(controller.displayEditor).toHaveBeenCalledWith();
- expect(controller.updatePhotoPreview).toHaveBeenCalledWith(files);
+ const firstFile = files[0];
+
+ expect(controller.updatePhotoPreview).toHaveBeenCalledWith(firstFile);
+ });
+
+ it('should call to the updatePhotoPreview() method when uploadMethod property is set to "URL"', () => {
+ controller.updatePhotoPreview = jest.fn();
+
+ const url = 'http://gothamcity.com/batman.png';
+ controller.newPhoto.url = url;
+
+ controller.uploadMethod = 'URL';
+ controller.viewportSelection = {code: 'normal'};
+
+ expect(controller.updatePhotoPreview).toHaveBeenCalledWith(url);
});
});
diff --git a/front/salix/components/upload-photo/locale/es.yml b/front/salix/components/upload-photo/locale/es.yml
index bba3a985a..bcc3801d8 100644
--- a/front/salix/components/upload-photo/locale/es.yml
+++ b/front/salix/components/upload-photo/locale/es.yml
@@ -3,4 +3,6 @@ Select an image: Selecciona una imagen
File name: Nombre del fichero
Rotate left: Girar a la izquierda
Rotate right: Girar a la derecha
-Panoramic: Panorámico
\ No newline at end of file
+Panoramic: Panorámico
+Select from computer: Seleccionar desde ordenador
+Import from external URL: Importar desde URL externa
\ No newline at end of file
diff --git a/loopback/locale/es.json b/loopback/locale/es.json
index 884db41f0..7a670d2ed 100644
--- a/loopback/locale/es.json
+++ b/loopback/locale/es.json
@@ -206,5 +206,8 @@
"A ticket with an amount of zero can't be invoiced": "No se puede facturar un ticket con importe cero",
"A ticket with a negative base can't be invoiced": "No se puede facturar un ticket con una base negativa",
"Global invoicing failed": "[Facturación global] No se han podido facturar algunos clientes",
- "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes"
+ "Wasn't able to invoice the following clients": "No se han podido facturar los siguientes clientes",
+ "Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio",
+ "You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito",
+ "You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente"
}
\ No newline at end of file
diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js
index a4332290d..6519cb979 100644
--- a/modules/client/back/models/client.js
+++ b/modules/client/back/models/client.js
@@ -217,19 +217,9 @@ module.exports = Self => {
if (isTaxDataCheckedChanged && !orgData.businessTypeFk)
throw new UserError(`Can't verify data unless the client has a business type`);
}
-
- if (changes.credit !== undefined) {
- await validateCreditChange(ctx, finalState);
- let filter = {fields: ['id'], where: {userFk: ctx.options.accessToken.userId}};
- let worker = await Self.app.models.Worker.findOne(filter);
-
- let newCredit = {
- amount: changes.credit,
- clientFk: finalState.id,
- workerFk: worker ? worker.id : null
- };
- await Self.app.models.ClientCredit.create(newCredit);
- }
+ // Credit changes
+ if (changes.credit !== undefined)
+ await Self.changeCredit(ctx, finalState, changes);
});
Self.observe('after save', async ctx => {
@@ -332,42 +322,54 @@ module.exports = Self => {
await models.Chat.send(httpCtx, `@${currentWorker.user}`, message);
};
- async function validateCreditChange(ctx, finalState) {
- let models = Self.app.models;
- let userId = ctx.options.accessToken.userId;
+ // Credit change validations
+ Self.changeCredit = async function changeCredit(ctx, finalState, changes) {
+ const models = Self.app.models;
+ const userId = ctx.options.accessToken.userId;
- let currentUserIsManager = await models.Account.hasRole(userId, 'manager');
- if (currentUserIsManager)
- return;
+ const isManager = await models.Account.hasRole(userId, 'manager', ctx.options);
+ if (!isManager) {
+ const lastCredit = await models.ClientCredit.findOne({
+ where: {
+ clientFk: finalState.id
+ },
+ order: 'id DESC'
+ }, ctx.options);
- let filter = {
- fields: ['roleFk'],
- where: {
- maxAmount: {gt: ctx.data.credit}
- }
- };
+ const lastAmount = lastCredit && lastCredit.amount;
+ const lastWorkerId = lastCredit && lastCredit.workerFk;
+ const lastWorkerIsManager = await models.Account.hasRole(lastWorkerId, 'manager', ctx.options);
- let limits = await models.ClientCreditLimit.find(filter);
+ if (lastAmount == 0 && lastWorkerIsManager)
+ throw new UserError(`You can't change the credit set to zero from a manager`);
- if (limits.length == 0)
- throw new UserError('Credit limits not found');
+ const creditLimits = await models.ClientCreditLimit.find({
+ fields: ['roleFk'],
+ where: {
+ maxAmount: {gte: changes.credit}
+ }
+ }, ctx.options);
- // Si el usuario no tiene alguno de los roles no continua
+ const requiredRoles = [];
+ for (limit of creditLimits)
+ requiredRoles.push(limit.roleFk);
- let requiredRoles = [];
- for (limit of limits)
- requiredRoles.push(limit.roleFk);
+ const userRequiredRoles = await models.RoleMapping.count({
+ roleId: {inq: requiredRoles},
+ principalType: 'USER',
+ principalId: userId
+ }, ctx.options);
- let where = {
- roleId: {inq: requiredRoles},
- principalType: 'USER',
- principalId: userId
- };
- let count = await models.RoleMapping.count(where);
+ if (userRequiredRoles <= 0)
+ throw new UserError(`You don't have enough privileges to set this credit amount`);
+ }
- if (count <= 0)
- throw new UserError('The role cannot set this credit amount');
- }
+ await models.ClientCredit.create({
+ amount: changes.credit,
+ clientFk: finalState.id,
+ workerFk: userId
+ }, ctx.options);
+ };
const app = require('vn-loopback/server/server');
app.on('started', function() {
diff --git a/modules/client/back/models/specs/client.spec.js b/modules/client/back/models/specs/client.spec.js
index 0406cfc21..d1a6d77cb 100644
--- a/modules/client/back/models/specs/client.spec.js
+++ b/modules/client/back/models/specs/client.spec.js
@@ -1,4 +1,4 @@
-const app = require('vn-loopback/server/server');
+const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('Client Model', () => {
@@ -14,8 +14,8 @@ describe('Client Model', () => {
}
};
const ctx = {req: activeCtx};
- const chatModel = app.models.Chat;
- const client = {id: 1101, name: 'Bruce Banner'};
+ const chatModel = models.Chat;
+ const instance = {id: 1101, name: 'Bruce Banner'};
const previousWorkerId = 1106; // DavidCharlesHaller
const currentWorkerId = 1107; // HankPym
@@ -29,7 +29,7 @@ describe('Client Model', () => {
it('should call to the Chat send() method for both workers', async() => {
spyOn(chatModel, 'send').and.callThrough();
- await app.models.Client.notifyAssignment(client, previousWorkerId, currentWorkerId);
+ await models.Client.notifyAssignment(instance, previousWorkerId, currentWorkerId);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@DavidCharlesHaller', `Client assignment has changed`);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@HankPym', `Client assignment has changed`);
@@ -38,7 +38,7 @@ describe('Client Model', () => {
it('should call to the Chat send() method for the previous worker', async() => {
spyOn(chatModel, 'send').and.callThrough();
- await app.models.Client.notifyAssignment(client, null, currentWorkerId);
+ await models.Client.notifyAssignment(instance, null, currentWorkerId);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@HankPym', `Client assignment has changed`);
});
@@ -46,9 +46,69 @@ describe('Client Model', () => {
it('should call to the Chat send() method for the current worker', async() => {
spyOn(chatModel, 'send').and.callThrough();
- await app.models.Client.notifyAssignment(client, previousWorkerId, null);
+ await models.Client.notifyAssignment(instance, previousWorkerId, null);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@DavidCharlesHaller', `Client assignment has changed`);
});
});
+
+ describe('changeCredit()', () => {
+ it('should fail to change the credit as a salesAssistant set to zero by a manager', async() => {
+ const tx = await models.Client.beginTransaction({});
+
+ let error;
+
+ try {
+ const options = {transaction: tx};
+ const context = {options};
+
+ // Set credit to zero by a manager
+ const financialBoss = await models.Account.findOne({
+ where: {name: 'financialBoss'}
+ }, options);
+ context.options.accessToken = {userId: financialBoss.id};
+
+ await models.Client.changeCredit(context, instance, {credit: 0});
+
+ const salesAssistant = await models.Account.findOne({
+ where: {name: 'salesAssistant'}
+ }, options);
+ context.options.accessToken = {userId: salesAssistant.id};
+
+ await models.Client.changeCredit(context, instance, {credit: 300});
+
+ await tx.rollback();
+ } catch (e) {
+ error = e;
+ await tx.rollback();
+ }
+
+ expect(error.message).toEqual(`You can't change the credit set to zero from a manager`);
+ });
+
+ it('should fail to change to a high credit amount as a salesAssistant', async() => {
+ const tx = await models.Client.beginTransaction({});
+
+ let error;
+
+ try {
+ const options = {transaction: tx};
+ const context = {options};
+
+ const salesAssistant = await models.Account.findOne({
+ where: {name: 'salesAssistant'}
+ }, options);
+ context.options.accessToken = {userId: salesAssistant.id};
+
+ await models.Client.changeCredit(context, instance, {credit: 99999});
+
+ await tx.rollback();
+ } catch (e) {
+ error = e;
+ await tx.rollback();
+ }
+
+ expect(error.message).toEqual(`You don't have enough privileges to set this credit amount`);
+ });
+ });
});
diff --git a/modules/client/front/billing-data/index.html b/modules/client/front/billing-data/index.html
index b9c20ec24..ff2e2f157 100644
--- a/modules/client/front/billing-data/index.html
+++ b/modules/client/front/billing-data/index.html
@@ -66,7 +66,7 @@
@@ -108,53 +108,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/modules/client/front/billing-data/index.js b/modules/client/front/billing-data/index.js
index 2dda347b9..7056fa566 100644
--- a/modules/client/front/billing-data/index.js
+++ b/modules/client/front/billing-data/index.js
@@ -37,17 +37,8 @@ export default class Controller extends Section {
return payMethod || iban || dueDay;
}
- onAddEntityClick(event) {
- event.preventDefault();
- this.newBankEntity = {
- countryFk: Number.parseInt(this.client.countryFk)
- };
- this.$.bankEntityDialog.show();
- }
-
- onBankEntityAccept() {
- return this.$http.post(`BankEntities`, this.newBankEntity)
- .then(res => this.client.bankEntityFk = res.data.id);
+ onAccept(data) {
+ this.client.bankEntityFk = data.id;
}
get ibanCountry() {
diff --git a/modules/client/front/billing-data/index.spec.js b/modules/client/front/billing-data/index.spec.js
index 95700cb5a..2e9e8ba97 100644
--- a/modules/client/front/billing-data/index.spec.js
+++ b/modules/client/front/billing-data/index.spec.js
@@ -35,20 +35,12 @@ describe('Client', () => {
});
});
- describe('onBankEntityAccept()', () => {
- it('should request to create a new bank entity', () => {
- let newBankEntity = {
- name: 'My new bank entity',
- bic: 'ES123',
- countryFk: 1,
- id: 999
- };
- controller.newBankEntity = newBankEntity;
- $httpBackend.expectPOST('BankEntities', newBankEntity).respond({id: 999});
- controller.onBankEntityAccept();
- $httpBackend.flush();
+ describe('onAccept()', () => {
+ it('should assign the response id to the client bankEntityFk', () => {
+ const expectedResponse = {id: 999};
+ controller.onAccept(expectedResponse);
- expect(controller.client.bankEntityFk).toEqual(newBankEntity.id);
+ expect(controller.client.bankEntityFk).toEqual(expectedResponse.id);
});
});
diff --git a/modules/client/front/billing-data/locale/es.yml b/modules/client/front/billing-data/locale/es.yml
index a7ecbbdae..0052ee403 100644
--- a/modules/client/front/billing-data/locale/es.yml
+++ b/modules/client/front/billing-data/locale/es.yml
@@ -14,5 +14,4 @@ Received core VNL: Recibido core VNL
Received B2B VNL: Recibido B2B VNL
Save: Guardar
New bank entity: Nueva entidad bancaria
-Name can't be empty: El nombre no puede quedar vacío
-Entity Code: Código
\ No newline at end of file
+Name can't be empty: El nombre no puede quedar vacío
\ No newline at end of file
diff --git a/modules/client/front/fiscal-data/index.html b/modules/client/front/fiscal-data/index.html
index 93a3c9cb6..f3fd42e76 100644
--- a/modules/client/front/fiscal-data/index.html
+++ b/modules/client/front/fiscal-data/index.html
@@ -182,8 +182,7 @@
vn-one
label="Verified data"
ng-model="$ctrl.client.isTaxDataChecked"
- vn-acl="salesAssistant"
- disabled="!$ctrl.client.businessTypeFk">
+ vn-acl="salesAssistant">
diff --git a/modules/client/front/summary/index.html b/modules/client/front/summary/index.html
index 81f80d370..3c5a8d3e5 100644
--- a/modules/client/front/summary/index.html
+++ b/modules/client/front/summary/index.html
@@ -5,7 +5,7 @@
filter="::$ctrl.ticketFilter"
limit="5"
data="tickets"
- order="shipped DESC">
+ order="shipped DESC, id">
@@ -314,7 +314,7 @@
{{::ticket.nickname}}
-
+
{{::ticket.agencyMode.name}}
diff --git a/modules/entry/back/methods/entry/latestBuysFilter.js b/modules/entry/back/methods/entry/latestBuysFilter.js
index d59e34e64..cbf9e3b6a 100644
--- a/modules/entry/back/methods/entry/latestBuysFilter.js
+++ b/modules/entry/back/methods/entry/latestBuysFilter.js
@@ -115,7 +115,6 @@ module.exports = Self => {
const stmts = [];
let stmt;
- stmts.push('CALL cache.last_buy_refresh(FALSE)');
stmts.push('CALL cache.visible_refresh(@calc_id, FALSE, 1)');
stmt = new ParameterizedSQL(`
diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js
index f06fd0db5..cff36a223 100644
--- a/modules/item/back/methods/item/filter.js
+++ b/modules/item/back/methods/item/filter.js
@@ -57,6 +57,11 @@ module.exports = Self => {
arg: 'stemMultiplier',
type: 'integer',
description: 'The item multiplier',
+ },
+ {
+ arg: 'landed',
+ type: 'date',
+ description: 'The item last buy landed date',
}
],
returns: {
@@ -114,6 +119,8 @@ module.exports = Self => {
return {'ori.code': value};
case 'intrastat':
return {'intr.description': value};
+ case 'landed':
+ return {'lb.landed': value};
}
});
@@ -146,7 +153,8 @@ module.exports = Self => {
ic.name AS category,
intr.description AS intrastat,
b.grouping,
- b.packing
+ b.packing,
+ lb.landing AS landed
FROM item i
LEFT JOIN itemType it ON it.id = i.typeFk
LEFT JOIN itemCategory ic ON ic.id = it.categoryFk
diff --git a/modules/item/front/index/index.html b/modules/item/front/index/index.html
index 36ef4839a..5b1e7fdc8 100644
--- a/modules/item/front/index/index.html
+++ b/modules/item/front/index/index.html
@@ -26,6 +26,7 @@
DensityMultiplierActive
+ Landed
@@ -87,6 +88,7 @@
ng-model="::item.isActive">
+ {{::item.landed | date:'dd/MM/yyyy'}} {
MINUTE(z.hour) AS zoneMinute,
z.name AS zoneName,
z.id AS zoneFk,
- CAST(z.hour AS CHAR) AS hour
+ CAST(z.hour AS CHAR) AS hour,
+ TIME_FORMAT(zed.etc, '%H:%i') AS practicalHour
FROM ticket t
LEFT JOIN invoiceOut io ON t.refFk = io.ref
LEFT JOIN zone z ON z.id = t.zoneFk
@@ -235,7 +236,8 @@ module.exports = Self => {
LEFT JOIN state st ON st.id = ts.stateFk
LEFT JOIN client c ON c.id = t.clientFk
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
- LEFT JOIN account.user u ON u.id = wk.userFk`);
+ LEFT JOIN account.user u ON u.id = wk.userFk
+ LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`);
if (args.orderFk) {
stmt.merge({
diff --git a/modules/monitor/front/index/locale/es.yml b/modules/monitor/front/index/locale/es.yml
index 160392245..4eef3c93f 100644
--- a/modules/monitor/front/index/locale/es.yml
+++ b/modules/monitor/front/index/locale/es.yml
@@ -6,4 +6,6 @@ Delete selected elements: Eliminar los elementos seleccionados
All the selected elements will be deleted. Are you sure you want to continue?: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar?
Component lack: Faltan componentes
Minimize/Maximize: Minimizar/Maximizar
-Problems: Problemas
\ No newline at end of file
+Problems: Problemas
+Theoretical: Teórica
+Practical: Práctica
\ No newline at end of file
diff --git a/modules/monitor/front/index/tickets/index.html b/modules/monitor/front/index/tickets/index.html
index 2d2c5fa78..82adf2765 100644
--- a/modules/monitor/front/index/tickets/index.html
+++ b/modules/monitor/front/index/tickets/index.html
@@ -37,8 +37,9 @@
ClientSalespersonDate
- Hour
- Closure
+ Prep.
+ Theoretical
+ PracticalProvinceStateZone
@@ -112,6 +113,7 @@
{{::ticket.shipped | date: 'HH:mm'}}{{::ticket.zoneLanding | date: 'HH:mm'}}
+ {{::ticket.practicalHour | date: 'HH:mm'}}{{::ticket.province}}
+
+
+
+
+
+ on-accept="$ctrl.onAccept($data)">
this.$.watcher.notifySaved());
+ onAccept(data) {
+ const accounts = this.supplierAccounts;
+ const targetAccount = accounts[data.index];
+ targetAccount.bankEntityFk = data.id;
}
onSubmit() {
diff --git a/modules/supplier/front/account/index.spec.js b/modules/supplier/front/account/index.spec.js
index 6491da7d0..ba21801e1 100644
--- a/modules/supplier/front/account/index.spec.js
+++ b/modules/supplier/front/account/index.spec.js
@@ -5,17 +5,9 @@ import crudModel from 'core/mocks/crud-model';
describe('Supplier Component vnSupplierAccount', () => {
let $scope;
let controller;
- let $httpBackend;
- let $httpParamSerializer;
- let vnApp;
-
beforeEach(ngModule('supplier'));
- beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_, _vnApp_) => {
- vnApp = _vnApp_;
- $httpBackend = _$httpBackend_;
- $httpParamSerializer = _$httpParamSerializer_;
- jest.spyOn(vnApp, 'showError');
+ beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
$scope = $rootScope.$new();
$scope.model = crudModel;
$scope.watcher = watcher;
@@ -34,58 +26,20 @@ describe('Supplier Component vnSupplierAccount', () => {
};
}));
- describe('showBankEntity()', () => {
- it('should do nothing if it default is prevented', () => {
- const event = {
- defaultPrevented: true,
- preventDefault: () => {}
- };
- jest.spyOn(event, 'preventDefault');
- jest.spyOn(controller.$.bankEntity, 'open');
+ describe('onAccept()', () => {
+ it('should set the created bank entity id into the target account', () => {
+ controller.supplierAccounts = [{}, {}, {}];
- controller.showBankEntity(event);
-
- expect(event.preventDefault).not.toHaveBeenCalledWith();
- expect(controller.$.bankEntity.open).not.toHaveBeenCalledWith();
- });
-
- it('should call preventDefault() and open() when the default is not prevented', () => {
- const event = {
- defaultPrevented: false,
- preventDefault: () => {}
+ const data = {
+ id: 999,
+ index: 1
};
- jest.spyOn(event, 'preventDefault');
- jest.spyOn(controller.$.bankEntity, 'open');
+ controller.onAccept(data);
- controller.showBankEntity(event);
+ const targetAccount = controller.supplierAccounts[data.index];
- expect(event.preventDefault).toHaveBeenCalledWith();
- expect(controller.$.bankEntity.open).toHaveBeenCalledWith();
- });
-
- it('should set pay method to wireTransfer', () => {
- controller.bankEntity = {
- name: 'My new bank entity',
- bic: 'ES1234',
- countryFk: 1,
- id: 2200
- };
- const expectedParams = {
- filter: {
- where: {code: 'wireTransfer'}
- }
- };
- const serializedParams = $httpParamSerializer(expectedParams);
-
- $httpBackend.when('GET', `payMethods/findOne?${serializedParams}`).respond({id: 1});
-
- const query = `SupplierAccounts/${controller.$.bankEntity.id}/createBankEntity`;
- $httpBackend.expectPATCH(query).respond({id: 2200});
- controller.onBankEntityAccept();
- $httpBackend.flush();
-
- expect(controller.supplierAccount.bankEntityFk).toEqual(controller.bankEntity.id);
+ expect(targetAccount.bankEntityFk).toEqual(data.id);
});
});
diff --git a/modules/ticket/front/main/index.html b/modules/ticket/front/main/index.html
index 8e9af1e12..590d33887 100644
--- a/modules/ticket/front/main/index.html
+++ b/modules/ticket/front/main/index.html
@@ -2,7 +2,7 @@
vn-id="model"
url="Tickets/filter"
limit="20"
- order="shippedDate DESC, shippedHour ASC, zoneLanding ASC">
+ order="shippedDate DESC, shippedHour ASC, zoneLanding ASC, id">
Festive
+
+
+
+ Current day
+
diff --git a/modules/worker/front/calendar/locale/es.yml b/modules/worker/front/calendar/locale/es.yml
index 1ff12358c..464ad9750 100644
--- a/modules/worker/front/calendar/locale/es.yml
+++ b/modules/worker/front/calendar/locale/es.yml
@@ -7,4 +7,5 @@ of: de
days: días
Choose an absence type from the right menu: Elige un tipo de ausencia desde el menú de la derecha
To start adding absences, click an absence type from the right menu and then on the day you want to add an absence: Para empezar a añadir ausencias, haz clic en un tipo de ausencia desde el menu de la derecha y después en el día que quieres añadir la ausencia
-You can just add absences within the current year: Solo puedes añadir ausencias dentro del año actual
\ No newline at end of file
+You can just add absences within the current year: Solo puedes añadir ausencias dentro del año actual
+Current day: Día actual
\ No newline at end of file
diff --git a/modules/worker/front/calendar/style.scss b/modules/worker/front/calendar/style.scss
index b778a68b5..a028c8c30 100644
--- a/modules/worker/front/calendar/style.scss
+++ b/modules/worker/front/calendar/style.scss
@@ -41,12 +41,20 @@ vn-worker-calendar {
border-color: rgba(0, 0, 0, 0.3);
border-bottom: 1px solid rgba(0, 0, 0, 0.3);
}
-
- .festive {
- background-color:white;
- border: 2px solid $color-alert;
+
+ vn-avatar.festive,
+ vn-avatar.today {
+ background-color: $color-font-dark;
width: 24px;
min-width: 24px;
height: 24px
}
+
+ vn-avatar.festive {
+ border: 2px solid $color-alert
+ }
+
+ vn-avatar.today {
+ border: 2px solid $color-font-link
+ }
}
diff --git a/print/core/smtp.js b/print/core/smtp.js
index c42a080f5..5fb5c4a2c 100644
--- a/print/core/smtp.js
+++ b/print/core/smtp.js
@@ -25,7 +25,7 @@ module.exports = {
throw err;
}).finally(async() => {
await db.rawSql(`
- INSERT INTO vn.mail (sender, replyTo, sent, subject, body, status)
+ INSERT INTO vn.mail (receiver, replyTo, sent, subject, body, status)
VALUES (?, ?, 1, ?, ?, ?)`, [
options.to,
options.replyTo,
diff --git a/print/methods/closure.js b/print/methods/closure.js
index 4c6f91b58..daa2d5e7c 100644
--- a/print/methods/closure.js
+++ b/print/methods/closure.js
@@ -143,8 +143,24 @@ module.exports = app => {
AND t.refFk IS NULL
GROUP BY e.ticketFk`, [reqArgs.routeId]);
const ticketIds = tickets.map(ticket => ticket.id);
-
await closeAll(ticketIds, reqArgs);
+
+ // Send route report to the agency
+ const agencyMail = await db.findValue(`
+ SELECT am.reportMail
+ FROM route r
+ JOIN agencyMode am ON am.id = r.agencyModeFk
+ WHERE r.id = ?`, [reqArgs.routeId]);
+
+ if (agencyMail) {
+ const args = Object.assign({
+ routeId: reqArgs.routeId,
+ recipient: agencyMail
+ }, reqArgs);
+
+ const email = new Email('driver-route', args);
+ await email.send();
+ }
} catch (error) {
next(error);
}
diff --git a/print/templates/email/claim-pickup-order/locale/es.yml b/print/templates/email/claim-pickup-order/locale/es.yml
index 1d49b2b2b..fe08fb0a8 100644
--- a/print/templates/email/claim-pickup-order/locale/es.yml
+++ b/print/templates/email/claim-pickup-order/locale/es.yml
@@ -2,22 +2,4 @@ subject: Orden de recogida
title: Orden de recogida
description:
dear: Estimado cliente
- instructions: Aqui tienes tu orden de recogida.
-sections:
- howToBuy:
- title: Cómo hacer un pedido
- description: 'Para realizar un pedido en nuestra web, debes configurarlo indicando:'
- requeriments:
- - Si quieres recibir el pedido (por agencia o por nuestro propio reparto) o si
- lo prefieres recoger en alguno de nuestros almacenes.
- - La fecha en la que quieres recibir el pedido (se preparará el día anterior).
- - La dirección de entrega o el almacén donde quieres recoger el pedido.
- stock: En nuestra web y aplicaciones puedes visualizar el stock disponible de
- flor cortada, verdes, plantas, complementos y artificial. Ten en cuenta que
- dicho stock puede variar en función de la fecha seleccionada al configurar el
- pedido. Es importante CONFIRMAR los pedidos para que la mercancía quede reservada.
- delivery: El reparto se realiza de lunes a sábado según la zona en la que te encuentres.
- Por regla general, los pedidos que se entregan por agencia, deben estar confirmados
- y pagados antes de las 17h del día en que se preparan (el día anterior a recibirlos),
- aunque esto puede variar si el pedido se envía a través de nuestro reparto y
- según la zona.
+ instructions: Aqui tienes tu orden de recogida.
\ No newline at end of file
diff --git a/print/templates/reports/delivery-note/delivery-note.html b/print/templates/reports/delivery-note/delivery-note.html
index 771f1fd0c..36d9abde1 100644
--- a/print/templates/reports/delivery-note/delivery-note.html
+++ b/print/templates/reports/delivery-note/delivery-note.html
@@ -118,20 +118,20 @@
-