clone feature for routes index

This commit is contained in:
Carlos Jimenez Ruiz 2020-12-24 11:31:20 +01:00
parent e70b8a80e1
commit 8ede30398b
8 changed files with 151 additions and 6 deletions

View File

@ -0,0 +1,56 @@
module.exports = Self => {
Self.remoteMethod('clone', {
description: 'Clones the selected routes',
accessType: 'WRITE',
accepts: [
{
arg: 'ids',
type: ['number'],
required: true,
description: 'The routes ids to clone'
},
{
arg: 'started',
type: 'date',
required: true,
description: 'The started date for all routes'
}
],
returns: {
type: ['Object'],
root: true
},
http: {
path: `/clone`,
verb: 'POST'
}
});
Self.clone = async(ids, started) => {
const tx = await Self.beginTransaction({});
try {
const options = {transaction: tx};
const originalRoutes = await Self.find({
where: {id: {inq: ids}},
fields: ['workerFk', 'agencyModeFk', 'vehicleFk', 'description']
}, options);
if (ids.length != originalRoutes.length)
throw new Error(`The amount of routes found don't match`);
const routes = originalRoutes.map(route => {
route.started = started;
route.created = new Date();
return route;
});
const clones = await Self.create(routes, options);
await tx.commit();
return clones;
} catch (e) {
await tx.rollback();
throw e;
}
};
};

View File

@ -0,0 +1,31 @@
const app = require('vn-loopback/server/server');
describe('route clone()', () => {
const startDate = new Date();
it('should throw an error if the amount of ids pased to the clone function do no match the database', async() => {
const ids = [996, 997, 998, 999];
let error;
try {
await app.models.Route.clone(ids, startDate);
} catch (e) {
error = e;
}
expect(error).toBeDefined();
expect(error.message).toEqual(`The amount of routes found don't match`);
});
it('should clone two routes', async() => {
const ids = [1, 2];
const clones = await app.models.Route.clone(ids, startDate);
expect(clones.length).toEqual(2);
// restores
for (const clone of clones)
await app.models.Route.destroyById(clone.id);
});
});

View File

@ -6,6 +6,7 @@ module.exports = Self => {
require('../methods/route/updateVolume')(Self);
require('../methods/route/getDeliveryPoint')(Self);
require('../methods/route/insertTicket')(Self);
require('../methods/route/clone')(Self);
Self.validate('kmStart', validateDistance, {
message: 'Distance must be lesser than 1000'

View File

@ -3,3 +3,5 @@ Date started: Fecha inicio
Km start: Km de inicio
Km end: Km de fin
Description: Descripción
Hour started: Hora inicio
Hour finished: Hora fin

View File

@ -44,7 +44,7 @@
</vn-td>
<vn-td>{{::route.agencyName | dashIfEmpty}}</vn-td>
<vn-td>{{::route.vehiclePlateNumber | dashIfEmpty}}</vn-td>
<vn-td expand>{{::route.created | date:'dd/MM/yyyy' | dashIfEmpty}}</vn-td>
<vn-td expand>{{::route.created | dashIfEmpty | date:'dd/MM/yyyy'}}</vn-td>
<vn-td number>{{::route.m3 | dashIfEmpty}}</vn-td>
<vn-td>{{::route.description | dashIfEmpty}}</vn-td>
<vn-td>
@ -59,19 +59,26 @@
</vn-table>
</vn-card>
</vn-data-viewer>
<vn-popup vn-id="summary">
<vn-route-summary
route="$ctrl.routeSelected">
</vn-route-summary>
</vn-popup>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>
</vn-data-viewer>
<div fixed-bottom-right>
<vn-vertical style="align-items: center;">
<vn-button class="round sm vn-mb-sm"
icon="icon-clone"
ng-show="$ctrl.totalChecked > 0"
ng-click="$ctrl.openClonationDialog()"
vn-tooltip="Clone selected routes"
tooltip-position="left">
</vn-button>
<vn-button class="round sm vn-mb-sm"
icon="cloud_download"
ng-show="$ctrl.totalChecked > 0"
@ -79,7 +86,6 @@
vn-tooltip="Download selected routes as PDF"
tooltip-position="left">
</vn-button>
<a ui-sref="route.create" vn-bind="+">
<vn-button class="round md vn-mb-sm"
icon="add"
@ -89,3 +95,23 @@
</a>
</vn-vertical>
</div>
<!-- Clonation dialog -->
<vn-dialog class="edit"
vn-id="clonationDialog"
on-accept="$ctrl.cloneSelectedRoutes()"
message="Select the starting date">
<tpl-body>
<vn-horizontal>
<vn-date-picker
label="Starting date"
ng-model="$ctrl.startedDate"
required="true">
</vn-date-picker>
</vn-horizontal>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Clone</button>
</tpl-buttons>
</vn-dialog>

View File

@ -40,6 +40,22 @@ export default class Controller extends Section {
});
}
openClonationDialog() {
this.startedDate = new Date();
this.$.clonationDialog.show();
}
cloneSelectedRoutes() {
const routesIds = [];
for (let route of this.checked)
routesIds.push(route.id);
return this.$http.post('Routes/clone', {ids: routesIds, started: this.startedDate}).then(() => {
this.$.model.refresh();
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
onDrop($event) {
const target = $event.target;
const droppable = target.closest(this.droppableElement);

View File

@ -60,6 +60,16 @@ describe('Component vnRouteIndex', () => {
});
});
describe('cloneSelectedRoutes()', () => {
it('should perform an http request to Routes/clone', () => {
controller.startedDate = new Date();
$httpBackend.expect('POST', 'Routes/clone').respond();
controller.cloneSelectedRoutes();
$httpBackend.flush();
});
});
describe('onDrop()', () => {
it('should call the insert method when dragging a ticket number', () => {
jest.spyOn(controller, 'insert');

View File

@ -1,2 +1,5 @@
Vehicle: Vehículo
Download selected routes as PDF: Descargar rutas seleccionadas como PDF
Clone selected routes: Clonar rutas seleccionadas
Select the starting date: Seleccione fecha de inicio
Starting date: Fecha de inicio