#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
gitea/salix/dev This commit looks good
Details
This commit is contained in:
parent
751c945575
commit
e8cb57e27a
|
@ -21,6 +21,9 @@
|
||||||
},
|
},
|
||||||
"isManaged":{
|
"isManaged":{
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"hasStowaway":{
|
||||||
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"acls": [
|
"acls": [
|
||||||
|
|
|
@ -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`;
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
};
|
||||||
|
};
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
|
@ -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'
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue