#1674 ticket.descriptor stowaway sólo debe de aparecer la opcion en el menu en el almacen
gitea/salix/dev This commit looks good Details

This commit is contained in:
Bernat 2019-09-06 09:47:58 +02:00
parent 751c945575
commit e8cb57e27a
13 changed files with 170 additions and 73 deletions

View File

@ -21,6 +21,9 @@
}, },
"isManaged":{ "isManaged":{
"type": "boolean" "type": "boolean"
},
"hasStowaway":{
"type": "boolean"
} }
}, },
"acls": [ "acls": [

View File

@ -0,0 +1,26 @@
ALTER TABLE `vn2008`.`warehouse`
ADD COLUMN `hasStowaway` TINYINT(1) NOT NULL DEFAULT 0 AFTER `hasConfectionTeam`;
-- UPDATE `vn2008`.`warehouse` SET `hasStowaway` = '1' WHERE (`id` = '1');
CREATE
OR REPLACE ALGORITHM = UNDEFINED
DEFINER = `root`@`%`
SQL SECURITY DEFINER
VIEW `vn`.`warehouse` AS
SELECT
`t`.`id` AS `id`,
`t`.`name` AS `name`,
`t`.`inventario` AS `isInventory`,
`t`.`fuente` AS `isFeedStock`,
`t`.`is_comparative` AS `isComparative`,
`t`.`comisionantes` AS `hasComission`,
`t`.`reserve` AS `hasAvailable`,
`t`.`isManaged` AS `isManaged`,
`t`.`tpv` AS `isForTicket`,
`t`.`hasStowaway` AS `hasStowaway`
FROM
`vn2008`.`warehouse` `t`;

View File

@ -56,13 +56,13 @@ INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`,
(19,'Francia', 1, 'FR', 1, 25), (19,'Francia', 1, 'FR', 1, 25),
(30,'Canarias', 1, 'IC', 1, 22); (30,'Canarias', 1, 'IC', 1, 22);
INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`) INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasStowaway`)
VALUES VALUES
(1, 'Warehouse One', 1, 1, 1, 1), (1, 'Warehouse One', 1, 1, 1, 1, 1),
(2, 'Warehouse Two', 1, 1, 1, 1), (2, 'Warehouse Two', 1, 1, 1, 1, 0),
(3, 'Warehouse Three', 1, 1, 1, 1), (3, 'Warehouse Three', 1, 1, 1, 1, 0),
(4, 'Warehouse Four', 1, 1, 1, 1), (4, 'Warehouse Four', 1, 1, 1, 1, 0),
(5, 'Warehouse Five', 1, 1, 1, 1); (5, 'Warehouse Five', 1, 1, 1, 1, 0);
INSERT INTO `vn`.`warehouseAlias`(`id`, `name`) INSERT INTO `vn`.`warehouseAlias`(`id`, `name`)
VALUES VALUES

View File

@ -110,6 +110,7 @@ describe('Ticket descriptor path', () => {
it('should open the add stowaway dialog', async() => { it('should open the add stowaway dialog', async() => {
const isVisible = await nightmare const isVisible = await nightmare
.waitForSpinnerLoad()
.waitToClick(selectors.ticketDescriptor.moreMenu) .waitToClick(selectors.ticketDescriptor.moreMenu)
.waitToClick(selectors.ticketDescriptor.moreMenuAddStowaway) .waitToClick(selectors.ticketDescriptor.moreMenuAddStowaway)
.wait(selectors.ticketDescriptor.addStowawayDialogFirstTicket) .wait(selectors.ticketDescriptor.addStowawayDialogFirstTicket)

View File

@ -101,5 +101,6 @@
"This ticket is already on weekly tickets": "Este ticket ya está en tickets programados", "This ticket is already on weekly tickets": "Este ticket ya está en tickets programados",
"Ticket id cannot be blank": "El id de ticket no puede quedar en blanco", "Ticket id cannot be blank": "El id de ticket no puede quedar en blanco",
"Weekday cannot be blank": "El día de la semana no puede quedar en blanco", "Weekday cannot be blank": "El día de la semana no puede quedar en blanco",
"You can't delete a confirmed order": "No puedes borrar un pedido confirmado" "You can't delete a confirmed order": "No puedes borrar un pedido confirmado",
"Can't create stowaway for this ticket": "No se puede crear un polizon para este ticket"
} }

View File

@ -0,0 +1,31 @@
module.exports = Self => {
Self.remoteMethod('canBeStowawayed', {
description: 'Returns if a ticket can be stowawayed',
accessType: 'READ',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'ticket id',
http: {source: 'path'}
}],
returns: {
root: true
},
http: {
path: `/:id/canBeStowawayed`,
verb: 'GET'
}
});
Self.canBeStowawayed = async id => {
const ticket = await Self.app.models.Ticket.findById(id);
const warehouse = await Self.app.models.Warehouse.findById(ticket.warehouseFk);
if (warehouse && warehouse.hasStowaway)
return true;
return false;
};
};

View File

@ -1,3 +1,5 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.remoteMethod('getPossibleStowaways', { Self.remoteMethod('getPossibleStowaways', {
description: 'Returns mana of a salesperson of a ticket', description: 'Returns mana of a salesperson of a ticket',
@ -19,6 +21,11 @@ module.exports = Self => {
}); });
Self.getPossibleStowaways = async ticketFk => { Self.getPossibleStowaways = async ticketFk => {
let canStowaway = await Self.app.models.Ticket.canBeStowawayed(ticketFk);
if (!canStowaway)
throw new UserError(`Can't create stowaway for this ticket`);
let ship = await Self.app.models.Ticket.findById(ticketFk); let ship = await Self.app.models.Ticket.findById(ticketFk);
if (!ship || !ship.shipped) if (!ship || !ship.shipped)

View File

@ -0,0 +1,17 @@
const app = require('vn-loopback/server/server');
describe('ticket canBeStowawayed()', () => {
it('should return true if the ticket warehouse have hasStowaway equal 1', async() => {
const ticketId = 16;
let canStowaway = await app.models.Ticket.canBeStowawayed(ticketId);
expect(canStowaway).toBeTruthy();
});
it('should return false if the ticket warehouse dont have hasStowaway equal 0', async() => {
const ticketId = 10;
let canStowaway = await app.models.Ticket.canBeStowawayed(ticketId);
expect(canStowaway).toBeFalsy();
});
});

View File

@ -1,6 +1,13 @@
const LoopBackContext = require('loopback-context'); const LoopBackContext = require('loopback-context');
const UserError = require('vn-loopback/util/user-error');
module.exports = function(Self) { module.exports = function(Self) {
Self.observe('before save', async function(ctx) { Self.observe('before save', async function(ctx) {
let isStowaway = await Self.app.models.Ticket.canBeStowawayed(ctx.instance.id);
if (!isStowaway)
throw new UserError(`Can't create stowaway for this ticket`);
if (ctx.isNewInstance) { if (ctx.isNewInstance) {
let where = { let where = {
code: 'BOARDING' code: 'BOARDING'

View File

@ -25,6 +25,7 @@ module.exports = Self => {
require('../methods/ticket/uploadFile')(Self); require('../methods/ticket/uploadFile')(Self);
require('../methods/ticket/addSale')(Self); require('../methods/ticket/addSale')(Self);
require('../methods/ticket/transferSales')(Self); require('../methods/ticket/transferSales')(Self);
require('../methods/ticket/canBeStowawayed')(Self);
Self.observe('before save', async function(ctx) { Self.observe('before save', async function(ctx) {
if (ctx.isNewInstance) return; if (ctx.isNewInstance) return;

View File

@ -156,7 +156,6 @@ describe('Ticket', () => {
$httpBackend.when('GET', `/api/Clients/${clientId}/addresses?filter=${filter}`).respond(200); $httpBackend.when('GET', `/api/Clients/${clientId}/addresses?filter=${filter}`).respond(200);
$httpBackend.expect('GET', `/api/Clients/${clientId}/addresses?filter=${filter}`); $httpBackend.expect('GET', `/api/Clients/${clientId}/addresses?filter=${filter}`);
controller.onChangeClient(clientId); controller.onChangeClient(clientId);
$httpBackend.flush(); $httpBackend.flush();
}); });
@ -175,66 +174,11 @@ describe('Ticket', () => {
$httpBackend.when('GET', `/api/Zones/${zoneId}`).respond(200); $httpBackend.when('GET', `/api/Zones/${zoneId}`).respond(200);
$httpBackend.expect('GET', `/api/Zones/${zoneId}`); $httpBackend.expect('GET', `/api/Zones/${zoneId}`);
controller.onChangeZone(zoneId); controller.onChangeZone(zoneId);
$httpBackend.flush(); $httpBackend.flush();
}); });
}); });
/* it('should return an available agency', async() => {
const landed = new Date();
const agencyModeId = 7;
controller._ticket = {
id: 1,
landed: landed,
addressFk: 121,
agencyModeFk: agencyModeId,
warehouseFk: 1
};
let params = {
landed: landed,
addressFk: 121,
agencyModeFk: agencyModeId,
warehouseFk: 1
};
let serializedParams = $httpParamSerializer(params);
$httpBackend.when('GET', `/api/Agencies/getShipped?${serializedParams}`).respond(200);
$httpBackend.expect('GET', `/api/Agencies/getShipped?${serializedParams}`);
controller.onChangeAgencyMode(agencyModeId);
$httpBackend.flush();
});
it('should throw a user error', async() => {
spyOn(controller.vnApp, 'showMessage');
const landed = new Date();
const agencyModeId = 7;
controller._ticket = {
id: 1,
landed: landed,
addressFk: 121,
agencyModeFk: agencyModeId,
warehouseFk: 1
};
let params = {
landed: landed,
addressFk: 121,
agencyModeFk: agencyModeId,
warehouseFk: 1
};
let serializedParams = $httpParamSerializer(params);
$httpBackend.when('GET', `/api/Agencies/getShipped?${serializedParams}`).respond(null);
$httpBackend.expect('GET', `/api/Agencies/getShipped?${serializedParams}`);
controller.onChangeAgencyMode(agencyModeId);
$httpBackend.flush();
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('No delivery zone available for this parameters');
}); */
describe('isFormInvalid()', () => { describe('isFormInvalid()', () => {
it('should check if all form fields are valid', () => { it('should check if all form fields are valid', () => {
controller.ticket = { controller.ticket = {

View File

@ -18,7 +18,7 @@ class Controller {
{ {
name: 'Add stowaway', name: 'Add stowaway',
callback: this.showAddStowaway, callback: this.showAddStowaway,
show: () => this.isTicketModule() show: () => this.canShowStowaway
}, },
{ {
name: 'Remove stowaway', name: 'Remove stowaway',
@ -40,6 +40,14 @@ class Controller {
]; ];
} }
set canShowStowaway(value) {
this._canShowStowaway = value;
}
get canShowStowaway() {
return this._canShowStowaway;
}
showChangeShipped() { showChangeShipped() {
if (!this.isEditable) { if (!this.isEditable) {
this.vnApp.showError(this.$translate.instant('This ticket can\'t be modified')); this.vnApp.showError(this.$translate.instant('This ticket can\'t be modified'));
@ -62,12 +70,24 @@ class Controller {
isTicketModule() { isTicketModule() {
let path = this.$state.getCurrentPath(); let path = this.$state.getCurrentPath();
if (path[1].state.name === 'ticket') const isTicket = path[1].state.name === 'ticket';
if (isTicket)
return true; return true;
return false; return false;
} }
canStowaway() {
if (!this.isTicketModule()) return;
this.$http.get(`/api/Tickets/${this.ticket.id}/canBeStowawayed`).then(response => {
if (response.data === true)
return this.canShowStowaway = true;
return this.canShowStowaway = false;
});
}
shouldShowRemoveStowaway() { shouldShowRemoveStowaway() {
if (!this._ticket || !this.isTicketModule()) if (!this._ticket || !this.isTicketModule())
return false; return false;
@ -153,6 +173,8 @@ class Controller {
set ticket(value) { set ticket(value) {
this._ticket = value; this._ticket = value;
if (value)
this.canStowaway();
if (!value) return; if (!value) return;

View File

@ -3,13 +3,21 @@ import './index.js';
describe('Ticket Component vnTicketDescriptor', () => { describe('Ticket Component vnTicketDescriptor', () => {
let $httpBackend; let $httpBackend;
let controller; let controller;
let $state;
beforeEach(ngModule('ticket')); beforeEach(ngModule('ticket'));
beforeEach(angular.mock.inject(($componentController, _$httpBackend_) => { beforeEach(angular.mock.inject(($componentController, _$state_, _$httpBackend_) => {
$state = _$state_;
$state.getCurrentPath = () => {
return [
{state: {}},
{state: {name: 'ticket'}}
];
};
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
controller = $componentController('vnTicketDescriptor'); controller = $componentController('vnTicketDescriptor', {$state});
controller.ticket = {id: 2, invoiceOut: {id: 1}}; controller._ticket = {id: 2, invoiceOut: {id: 1}};
controller.cardReload = ()=> { controller.cardReload = ()=> {
return true; return true;
}; };
@ -25,7 +33,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
}); });
}); });
describe('addTurn(day)', () => { describe('addTurn()', () => {
it('should make a query and call $.addTurn.hide() and vnApp.showSuccess()', () => { it('should make a query and call $.addTurn.hide() and vnApp.showSuccess()', () => {
controller.$scope.addTurn = {hide: () => {}}; controller.$scope.addTurn = {hide: () => {}};
spyOn(controller.$scope.addTurn, 'hide'); spyOn(controller.$scope.addTurn, 'hide');
@ -57,7 +65,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
}); });
}); });
describe('deleteTicket(response)', () => { describe('deleteTicket()', () => {
it('should make a query and call vnApp.showSuccess() if the response is ACCEPT', () => { it('should make a query and call vnApp.showSuccess() if the response is ACCEPT', () => {
spyOn(controller.$state, 'go'); spyOn(controller.$state, 'go');
spyOn(controller.vnApp, 'showSuccess'); spyOn(controller.vnApp, 'showSuccess');
@ -81,7 +89,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
}); });
}); });
describe('makeInvoice(response)', () => { describe('makeInvoice()', () => {
it('should make a query and call $state.reload() method if the response is ACCEPT', () => { it('should make a query and call $state.reload() method if the response is ACCEPT', () => {
spyOn(controller.$state, 'reload'); spyOn(controller.$state, 'reload');
spyOn(controller.vnApp, 'showSuccess'); spyOn(controller.vnApp, 'showSuccess');
@ -96,7 +104,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
}); });
}); });
describe('regenerateInvoice(response)', () => { describe('regenerateInvoice()', () => {
it('should make a query and show a success snackbar if the response is ACCEPT', () => { it('should make a query and show a success snackbar if the response is ACCEPT', () => {
spyOn(controller.vnApp, 'showSuccess'); spyOn(controller.vnApp, 'showSuccess');
@ -109,7 +117,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
}); });
}); });
describe('changeShipped(response)', () => { describe('changeShipped()', () => {
it('should make a query and change the shipped hour if the response is ACCEPT', () => { it('should make a query and change the shipped hour if the response is ACCEPT', () => {
controller.ticket.id = 12; controller.ticket.id = 12;
spyOn(controller.vnApp, 'showSuccess'); spyOn(controller.vnApp, 'showSuccess');
@ -124,4 +132,33 @@ describe('Ticket Component vnTicketDescriptor', () => {
expect(controller.cardReload).toHaveBeenCalledWith(); expect(controller.cardReload).toHaveBeenCalledWith();
}); });
}); });
describe('canStowaway()', () => {
it('should make a query and return if the ticket can be stowawayed', () => {
controller.ticket.id = 16;
spyOn(controller, 'isTicketModule').and.callThrough();
$httpBackend.when('GET', '/api/Tickets/16/canBeStowawayed').respond(true);
$httpBackend.expect('GET', '/api/Tickets/16/canBeStowawayed').respond(true);
controller.canStowaway();
$httpBackend.flush();
expect(controller.canShowStowaway).toBeTruthy();
expect(controller.isTicketModule).toHaveBeenCalledWith();
});
it('should not make a query if is not on the ticket module', () => {
controller.ticket.id = 16;
$state.getCurrentPath = () => {
return [
{state: {}},
{state: {name: 'client'}}
];
};
spyOn(controller, 'isTicketModule').and.callThrough();
controller.canStowaway();
expect(controller.canShowStowaway).toBeUndefined();
expect(controller.isTicketModule).toHaveBeenCalledWith();
});
});
}); });