7366-travelMigration #3054
|
@ -1,42 +0,0 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
|
||||||
|
|
||||||
describe('Travel create path', () => {
|
|
||||||
let browser;
|
|
||||||
let page;
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
|
||||||
browser = await getBrowser();
|
|
||||||
page = browser.page;
|
|
||||||
await page.loginAndModule('buyer', 'travel');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async() => {
|
|
||||||
await browser.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create a new travel and check it was created with the correct data', async() => {
|
|
||||||
const date = Date.vnNew();
|
|
||||||
date.setDate(15);
|
|
||||||
date.setUTCHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
await page.waitToClick(selectors.travelIndex.newTravelButton);
|
|
||||||
await page.waitForState('travel.create');
|
|
||||||
|
|
||||||
const values = {
|
|
||||||
reference: 'Testing reference',
|
|
||||||
agencyMode: 'inhouse pickup',
|
|
||||||
shipped: date,
|
|
||||||
landed: date,
|
|
||||||
warehouseOut: 'Warehouse One',
|
|
||||||
warehouseIn: 'Warehouse Five'
|
|
||||||
};
|
|
||||||
|
|
||||||
const message = await page.sendForm('vn-travel-create form', values);
|
|
||||||
await page.waitForState('travel.card.basicData');
|
|
||||||
const formValues = await page.fetchForm('vn-travel-basic-data form', Object.keys(values));
|
|
||||||
|
|
||||||
expect(message.isSuccess).toBeTrue();
|
|
||||||
expect(formValues).toEqual(values);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,97 +0,0 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
|
||||||
|
|
||||||
describe('Travel basic data path', () => {
|
|
||||||
let browser;
|
|
||||||
let page;
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
|
||||||
browser = await getBrowser();
|
|
||||||
page = browser.page;
|
|
||||||
await page.loginAndModule('buyer', 'travel');
|
|
||||||
await page.write(selectors.travelIndex.generalSearchFilter, '3');
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
await page.accessToSection('travel.card.basicData');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async() => {
|
|
||||||
await browser.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reach the thermograph section', async() => {
|
|
||||||
await page.waitForState('travel.card.basicData');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set a wrong delivery date then receive an error on submit', async() => {
|
|
||||||
await page.loginAndModule('buyer', 'travel');
|
|
||||||
await page.write(selectors.travelIndex.generalSearchFilter, '4');
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
await page.accessToSection('travel.card.basicData');
|
|
||||||
await page.waitForState('travel.card.basicData');
|
|
||||||
|
|
||||||
const lastMonth = Date.vnNew();
|
|
||||||
lastMonth.setMonth(lastMonth.getMonth() - 2);
|
|
||||||
|
|
||||||
await page.pickDate(selectors.travelBasicData.deliveryDate, lastMonth);
|
|
||||||
await page.waitToClick(selectors.travelBasicData.save);
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Landing cannot be lesser than shipment');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should undo the changes', async() => {
|
|
||||||
await page.clearInput(selectors.travelBasicData.reference);
|
|
||||||
await page.write(selectors.travelBasicData.reference, 'totally pointless ref');
|
|
||||||
await page.waitToClick(selectors.travelBasicData.undoChanges);
|
|
||||||
const result = await page.waitToGetProperty(selectors.travelBasicData.reference, 'value');
|
|
||||||
|
|
||||||
expect(result).toEqual('fourth travel');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should now edit the whole form then save', async() => {
|
|
||||||
await page.clearInput(selectors.travelBasicData.reference);
|
|
||||||
await page.write(selectors.travelBasicData.reference, 'new reference!');
|
|
||||||
await page.autocompleteSearch(selectors.travelBasicData.agency, 'Entanglement');
|
|
||||||
await page.autocompleteSearch(selectors.travelBasicData.outputWarehouse, 'Warehouse Three');
|
|
||||||
await page.autocompleteSearch(selectors.travelBasicData.inputWarehouse, 'Warehouse Four');
|
|
||||||
await page.waitToClick(selectors.travelBasicData.delivered);
|
|
||||||
await page.waitToClick(selectors.travelBasicData.received);
|
|
||||||
await page.waitToClick(selectors.travelBasicData.save);
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reload the section and check the reference was saved', async() => {
|
|
||||||
await page.reloadSection('travel.card.basicData');
|
|
||||||
const result = await page.waitToGetProperty(selectors.travelBasicData.reference, 'value');
|
|
||||||
|
|
||||||
expect(result).toEqual('new reference!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the agency was saved', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.travelBasicData.agency, 'value');
|
|
||||||
|
|
||||||
expect(result).toEqual('Entanglement');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the output warehouse date was saved', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.travelBasicData.outputWarehouse, 'value');
|
|
||||||
|
|
||||||
expect(result).toEqual('Warehouse Three');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the input warehouse date was saved', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.travelBasicData.inputWarehouse, 'value');
|
|
||||||
|
|
||||||
expect(result).toEqual('Warehouse Four');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should check the delivered checkbox was saved even tho it doesn't make sense`, async() => {
|
|
||||||
await page.waitForClassPresent(selectors.travelBasicData.delivered, 'checked');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should check the received checkbox was saved even tho it doesn't make sense`, async() => {
|
|
||||||
await page.waitForClassPresent(selectors.travelBasicData.received, 'checked');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,36 +0,0 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
|
||||||
|
|
||||||
describe('Travel descriptor path', () => {
|
|
||||||
let browser;
|
|
||||||
let page;
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
|
||||||
browser = await getBrowser();
|
|
||||||
page = browser.page;
|
|
||||||
await page.loginAndModule('buyer', 'travel');
|
|
||||||
await page.write(selectors.travelIndex.generalSearchFilter, '3');
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
await page.waitForState('travel.card.summary');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async() => {
|
|
||||||
await browser.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should click the descriptor button to navigate to the travel index showing all travels with current agency', async() => {
|
|
||||||
await page.waitToClick(selectors.travelDescriptor.filterByAgencyButton);
|
|
||||||
await page.waitForState('travel.index');
|
|
||||||
const result = await page.countElement(selectors.travelIndex.anySearchResult);
|
|
||||||
|
|
||||||
expect(result).toBeGreaterThanOrEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should navigate to the first search result', async() => {
|
|
||||||
await page.waitToClick(selectors.travelIndex.firstSearchResult);
|
|
||||||
await page.waitForState('travel.card.summary');
|
|
||||||
const state = await page.getState();
|
|
||||||
|
|
||||||
expect(state).toBe('travel.card.summary');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,42 +0,0 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
|
||||||
|
|
||||||
describe('Travel extra community path', () => {
|
|
||||||
let browser;
|
|
||||||
let page;
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
|
||||||
browser = await getBrowser();
|
|
||||||
page = browser.page;
|
|
||||||
await page.loginAndModule('buyer', 'travel');
|
|
||||||
await page.accessToSection('travel.extraCommunity');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async() => {
|
|
||||||
await browser.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should edit the travel reference and the locked kilograms', async() => {
|
|
||||||
await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter);
|
|
||||||
await page.waitForSpinnerLoad();
|
|
||||||
await page.writeOnEditableTD(selectors.travelExtraCommunity.firstTravelReference, 'edited reference');
|
|
||||||
await page.waitForSpinnerLoad();
|
|
||||||
await page.writeOnEditableTD(selectors.travelExtraCommunity.firstTravelLockedKg, '1500');
|
|
||||||
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reload the index and confirm the reference and locked kg were edited', async() => {
|
|
||||||
await page.accessToSection('travel.index');
|
|
||||||
await page.accessToSection('travel.extraCommunity');
|
|
||||||
await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter);
|
|
||||||
await page.waitForTextInElement(selectors.travelExtraCommunity.firstTravelReference, 'edited reference');
|
|
||||||
const reference = await page.getProperty(selectors.travelExtraCommunity.firstTravelReference, 'innerText');
|
|
||||||
const lockedKg = await page.getProperty(selectors.travelExtraCommunity.firstTravelLockedKg, 'innerText');
|
|
||||||
|
|
||||||
expect(reference).toContain('edited reference');
|
|
||||||
expect(lockedKg).toContain(1500);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,62 +0,0 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
|
||||||
|
|
||||||
describe('Travel search panel path', () => {
|
|
||||||
let browser;
|
|
||||||
let page;
|
|
||||||
let httpRequest;
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
|
||||||
browser = await getBrowser();
|
|
||||||
page = browser.page;
|
|
||||||
await page.loginAndModule('buyer', 'travel');
|
|
||||||
page.on('request', req => {
|
|
||||||
if (req.url().includes(`Travels/filter`))
|
|
||||||
httpRequest = req.url();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async() => {
|
|
||||||
await browser.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should filter using all the fields', async() => {
|
|
||||||
await page.click(selectors.travelIndex.chip);
|
|
||||||
await page.write(selectors.travelIndex.generalSearchFilter, 'travel');
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
|
|
||||||
expect(httpRequest).toContain('search=travel');
|
|
||||||
|
|
||||||
await page.click(selectors.travelIndex.chip);
|
|
||||||
await page.autocompleteSearch(selectors.travelIndex.agencyFilter, 'Entanglement');
|
|
||||||
|
|
||||||
expect(httpRequest).toContain('agencyModeFk');
|
|
||||||
|
|
||||||
await page.click(selectors.travelIndex.chip);
|
|
||||||
await page.autocompleteSearch(selectors.travelIndex.warehouseOutFilter, 'Warehouse One');
|
|
||||||
|
|
||||||
expect(httpRequest).toContain('warehouseOutFk');
|
|
||||||
|
|
||||||
await page.click(selectors.travelIndex.chip);
|
|
||||||
await page.autocompleteSearch(selectors.travelIndex.warehouseInFilter, 'Warehouse Two');
|
|
||||||
|
|
||||||
expect(httpRequest).toContain('warehouseInFk');
|
|
||||||
|
|
||||||
await page.click(selectors.travelIndex.chip);
|
|
||||||
await page.overwrite(selectors.travelIndex.scopeDaysFilter, '15');
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
|
|
||||||
expect(httpRequest).toContain('scopeDays=15');
|
|
||||||
|
|
||||||
await page.click(selectors.travelIndex.chip);
|
|
||||||
await page.autocompleteSearch(selectors.travelIndex.continentFilter, 'Asia');
|
|
||||||
|
|
||||||
expect(httpRequest).toContain('continent');
|
|
||||||
|
|
||||||
await page.click(selectors.travelIndex.chip);
|
|
||||||
await page.write(selectors.travelIndex.totalEntriesFilter, '1');
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
|
|
||||||
expect(httpRequest).toContain('totalEntries=1');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,92 +0,0 @@
|
||||||
<mg-ajax path="Travels/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
data="$ctrl.travel"
|
|
||||||
form="form"
|
|
||||||
save="patch">
|
|
||||||
</vn-watcher>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Warehouses"
|
|
||||||
data="warehouses"
|
|
||||||
order="name">
|
|
||||||
</vn-crud-model>
|
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Reference"
|
|
||||||
ng-model="$ctrl.travel.ref"
|
|
||||||
vn-name="reference">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
ng-model="$ctrl.travel.agencyModeFk"
|
|
||||||
url="AgencyModes"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
label="Agency"
|
|
||||||
vn-name="agencyMode">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-date-picker
|
|
||||||
vn-one
|
|
||||||
label="Shipped"
|
|
||||||
ng-model="$ctrl.travel.shipped"
|
|
||||||
vn-name="shipped">
|
|
||||||
</vn-date-picker>
|
|
||||||
<vn-date-picker
|
|
||||||
vn-one
|
|
||||||
label="Landed"
|
|
||||||
ng-model="$ctrl.travel.landed"
|
|
||||||
vn-name="landed">
|
|
||||||
</vn-date-picker>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
ng-model="$ctrl.travel.warehouseOutFk"
|
|
||||||
vn-name="warehouseOut"
|
|
||||||
data="warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
label="Warehouse Out">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
ng-model="$ctrl.travel.warehouseInFk"
|
|
||||||
vn-name="warehouseIn"
|
|
||||||
data="warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
label="Warehouse In">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-check
|
|
||||||
vn-one
|
|
||||||
label="Delivered"
|
|
||||||
ng-model="$ctrl.travel.isDelivered">
|
|
||||||
</vn-check>
|
|
||||||
<vn-check
|
|
||||||
vn-one
|
|
||||||
label="Received"
|
|
||||||
ng-model="$ctrl.travel.isReceived">
|
|
||||||
</vn-check>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
label="Save">
|
|
||||||
</vn-submit>
|
|
||||||
<vn-button
|
|
||||||
class="cancel"
|
|
||||||
label="Undo changes"
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
ng-click="watcher.loadOriginalData()">
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
|
@ -1,21 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
onSubmit() {
|
|
||||||
return this.$.watcher.submit().then(() =>
|
|
||||||
this.card.reload()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelBasicData', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
travel: '<'
|
|
||||||
},
|
|
||||||
require: {
|
|
||||||
card: '^vnTravelCard'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,28 +0,0 @@
|
||||||
import './index.js';
|
|
||||||
|
|
||||||
describe('Travel Component vnTravelBasicData', () => {
|
|
||||||
let controller;
|
|
||||||
|
|
||||||
beforeEach(angular.mock.module('travel', $translateProvider => {
|
|
||||||
$translateProvider.translations('en', {});
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(inject($componentController => {
|
|
||||||
const $element = angular.element('<vn-travel-basic-data></vn-travel-basic-data>');
|
|
||||||
controller = $componentController('vnTravelBasicData', {$element});
|
|
||||||
controller.card = {reload: () => {}};
|
|
||||||
controller.$.watcher = {submit: () => {}};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('onSubmit()', () => {
|
|
||||||
it('should call the card reload method after the watcher submits', done => {
|
|
||||||
jest.spyOn(controller.card, 'reload');
|
|
||||||
jest.spyOn(controller.$.watcher, 'submit').mockReturnValue(Promise.resolve());
|
|
||||||
|
|
||||||
controller.onSubmit().then(() => {
|
|
||||||
expect(controller.card.reload).toHaveBeenCalledWith();
|
|
||||||
done();
|
|
||||||
}).catch(done.fail);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1 +0,0 @@
|
||||||
Undo changes: Deshacer cambios
|
|
|
@ -1,5 +0,0 @@
|
||||||
<vn-portal slot="menu">
|
|
||||||
<vn-travel-descriptor travel="$ctrl.travel"></vn-travel-descriptor>
|
|
||||||
<vn-left-menu source="card"></vn-left-menu>
|
|
||||||
</vn-portal>
|
|
||||||
<ui-view></ui-view>
|
|
|
@ -1,31 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import ModuleCard from 'salix/components/module-card';
|
|
||||||
|
|
||||||
class Controller extends ModuleCard {
|
|
||||||
reload() {
|
|
||||||
let filter = {
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'warehouseIn',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'name']
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
relation: 'warehouseOut',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'name']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$http.get(`Travels/${this.$params.id}`, {filter})
|
|
||||||
.then(response => this.travel = response.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelCard', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
url="Travels"
|
|
||||||
data="$ctrl.travel"
|
|
||||||
insert-mode="true"
|
|
||||||
form="form">
|
|
||||||
</vn-watcher>
|
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
label="Reference"
|
|
||||||
ng-model="$ctrl.travel.ref"
|
|
||||||
vn-name="reference">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete
|
|
||||||
label="Agency"
|
|
||||||
ng-model="$ctrl.travel.agencyModeFk"
|
|
||||||
vn-name="agencyMode"
|
|
||||||
url="AgencyModes">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-date-picker
|
|
||||||
on-change="$ctrl.onShippedChange(value)"
|
|
||||||
label="Shipped"
|
|
||||||
ng-model="$ctrl.travel.shipped"
|
|
||||||
vn-name="shipped">
|
|
||||||
</vn-date-picker>
|
|
||||||
<vn-date-picker
|
|
||||||
label="Landed"
|
|
||||||
ng-model="$ctrl.travel.landed"
|
|
||||||
vn-name="landed">
|
|
||||||
</vn-date-picker>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete
|
|
||||||
label="Warehouse Out"
|
|
||||||
ng-model="$ctrl.travel.warehouseOutFk"
|
|
||||||
vn-name="warehouseOut"
|
|
||||||
url="Warehouses">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete
|
|
||||||
label="Warehouse In"
|
|
||||||
ng-model="$ctrl.travel.warehouseInFk"
|
|
||||||
vn-name="warehouseIn"
|
|
||||||
url="Warehouses">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
label="Save">
|
|
||||||
</vn-submit>
|
|
||||||
<vn-button
|
|
||||||
class="cancel"
|
|
||||||
label="Cancel"
|
|
||||||
ui-sref="travel.index">
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</form>
|
|
|
@ -1,48 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
$onChanges() {
|
|
||||||
if (this.$params && this.$params.q)
|
|
||||||
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 => {
|
|
||||||
if (!res.data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
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})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelCreate', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,88 +0,0 @@
|
||||||
import './index';
|
|
||||||
import watcher from 'core/mocks/watcher';
|
|
||||||
|
|
||||||
describe('Travel Component vnTravelCreate', () => {
|
|
||||||
let $scope;
|
|
||||||
let $state;
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('travel'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$state_, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$state = _$state_;
|
|
||||||
$scope.watcher = watcher;
|
|
||||||
const $element = angular.element('<vn-travel-create></vn-travel-create>');
|
|
||||||
controller = $componentController('vnTravelCreate', {$element, $scope});
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('onSubmit()', () => {
|
|
||||||
it(`should call submit() on the watcher then expect a callback`, () => {
|
|
||||||
jest.spyOn($state, 'go');
|
|
||||||
|
|
||||||
controller.onSubmit();
|
|
||||||
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('travel.card.basicData', {id: 1234});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('$onChanges()', () => {
|
|
||||||
it('should update the travel data when $params.q is defined', () => {
|
|
||||||
controller.$params = {q: '{"ref": 1,"agencyModeFk": 1}'};
|
|
||||||
|
|
||||||
const params = {q: '{"ref": 1, "agencyModeFk": 1}'};
|
|
||||||
const json = JSON.parse(params.q);
|
|
||||||
|
|
||||||
controller.$onChanges();
|
|
||||||
|
|
||||||
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 do nothing if there's no response data.`, () => {
|
|
||||||
controller.travel = {agencyModeFk: 4};
|
|
||||||
const tomorrow = Date.vnNew();
|
|
||||||
|
|
||||||
const query = `travels/getAverageDays?agencyModeFk=${controller.travel.agencyModeFk}`;
|
|
||||||
$httpBackend.expectGET(query).respond(undefined);
|
|
||||||
controller.onShippedChange(tomorrow);
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.travel.warehouseInFk).toBeUndefined();
|
|
||||||
expect(controller.travel.warehouseOutFk).toBeUndefined();
|
|
||||||
expect(controller.travel.dayDuration).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should fill the fields when it's selected a date and agency.`, () => {
|
|
||||||
controller.travel = {agencyModeFk: 1};
|
|
||||||
const tomorrow = Date.vnNew();
|
|
||||||
tomorrow.setDate(tomorrow.getDate() + 9);
|
|
||||||
const expectedResponse = {
|
|
||||||
id: 8,
|
|
||||||
dayDuration: 9,
|
|
||||||
warehouseInFk: 5,
|
|
||||||
warehouseOutFk: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,59 +0,0 @@
|
||||||
<vn-icon-button
|
|
||||||
icon="more_vert"
|
|
||||||
vn-popover="menu">
|
|
||||||
</vn-icon-button>
|
|
||||||
<vn-menu vn-id="menu">
|
|
||||||
<vn-list>
|
|
||||||
<vn-item
|
|
||||||
id="clone"
|
|
||||||
ng-click="clone.show()"
|
|
||||||
ng-show="::$ctrl.isBuyer"
|
|
||||||
translate>
|
|
||||||
Clone travel
|
|
||||||
</vn-item>
|
|
||||||
<vn-item
|
|
||||||
id="cloneWithEntries"
|
|
||||||
ng-click="cloneWithEntries.show()"
|
|
||||||
ng-show="::$ctrl.isBuyer"
|
|
||||||
translate>
|
|
||||||
Clone travel and his entries
|
|
||||||
</vn-item>
|
|
||||||
<vn-item
|
|
||||||
id="delete"
|
|
||||||
ng-click="delete.show()"
|
|
||||||
ng-show="$ctrl.isBuyer && !$ctrl.entries.length"
|
|
||||||
translate>
|
|
||||||
Delete travel
|
|
||||||
</vn-item>
|
|
||||||
<a class="vn-item"
|
|
||||||
name="addEntry"
|
|
||||||
ng-click="$ctrl.redirectToCreateEntry()"
|
|
||||||
translate>
|
|
||||||
Add entry
|
|
||||||
</a>
|
|
||||||
</vn-list>
|
|
||||||
</vn-menu>
|
|
||||||
|
|
||||||
<!-- Clone travel popup -->
|
|
||||||
<vn-confirm
|
|
||||||
vn-id="clone"
|
|
||||||
on-accept="$ctrl.onCloneAccept()"
|
|
||||||
question="Do you want to clone this travel?"
|
|
||||||
message="All it's properties will be copied">
|
|
||||||
</vn-confirm>
|
|
||||||
|
|
||||||
<!-- Delete travel popup -->
|
|
||||||
<vn-confirm
|
|
||||||
vn-id="delete"
|
|
||||||
on-accept="$ctrl.onDeleteAccept()"
|
|
||||||
question="Do you want to delete this travel?"
|
|
||||||
message="The travel will be deleted">
|
|
||||||
</vn-confirm>
|
|
||||||
|
|
||||||
<!-- Clone travel popup -->
|
|
||||||
<vn-confirm
|
|
||||||
vn-id="cloneWithEntries"
|
|
||||||
on-accept="$ctrl.onCloneWithEntriesAccept()"
|
|
||||||
question="Do you want to clone this travel and all containing entries?"
|
|
||||||
message="All it's properties will be copied">
|
|
||||||
</vn-confirm>
|
|
|
@ -1,95 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
}
|
|
||||||
|
|
||||||
get travelId() {
|
|
||||||
return this._travelId;
|
|
||||||
}
|
|
||||||
|
|
||||||
set travelId(value) {
|
|
||||||
this._travelId = value;
|
|
||||||
|
|
||||||
if (value) this.loadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
loadData() {
|
|
||||||
const filter = {
|
|
||||||
fields: [
|
|
||||||
'id',
|
|
||||||
'ref',
|
|
||||||
'shipped',
|
|
||||||
'landed',
|
|
||||||
'totalEntries',
|
|
||||||
'agencyModeFk',
|
|
||||||
'warehouseInFk',
|
|
||||||
'warehouseOutFk',
|
|
||||||
'cargoSupplierFk'
|
|
||||||
],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'warehouseIn',
|
|
||||||
scope: {
|
|
||||||
fields: ['name']
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
relation: 'warehouseOut',
|
|
||||||
scope: {
|
|
||||||
fields: ['name']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
this.$http.get(`Travels/${this.travelId}`, {filter})
|
|
||||||
.then(res => this.travel = res.data);
|
|
||||||
|
|
||||||
this.$http.get(`Travels/${this.travelId}/getEntries`)
|
|
||||||
.then(res => this.entries = res.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
get isBuyer() {
|
|
||||||
return this.aclService.hasAny(['buyer']);
|
|
||||||
}
|
|
||||||
|
|
||||||
onDeleteAccept() {
|
|
||||||
this.$http.delete(`Travels/${this.travelId}`)
|
|
||||||
.then(() => this.$state.go('travel.index'))
|
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('Travel deleted')));
|
|
||||||
}
|
|
||||||
|
|
||||||
onCloneAccept() {
|
|
||||||
const params = JSON.stringify({
|
|
||||||
ref: this.travel.ref,
|
|
||||||
agencyModeFk: this.travel.agencyModeFk,
|
|
||||||
shipped: this.travel.shipped,
|
|
||||||
landed: this.travel.landed,
|
|
||||||
warehouseInFk: this.travel.warehouseInFk,
|
|
||||||
warehouseOutFk: this.travel.warehouseOutFk
|
|
||||||
});
|
|
||||||
this.$state.go('travel.create', {q: params});
|
|
||||||
}
|
|
||||||
|
|
||||||
async redirectToCreateEntry() {
|
|
||||||
this.$state.go('home');
|
|
||||||
window.location.href = await this.vnApp.getUrl(`entry/create?travelFk=${this.travelId}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
onCloneWithEntriesAccept() {
|
|
||||||
this.$http.post(`Travels/${this.travelId}/cloneWithEntries`)
|
|
||||||
.then(res => this.$state.go('travel.card.basicData', {id: res.data}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelDescriptorMenu', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
travelId: '<',
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,71 +0,0 @@
|
||||||
import './index.js';
|
|
||||||
|
|
||||||
describe('Travel Component vnTravelDescriptorMenu', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
beforeEach(ngModule('travel'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
const $element = angular.element('<vn-travel-descriptor-menu></vn-travel-descriptor-menu>');
|
|
||||||
controller = $componentController('vnTravelDescriptorMenu', {$element});
|
|
||||||
controller._travelId = 5;
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('onCloneAccept()', () => {
|
|
||||||
it('should call state.go with the travel data', () => {
|
|
||||||
jest.spyOn(controller.$state, 'go').mockReturnValue('ok');
|
|
||||||
|
|
||||||
controller.travel = {
|
|
||||||
ref: 'the ref',
|
|
||||||
agencyModeFk: 'the agency',
|
|
||||||
shipped: 'the shipped date',
|
|
||||||
landed: 'the landing date',
|
|
||||||
warehouseInFk: 'the receiver warehouse',
|
|
||||||
warehouseOutFk: 'the sender warehouse'
|
|
||||||
};
|
|
||||||
|
|
||||||
controller.onCloneAccept();
|
|
||||||
|
|
||||||
const params = JSON.stringify({
|
|
||||||
ref: controller.travel.ref,
|
|
||||||
agencyModeFk: controller.travel.agencyModeFk,
|
|
||||||
shipped: controller.travel.shipped,
|
|
||||||
landed: controller.travel.landed,
|
|
||||||
warehouseInFk: controller.travel.warehouseInFk,
|
|
||||||
warehouseOutFk: controller.travel.warehouseOutFk
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('travel.create', {'q': params});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onDeleteAccept()', () => {
|
|
||||||
it('should perform a delete query', () => {
|
|
||||||
jest.spyOn(controller.$state, 'go').mockReturnValue('ok');
|
|
||||||
controller.travelId = 1;
|
|
||||||
|
|
||||||
$httpBackend.when('GET', `Travels/${controller.travelId}`).respond(200);
|
|
||||||
$httpBackend.when('GET', `Travels/${controller.travelId}/getEntries`).respond(200);
|
|
||||||
$httpBackend.expect('DELETE', `Travels/${controller.travelId}`).respond(200);
|
|
||||||
controller.onDeleteAccept();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('travel.index');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onCloneWithEntriesAccept()', () => {
|
|
||||||
it('should make an HTTP query and then call to the $state.go method with the returned id', () => {
|
|
||||||
jest.spyOn(controller.$state, 'go').mockReturnValue('ok');
|
|
||||||
|
|
||||||
$httpBackend.expect('POST', `Travels/${controller.travelId}/cloneWithEntries`).respond(200, 9);
|
|
||||||
controller.onCloneWithEntriesAccept();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('travel.card.basicData', {
|
|
||||||
id: jasmine.any(Number)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,8 +0,0 @@
|
||||||
Clone travel: Clonar envío
|
|
||||||
Add entry: Añadir entrada
|
|
||||||
Clone travel and his entries: Clonar travel y sus entradas
|
|
||||||
Do you want to clone this travel and all containing entries?: ¿Quieres clonar este travel y todas las entradas que contiene?
|
|
||||||
Delete travel: Eliminar envío
|
|
||||||
The travel will be deleted: El envío será eliminado
|
|
||||||
Do you want to delete this travel?: ¿Quieres eliminar este envío?
|
|
||||||
Travel deleted: Envío eliminado
|
|
|
@ -1,24 +0,0 @@
|
||||||
@import "./effects";
|
|
||||||
@import "variables";
|
|
||||||
|
|
||||||
vn-travel-descriptor-menu {
|
|
||||||
& > vn-icon-button[icon="more_vert"] {
|
|
||||||
display: flex;
|
|
||||||
min-width: 45px;
|
|
||||||
height: 45px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
& > vn-icon-button[icon="more_vert"] {
|
|
||||||
@extend %clickable;
|
|
||||||
color: inherit;
|
|
||||||
|
|
||||||
& > vn-icon {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
vn-icon {
|
|
||||||
font-size: 1.75rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
<slot-descriptor>
|
|
||||||
<vn-travel-descriptor>
|
|
||||||
</vn-travel-descriptor>
|
|
||||||
</slot-descriptor>
|
|
|
@ -1,9 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
|
||||||
|
|
||||||
class Controller extends DescriptorPopover {}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelDescriptorPopover', {
|
|
||||||
slotTemplate: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,48 +0,0 @@
|
||||||
<vn-descriptor-content
|
|
||||||
module="travel"
|
|
||||||
description="$ctrl.travel.ref"
|
|
||||||
summary="$ctrl.$.summary">
|
|
||||||
<slot-dot-menu>
|
|
||||||
<vn-travel-descriptor-menu travel-id="$ctrl.travel.id"/>
|
|
||||||
</slot-dot-menu>
|
|
||||||
<slot-body>
|
|
||||||
<div class="attributes">
|
|
||||||
<vn-label-value
|
|
||||||
label="Wh. In"
|
|
||||||
value="{{$ctrl.travel.warehouseIn.name}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Wh. Out"
|
|
||||||
value="{{$ctrl.travel.warehouseOut.name}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Shipped"
|
|
||||||
value="{{$ctrl.travel.shipped | date: 'dd/MM/yyyy'}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Landed"
|
|
||||||
value="{{$ctrl.travel.landed | date: 'dd/MM/yyyy'}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Total entries"
|
|
||||||
value="{{$ctrl.travel.totalEntries}}">
|
|
||||||
</vn-label-value>
|
|
||||||
</div>
|
|
||||||
<div class="quicklinks">
|
|
||||||
<div ng-transclude="btnOne">
|
|
||||||
<vn-quick-link
|
|
||||||
tooltip="All travels with current agency"
|
|
||||||
state="['travel.index', {q: $ctrl.travelFilter}]"
|
|
||||||
icon="local_airport">
|
|
||||||
</vn-quick-link>
|
|
||||||
</div>
|
|
||||||
<div ng-transclude="btnTwo">
|
|
||||||
</div>
|
|
||||||
<div ng-transclude="btnThree">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</slot-body>
|
|
||||||
</vn-descriptor-content>
|
|
||||||
<vn-popup vn-id="summary">
|
|
||||||
<vn-travel-summary travel="$ctrl.travel"></vn-travel-summary>
|
|
||||||
</vn-popup>
|
|
|
@ -1,63 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Descriptor from 'salix/components/descriptor';
|
|
||||||
|
|
||||||
class Controller extends Descriptor {
|
|
||||||
get travel() {
|
|
||||||
return this.entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
set travel(value) {
|
|
||||||
this.entity = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get travelFilter() {
|
|
||||||
let travelFilter;
|
|
||||||
const travel = this.travel;
|
|
||||||
|
|
||||||
if (travel && travel.agencyModeFk) {
|
|
||||||
travelFilter = this.travel && JSON.stringify({
|
|
||||||
agencyModeFk: this.travel.agencyModeFk
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return travelFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
loadData() {
|
|
||||||
const filter = {
|
|
||||||
fields: [
|
|
||||||
'id',
|
|
||||||
'ref',
|
|
||||||
'shipped',
|
|
||||||
'landed',
|
|
||||||
'totalEntries',
|
|
||||||
'warehouseInFk',
|
|
||||||
'warehouseOutFk',
|
|
||||||
'cargoSupplierFk'
|
|
||||||
],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'warehouseIn',
|
|
||||||
scope: {
|
|
||||||
fields: ['name']
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
relation: 'warehouseOut',
|
|
||||||
scope: {
|
|
||||||
fields: ['name']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.getData(`Travels/${this.id}`, {filter})
|
|
||||||
.then(res => this.entity = res.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelDescriptor', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
travel: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,26 +0,0 @@
|
||||||
import './index.js';
|
|
||||||
|
|
||||||
describe('vnTravelDescriptor', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('travel'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
controller = $componentController('vnTravelDescriptor', {$element: null});
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('loadData()', () => {
|
|
||||||
it(`should perform a get query to store the worker data into the controller`, () => {
|
|
||||||
const id = 1;
|
|
||||||
const response = 'foo';
|
|
||||||
|
|
||||||
$httpBackend.expectRoute('GET', `Travels/${id}`).respond(response);
|
|
||||||
controller.id = id;
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.travel).toEqual(response);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,6 +0,0 @@
|
||||||
Reference: Referencia
|
|
||||||
Wh. In: Alm. entrada
|
|
||||||
Wh. Out: Alm. salida
|
|
||||||
Shipped: F. envío
|
|
||||||
Landed: F. entrega
|
|
||||||
Total entries: Entradas totales
|
|
|
@ -1,92 +0,0 @@
|
||||||
<div class="search-panel">
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Warehouses"
|
|
||||||
data="warehouses">
|
|
||||||
</vn-crud-model>
|
|
||||||
<form ng-submit="$ctrl.onSearch()">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="General search"
|
|
||||||
ng-model="filter.search"
|
|
||||||
info="Search travels by id"
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Reference"
|
|
||||||
ng-model="filter.ref">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Total entries"
|
|
||||||
ng-model="filter.totalEntries">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
label="Travel id"
|
|
||||||
ng-model="filter.id">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Agency"
|
|
||||||
ng-model="filter.agencyModeFk"
|
|
||||||
url="AgencyModes"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-date-picker
|
|
||||||
vn-one
|
|
||||||
label="Shipped from"
|
|
||||||
ng-model="$ctrl.shippedFrom">
|
|
||||||
</vn-date-picker>
|
|
||||||
<vn-date-picker
|
|
||||||
vn-one
|
|
||||||
label="Landed to"
|
|
||||||
ng-model="$ctrl.landedTo">
|
|
||||||
</vn-date-picker>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Warehouse Out"
|
|
||||||
ng-model="filter.warehouseOutFk"
|
|
||||||
data="warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Warehouse In"
|
|
||||||
ng-model="filter.warehouseInFk"
|
|
||||||
data="warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Freighter"
|
|
||||||
ng-model="filter.cargoSupplierFk"
|
|
||||||
url="Suppliers"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Continent Out"
|
|
||||||
ng-model="filter.continent"
|
|
||||||
url="Continents"
|
|
||||||
show-field="name"
|
|
||||||
value-field="code">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal class="vn-mt-lg">
|
|
||||||
<vn-submit label="Search"></vn-submit>
|
|
||||||
</vn-horizontal>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
|
@ -1,31 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
|
||||||
|
|
||||||
class Controller extends SearchPanel {
|
|
||||||
constructor($, $element) {
|
|
||||||
super($, $element);
|
|
||||||
|
|
||||||
this.filter = this.$.filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
get shippedFrom() {
|
|
||||||
return this.filter.shippedFrom;
|
|
||||||
}
|
|
||||||
|
|
||||||
set shippedFrom(value) {
|
|
||||||
this.filter.shippedFrom = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get landedTo() {
|
|
||||||
return this.filter.landedTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
set landedTo(value) {
|
|
||||||
this.filter.landedTo = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnExtraCommunitySearchPanel', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,189 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="Travels/extraCommunityFilter"
|
|
||||||
user-params="::$ctrl.defaultFilter"
|
|
||||||
data="travels"
|
|
||||||
order="landed ASC, shipped ASC, travelFk, loadPriority, agencyModeFk, supplierName, evaNotes"
|
|
||||||
limit="20"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-portal slot="topbar">
|
|
||||||
<vn-searchbar
|
|
||||||
vn-focus
|
|
||||||
panel="vn-extra-community-search-panel"
|
|
||||||
info="Search by travel id or reference"
|
|
||||||
placeholder="Search by extra community travel"
|
|
||||||
suggested-filter="$ctrl.defaultFilter"
|
|
||||||
filter="$ctrl.defaultFilter"
|
|
||||||
auto-state="false"
|
|
||||||
model="model">
|
|
||||||
</vn-searchbar>
|
|
||||||
</vn-portal>
|
|
||||||
<vn-card class="travel-list scrollable">
|
|
||||||
<smart-table
|
|
||||||
model="model"
|
|
||||||
options="$ctrl.smartTableOptions">
|
|
||||||
<slot-actions>
|
|
||||||
<section>
|
|
||||||
<vn-tool-bar class="vn-mb-md">
|
|
||||||
<vn-button
|
|
||||||
disabled="!travels.length"
|
|
||||||
icon="picture_as_pdf"
|
|
||||||
ng-click="$ctrl.showReport()"
|
|
||||||
vn-tooltip="Open as PDF">
|
|
||||||
</vn-button>
|
|
||||||
</vn-tool-bar>
|
|
||||||
</section>
|
|
||||||
</slot-actions>
|
|
||||||
<slot-table>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th field="id" shrink>
|
|
||||||
<span translate>Id</span>
|
|
||||||
</th>
|
|
||||||
<th field="cargoSupplierFk">
|
|
||||||
<span translate>Supplier</span>
|
|
||||||
</th>
|
|
||||||
<th field="agencyModeFk">
|
|
||||||
<span translate>Agency</span>
|
|
||||||
</th>
|
|
||||||
<th field="invoiceAmount">
|
|
||||||
<span translate>Amount</span>
|
|
||||||
</th>
|
|
||||||
<th field="ref">
|
|
||||||
<span translate>Reference</span>
|
|
||||||
</th>
|
|
||||||
<th field="stickers" number>
|
|
||||||
<span translate>Packages</span>
|
|
||||||
</th>
|
|
||||||
<th field="kg" number>
|
|
||||||
<span translate>Bl. KG</span>
|
|
||||||
</th>
|
|
||||||
<th field="loadedKg" number>
|
|
||||||
<span translate>Phy. KG</span>
|
|
||||||
</th>
|
|
||||||
<th field="volumeKg" number>
|
|
||||||
<span translate>Vol. KG</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
field="warehouseOutFk"
|
|
||||||
translate-attr="{title: 'Warehouse Out'}">
|
|
||||||
<span translate>Wh. Out</span>
|
|
||||||
</th>
|
|
||||||
<th field="shipped">
|
|
||||||
<span translate>W. Shipped</span>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
field="warehouseInFk"
|
|
||||||
translate-attr="{title: 'Warehouse In'}">
|
|
||||||
<span translate>Wh. In</span>
|
|
||||||
</th>
|
|
||||||
<th field="landed">
|
|
||||||
<span translate>W. Landed</span>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody
|
|
||||||
ng-repeat="travel in travels"
|
|
||||||
class="vn-mb-md"
|
|
||||||
vn-droppable="$ctrl.onDrop($event)"
|
|
||||||
ng-attr-id="{{::travel.id}}"
|
|
||||||
vn-stop-click>
|
|
||||||
<tr
|
|
||||||
class="header"
|
|
||||||
vn-anchor="::{
|
|
||||||
state: 'travel.card.basicData',
|
|
||||||
params: {id: travel.id}
|
|
||||||
}">
|
|
||||||
<td vn-click-stop>
|
|
||||||
<span
|
|
||||||
class="link"
|
|
||||||
ng-click="travelDescriptor.show($event, travel.id)">
|
|
||||||
{{::travel.id}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td class="multi-line" vn-click-stop>
|
|
||||||
<span
|
|
||||||
class="link"
|
|
||||||
ng-click="supplierDescriptor.show($event, travel.cargoSupplierFk)">
|
|
||||||
{{::travel.cargoSupplierNickname}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
<td>{{::travel.agencyModeName}}</td>
|
|
||||||
<td vn-click-stop>
|
|
||||||
<vn-td-editable name="reference" expand>
|
|
||||||
<text>{{travel.ref}}</text>
|
|
||||||
<field>
|
|
||||||
<vn-textfield class="dense" vn-focus
|
|
||||||
ng-model="travel.ref"
|
|
||||||
on-change="$ctrl.save(travel.id, {ref: value})">
|
|
||||||
</vn-textfield>
|
|
||||||
</field>
|
|
||||||
</vn-td-editable>
|
|
||||||
</td>
|
|
||||||
<td number>{{::travel.stickers}}</td>
|
|
||||||
<td vn-click-stop>
|
|
||||||
<vn-td-editable name="lockedKg" expand style="text-align: right">
|
|
||||||
<text number>{{travel.kg}}</text>
|
|
||||||
<field>
|
|
||||||
<vn-input-number class="dense" vn-focus
|
|
||||||
ng-model="travel.kg"
|
|
||||||
on-change="$ctrl.save(travel.id, {kg: value})"
|
|
||||||
min="0">
|
|
||||||
</vn-input-number>
|
|
||||||
</field>
|
|
||||||
</vn-td-editable>
|
|
||||||
</td>
|
|
||||||
<td number>{{::travel.loadedKg}}</td>
|
|
||||||
<td number>{{::travel.volumeKg}}</td>
|
|
||||||
<td expand>{{::travel.warehouseOutName}}</td>
|
|
||||||
<td expand>{{::travel.shipped | date: 'dd/MM/yyyy'}}</td>
|
|
||||||
<td expand>{{::travel.warehouseInName}}</td>
|
|
||||||
<td expand>{{::travel.landed | date: 'dd/MM/yyyy'}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr
|
|
||||||
ng-repeat="entry in travel.entries"
|
|
||||||
draggable
|
|
||||||
ng-attr-id="{{::entry.id}}"
|
|
||||||
ng-click="$event.preventDefault()">
|
|
||||||
<td>
|
|
||||||
<span class="link"
|
|
||||||
ng-click="entryDescriptor.show($event, entry.id)">
|
|
||||||
{{::entry.id}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td class="multi-line">
|
|
||||||
<span
|
|
||||||
class="link"
|
|
||||||
ng-click="supplierDescriptor.show($event, entry.supplierFk)">
|
|
||||||
{{::entry.supplierName}}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td number>{{::entry.invoiceAmount | currency: 'EUR': 2}}</td>
|
|
||||||
<td></td>
|
|
||||||
<td class="td-editable">{{::entry.reference}}</td>
|
|
||||||
<td number>{{::entry.stickers}}</td>
|
|
||||||
<td number></td>
|
|
||||||
<td number>{{::entry.loadedkg}}</td>
|
|
||||||
<td number>{{::entry.volumeKg}}</td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</slot-table>
|
|
||||||
</smart-table>
|
|
||||||
</vn-card>
|
|
||||||
<vn-travel-descriptor-popover
|
|
||||||
vn-id="travelDescriptor">
|
|
||||||
</vn-travel-descriptor-popover>
|
|
||||||
<vn-entry-descriptor-popover
|
|
||||||
vn-id="entryDescriptor">
|
|
||||||
</vn-entry-descriptor-popover>
|
|
||||||
<vn-supplier-descriptor-popover
|
|
||||||
vn-id="supplierDescriptor">
|
|
||||||
</vn-supplier-descriptor-popover>
|
|
|
@ -1,162 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $, vnReport) {
|
|
||||||
super($element, $);
|
|
||||||
|
|
||||||
this.vnReport = vnReport;
|
|
||||||
|
|
||||||
const draggable = this.element.querySelector('.travel-list');
|
|
||||||
draggable.addEventListener('dragstart',
|
|
||||||
event => this.dragStart(event));
|
|
||||||
draggable.addEventListener('dragend',
|
|
||||||
event => this.dragEnd(event));
|
|
||||||
|
|
||||||
draggable.addEventListener('dragover',
|
|
||||||
event => this.dragOver(event));
|
|
||||||
draggable.addEventListener('dragenter',
|
|
||||||
event => this.dragEnter(event));
|
|
||||||
draggable.addEventListener('dragleave',
|
|
||||||
event => this.dragLeave(event));
|
|
||||||
|
|
||||||
this.draggableElement = 'tr[draggable]';
|
|
||||||
this.droppableElement = 'tbody[vn-droppable]';
|
|
||||||
|
|
||||||
const twoDays = 2;
|
|
||||||
const shippedFrom = Date.vnNew();
|
|
||||||
shippedFrom.setDate(shippedFrom.getDate() - twoDays);
|
|
||||||
shippedFrom.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const sevenDays = 7;
|
|
||||||
const landedTo = Date.vnNew();
|
|
||||||
landedTo.setDate(landedTo.getDate() + sevenDays);
|
|
||||||
landedTo.setHours(23, 59, 59, 59);
|
|
||||||
|
|
||||||
this.defaultFilter = {
|
|
||||||
shippedFrom: shippedFrom,
|
|
||||||
landedTo: landedTo,
|
|
||||||
continent: 'AM'
|
|
||||||
};
|
|
||||||
|
|
||||||
this.smartTableOptions = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
onDragInterval() {
|
|
||||||
if (this.dragClientY > 0 && this.dragClientY < 75)
|
|
||||||
this.$window.scrollTo(0, this.$window.scrollY - 10);
|
|
||||||
|
|
||||||
const maxHeight = window.screen.availHeight - (window.outerHeight - window.innerHeight);
|
|
||||||
if (this.dragClientY > maxHeight - 75 && this.dragClientY < maxHeight)
|
|
||||||
this.$window.scrollTo(0, this.$window.scrollY + 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
findDraggable($event) {
|
|
||||||
const target = $event.target;
|
|
||||||
const draggable = target.closest(this.draggableElement);
|
|
||||||
|
|
||||||
return draggable;
|
|
||||||
}
|
|
||||||
|
|
||||||
findDroppable($event) {
|
|
||||||
const target = $event.target;
|
|
||||||
const droppable = target.closest(this.droppableElement);
|
|
||||||
|
|
||||||
return droppable;
|
|
||||||
}
|
|
||||||
|
|
||||||
dragStart($event) {
|
|
||||||
const draggable = this.findDraggable($event);
|
|
||||||
draggable.classList.add('dragging');
|
|
||||||
|
|
||||||
const id = parseInt(draggable.id);
|
|
||||||
this.entryId = id;
|
|
||||||
this.entry = draggable;
|
|
||||||
this.interval = setInterval(() => this.onDragInterval(), 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
dragEnd($event) {
|
|
||||||
const draggable = this.findDraggable($event);
|
|
||||||
draggable.classList.remove('dragging');
|
|
||||||
this.entryId = null;
|
|
||||||
this.entry = null;
|
|
||||||
|
|
||||||
clearInterval(this.interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
onDrop($event) {
|
|
||||||
const model = this.$.model;
|
|
||||||
const droppable = this.findDroppable($event);
|
|
||||||
const travelId = parseInt(droppable.id);
|
|
||||||
|
|
||||||
const currentDroppable = this.entry.closest(this.droppableElement);
|
|
||||||
|
|
||||||
if (currentDroppable == droppable) return;
|
|
||||||
|
|
||||||
if (this.entryId && travelId) {
|
|
||||||
const path = `Entries/${this.entryId}`;
|
|
||||||
this.$http.patch(path, {travelFk: travelId})
|
|
||||||
.then(() => model.refresh())
|
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
undrop() {
|
|
||||||
if (!this.dropping) return;
|
|
||||||
this.dropping.classList.remove('dropping');
|
|
||||||
this.dropping = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dragOver($event) {
|
|
||||||
this.dragClientY = $event.clientY;
|
|
||||||
$event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
dragEnter($event) {
|
|
||||||
let element = this.findDroppable($event);
|
|
||||||
if (element) this.dropCount++;
|
|
||||||
|
|
||||||
if (element != this.dropping) {
|
|
||||||
this.undrop();
|
|
||||||
if (element) element.classList.add('dropping');
|
|
||||||
this.dropping = element;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dragLeave($event) {
|
|
||||||
let element = this.findDroppable($event);
|
|
||||||
|
|
||||||
if (element) {
|
|
||||||
this.dropCount--;
|
|
||||||
if (this.dropCount == 0) this.undrop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
save(id, data) {
|
|
||||||
const endpoint = `Travels/${id}`;
|
|
||||||
this.$http.patch(endpoint, data)
|
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
|
|
||||||
}
|
|
||||||
|
|
||||||
get reportParams() {
|
|
||||||
const userParams = this.$.model.userParams;
|
|
||||||
const currentFilter = this.$.model.currentFilter;
|
|
||||||
|
|
||||||
return Object.assign({
|
|
||||||
authorization: this.vnToken.tokenMultimedia,
|
|
||||||
filter: currentFilter
|
|
||||||
}, userParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
showReport() {
|
|
||||||
this.vnReport.show(`Travels/extra-community-pdf`, this.reportParams);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope', 'vnReport'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelExtraCommunity', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,128 +0,0 @@
|
||||||
import './index.js';
|
|
||||||
|
|
||||||
describe('Travel Component vnTravelExtraCommunity', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('travel'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
const $element = angular.element('<vn-travel-extra-community><div class="travel-list"></div></vn-travel-extra-community>');
|
|
||||||
controller = $componentController('vnTravelExtraCommunity', {$element});
|
|
||||||
controller.$.model = {};
|
|
||||||
controller.$.model.refresh = jest.fn();
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('findDraggable()', () => {
|
|
||||||
it('should find the draggable element', () => {
|
|
||||||
const draggable = document.createElement('tr');
|
|
||||||
draggable.setAttribute('draggable', true);
|
|
||||||
|
|
||||||
const $event = new Event('dragstart');
|
|
||||||
const target = document.createElement('div');
|
|
||||||
draggable.appendChild(target);
|
|
||||||
target.dispatchEvent($event);
|
|
||||||
|
|
||||||
const result = controller.findDraggable($event);
|
|
||||||
|
|
||||||
expect(result).toEqual(draggable);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('findDroppable()', () => {
|
|
||||||
it('should find the droppable element', () => {
|
|
||||||
const droppable = document.createElement('tbody');
|
|
||||||
droppable.setAttribute('vn-droppable', true);
|
|
||||||
|
|
||||||
const $event = new Event('drop');
|
|
||||||
const target = document.createElement('div');
|
|
||||||
droppable.appendChild(target);
|
|
||||||
target.dispatchEvent($event);
|
|
||||||
|
|
||||||
const result = controller.findDroppable($event);
|
|
||||||
|
|
||||||
expect(result).toEqual(droppable);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('dragStart()', () => {
|
|
||||||
it(`should add the class "dragging" to the draggable element
|
|
||||||
and then set the entryId controller property`, () => {
|
|
||||||
const draggable = document.createElement('tr');
|
|
||||||
draggable.setAttribute('draggable', true);
|
|
||||||
draggable.setAttribute('id', 3);
|
|
||||||
|
|
||||||
jest.spyOn(controller, 'findDraggable').mockReturnValue(draggable);
|
|
||||||
|
|
||||||
const $event = new Event('dragStart');
|
|
||||||
controller.dragStart($event);
|
|
||||||
|
|
||||||
const firstClass = draggable.classList[0];
|
|
||||||
|
|
||||||
expect(firstClass).toEqual('dragging');
|
|
||||||
expect(controller.entryId).toEqual(3);
|
|
||||||
expect(controller.entry).toEqual(draggable);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('dragEnd()', () => {
|
|
||||||
it(`should remove the class "dragging" from the draggable element
|
|
||||||
and then set the entryId controller property to null`, () => {
|
|
||||||
const draggable = document.createElement('tr');
|
|
||||||
draggable.setAttribute('draggable', true);
|
|
||||||
draggable.setAttribute('id', 3);
|
|
||||||
draggable.classList.add('dragging');
|
|
||||||
|
|
||||||
jest.spyOn(controller, 'findDraggable').mockReturnValue(draggable);
|
|
||||||
|
|
||||||
const $event = new Event('dragStart');
|
|
||||||
controller.dragEnd($event);
|
|
||||||
|
|
||||||
const classList = draggable.classList;
|
|
||||||
|
|
||||||
expect(classList.length).toEqual(0);
|
|
||||||
expect(controller.entryId).toBeNull();
|
|
||||||
expect(controller.entry).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onDrop()', () => {
|
|
||||||
it('should make an HTTP patch query', () => {
|
|
||||||
const droppable = document.createElement('tbody');
|
|
||||||
droppable.setAttribute('vn-droppable', true);
|
|
||||||
droppable.setAttribute('id', 1);
|
|
||||||
|
|
||||||
jest.spyOn(controller, 'findDroppable').mockReturnValue(droppable);
|
|
||||||
|
|
||||||
const oldDroppable = document.createElement('tbody');
|
|
||||||
oldDroppable.setAttribute('vn-droppable', true);
|
|
||||||
const entry = document.createElement('div');
|
|
||||||
oldDroppable.appendChild(entry);
|
|
||||||
|
|
||||||
controller.entryId = 3;
|
|
||||||
controller.entry = entry;
|
|
||||||
|
|
||||||
const $event = new Event('drop');
|
|
||||||
const expectedData = {travelFk: 1};
|
|
||||||
$httpBackend.expect('PATCH', `Entries/3`, expectedData).respond(200);
|
|
||||||
controller.onDrop($event);
|
|
||||||
$httpBackend.flush();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('save()', () => {
|
|
||||||
it('should make an HTTP query', () => {
|
|
||||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
|
|
||||||
const travelId = 1;
|
|
||||||
const data = {ref: 'New reference'};
|
|
||||||
const expectedData = {ref: 'New reference'};
|
|
||||||
$httpBackend.expect('PATCH', `Travels/${travelId}`, expectedData).respond(200);
|
|
||||||
controller.save(travelId, data);
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,11 +0,0 @@
|
||||||
Family: Familia
|
|
||||||
Extra community: Extra comunitarios
|
|
||||||
Freighter: Transitario
|
|
||||||
Bl. KG: KG Bloq.
|
|
||||||
Phy. KG: KG físico
|
|
||||||
Vol. KG: KG Vol.
|
|
||||||
Search by travel id or reference: Buscar por id de travel o referencia
|
|
||||||
Search by extra community travel: Buscar por envío extra comunitario
|
|
||||||
Continent Out: Cont. salida
|
|
||||||
W. Shipped: F. envío
|
|
||||||
W. Landed: F. llegada
|
|
|
@ -1,67 +0,0 @@
|
||||||
@import "variables";
|
|
||||||
|
|
||||||
vn-travel-extra-community {
|
|
||||||
.header {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
line-height: 1;
|
|
||||||
padding: 7px;
|
|
||||||
padding-bottom: 7px;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
font-weight: lighter;
|
|
||||||
background-color: $color-bg;
|
|
||||||
color: white;
|
|
||||||
border-bottom: 1px solid #f7931e;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
cursor: pointer;
|
|
||||||
.multi-line{
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-bottom: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
table[vn-droppable] {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr[draggable] {
|
|
||||||
transition: all .5s;
|
|
||||||
cursor: move;
|
|
||||||
overflow: auto;
|
|
||||||
outline: 0;
|
|
||||||
height: 65px;
|
|
||||||
pointer-events: fill;
|
|
||||||
user-select: all;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr[draggable] *::selection {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr[draggable]:hover {
|
|
||||||
background-color: $color-hover-cd;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr[draggable].dragging {
|
|
||||||
background-color: $color-primary-light;
|
|
||||||
color: $color-font-light;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.multi-line{
|
|
||||||
max-width: 200px;
|
|
||||||
word-wrap: normal;
|
|
||||||
white-space: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
vn-td-editable text {
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
border-bottom: 1px dashed $color-active;
|
|
||||||
border-radius: 0;
|
|
||||||
color: $color-active
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +1,3 @@
|
||||||
export * from './module';
|
export * from './module';
|
||||||
|
|
||||||
import './main';
|
import './main';
|
||||||
import './index/';
|
|
||||||
import './search-panel';
|
|
||||||
import './descriptor';
|
|
||||||
import './card';
|
|
||||||
import './summary';
|
|
||||||
import './basic-data';
|
|
||||||
import './log';
|
|
||||||
import './create';
|
|
||||||
import './thermograph/index/';
|
|
||||||
import './thermograph/create/';
|
|
||||||
import './thermograph/edit/';
|
|
||||||
import './descriptor-popover';
|
|
||||||
import './descriptor-menu';
|
|
||||||
import './extra-community';
|
|
||||||
import './extra-community-search-panel';
|
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
|
|
||||||
<vn-auto-search
|
|
||||||
model="model">
|
|
||||||
</vn-auto-search>
|
|
||||||
<vn-travel-search-panel
|
|
||||||
model="model">
|
|
||||||
</vn-travel-search-panel>
|
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="Travels/filter"
|
|
||||||
limit="20"
|
|
||||||
order="shipped DESC, landed DESC">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-data-viewer
|
|
||||||
model="model"
|
|
||||||
class="vn-mb-xl vn-w-xl">
|
|
||||||
<vn-card>
|
|
||||||
<vn-table model="model">
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th field="ref">Reference</vn-th>
|
|
||||||
<vn-th field="agencyModeFk">Agency</vn-th>
|
|
||||||
<vn-th field="warehouseOutFk">Warehouse Out</vn-th>
|
|
||||||
<vn-th field="shipped" center shrink-date>Shipped</vn-th>
|
|
||||||
<vn-th shrink></vn-th>
|
|
||||||
<vn-th field="warehouseInFk">Warehouse In</vn-th>
|
|
||||||
<vn-th field="landed" center shrink-date>Landed</vn-th>
|
|
||||||
<vn-th shrink></vn-th>
|
|
||||||
<vn-th shrink field="totalEntries">Total entries</vn-th>
|
|
||||||
<vn-th shrink></vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<a ng-repeat="travel in model.data"
|
|
||||||
class="clickable vn-tr search-result"
|
|
||||||
ui-sref="travel.card.summary({id: {{::travel.id}}})">
|
|
||||||
<vn-td>{{::travel.ref}}</vn-td>
|
|
||||||
<vn-td>{{::travel.agencyModeName}}</vn-td>
|
|
||||||
<vn-td>{{::travel.warehouseOutName}}</vn-td>
|
|
||||||
<vn-td center shrink-date>
|
|
||||||
<span class="chip {{$ctrl.compareDate(travel.shipped)}}">
|
|
||||||
{{::travel.shipped | date:'dd/MM/yyyy'}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-icon
|
|
||||||
icon="flight_takeoff"
|
|
||||||
translate-attr="{title: 'Delivered'}"
|
|
||||||
ng-class="{active: travel.isDelivered}">
|
|
||||||
</vn-icon>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td expand>{{::travel.warehouseInName}}</vn-td>
|
|
||||||
<vn-td center shrink-date>
|
|
||||||
<span class="chip {{$ctrl.compareDate(travel.landed)}}">
|
|
||||||
{{::travel.landed | date:'dd/MM/yyyy'}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-icon
|
|
||||||
icon="flight_land"
|
|
||||||
translate-attr="{title: 'Received'}"
|
|
||||||
ng-class="{active: travel.isReceived}">
|
|
||||||
</vn-icon>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>{{::travel.totalEntries}}</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-horizontal class="buttons">
|
|
||||||
<vn-icon-button
|
|
||||||
vn-click-stop="clone.show(travel)"
|
|
||||||
vn-tooltip="Clone"
|
|
||||||
icon="icon-clone">
|
|
||||||
</vn-icon-button>
|
|
||||||
<vn-icon-button
|
|
||||||
vn-anchor="::{state: 'entry.create', params: {travelFk: travel.id}}"
|
|
||||||
vn-tooltip="Add entry"
|
|
||||||
icon="icon-ticket">
|
|
||||||
</vn-icon-button>
|
|
||||||
<vn-icon-button
|
|
||||||
vn-click-stop="$ctrl.preview(travel)"
|
|
||||||
vn-tooltip="Preview"
|
|
||||||
icon="preview">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-td>
|
|
||||||
</a>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-data-viewer>
|
|
||||||
</vn-card>
|
|
||||||
<vn-popup vn-id="summary">
|
|
||||||
<vn-travel-summary
|
|
||||||
travel="$ctrl.travelSelected">
|
|
||||||
</vn-travel-summary>
|
|
||||||
</vn-popup>
|
|
||||||
<a ui-sref="travel.create"
|
|
||||||
vn-tooltip="New travel"
|
|
||||||
vn-bind="+"
|
|
||||||
vn-acl="buyer"
|
|
||||||
fixed-bottom-right>
|
|
||||||
<vn-float-button icon="add"></vn-float-button>
|
|
||||||
</a>
|
|
||||||
<vn-confirm
|
|
||||||
vn-id="clone"
|
|
||||||
on-accept="$ctrl.onCloneAccept($data)"
|
|
||||||
question="Do you want to clone this travel?"
|
|
||||||
message="All it's properties will be copied">
|
|
||||||
</vn-confirm>
|
|
|
@ -1,39 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default class Controller extends Section {
|
|
||||||
preview(travel) {
|
|
||||||
this.travelSelected = travel;
|
|
||||||
this.$.summary.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
onCloneAccept(travel) {
|
|
||||||
const params = JSON.stringify({
|
|
||||||
ref: travel.ref,
|
|
||||||
agencyModeFk: travel.agencyModeFk,
|
|
||||||
shipped: travel.shipped,
|
|
||||||
landed: travel.landed,
|
|
||||||
warehouseInFk: travel.warehouseInFk,
|
|
||||||
warehouseOutFk: travel.warehouseOutFk
|
|
||||||
});
|
|
||||||
this.$state.go('travel.create', {q: params});
|
|
||||||
}
|
|
||||||
|
|
||||||
compareDate(date) {
|
|
||||||
let today = Date.vnNew();
|
|
||||||
today.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
date = new Date(date);
|
|
||||||
date.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
const timeDifference = today - date;
|
|
||||||
if (timeDifference == 0) return 'warning';
|
|
||||||
if (timeDifference < 0) return 'success';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelIndex', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,78 +0,0 @@
|
||||||
import './index.js';
|
|
||||||
|
|
||||||
describe('Travel Component vnTravelIndex', () => {
|
|
||||||
let controller;
|
|
||||||
let travel = {
|
|
||||||
id: 1,
|
|
||||||
warehouseInFk: 1,
|
|
||||||
totalEntries: 3,
|
|
||||||
isDelivered: false
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(ngModule('travel'));
|
|
||||||
|
|
||||||
beforeEach(inject($componentController => {
|
|
||||||
const $element = angular.element('<vn-travel-index></vn-travel-index>');
|
|
||||||
controller = $componentController('vnTravelIndex', {$element});
|
|
||||||
controller.$.summary = {show: jasmine.createSpy('show')};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('preview()', () => {
|
|
||||||
it('should show the dialog summary', () => {
|
|
||||||
let event = new MouseEvent('click', {
|
|
||||||
bubbles: true,
|
|
||||||
cancelable: true
|
|
||||||
});
|
|
||||||
controller.preview(event, travel);
|
|
||||||
|
|
||||||
expect(controller.$.summary.show).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onCloneAccept()', () => {
|
|
||||||
it('should call go() then update travelSelected in the controller', () => {
|
|
||||||
jest.spyOn(controller.$state, 'go');
|
|
||||||
|
|
||||||
const travel = {
|
|
||||||
ref: 1,
|
|
||||||
agencyModeFk: 1
|
|
||||||
};
|
|
||||||
const travelParams = {
|
|
||||||
ref: travel.ref,
|
|
||||||
agencyModeFk: travel.agencyModeFk
|
|
||||||
};
|
|
||||||
const queryParams = JSON.stringify(travelParams);
|
|
||||||
controller.onCloneAccept(travel);
|
|
||||||
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('travel.create', {q: queryParams});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('compareDate()', () => {
|
|
||||||
it('should return warning if the date passed to compareDate() is todays', () => {
|
|
||||||
const today = Date.vnNew();
|
|
||||||
|
|
||||||
const result = controller.compareDate(today);
|
|
||||||
|
|
||||||
expect(result).toEqual('warning');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return success if the date passed to compareDate() is in the future', () => {
|
|
||||||
const tomorrow = Date.vnNew();
|
|
||||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
||||||
|
|
||||||
const result = controller.compareDate(tomorrow);
|
|
||||||
|
|
||||||
expect(result).toEqual('success');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return undefined if the date passed to compareDate() is in the past', () => {
|
|
||||||
const yesterday = Date.vnNew();
|
|
||||||
yesterday.setDate(yesterday.getDate() - 1);
|
|
||||||
|
|
||||||
const result = controller.compareDate(yesterday);
|
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,3 +0,0 @@
|
||||||
Do you want to clone this travel?: ¿Desea clonar este envio?
|
|
||||||
All it's properties will be copied: Todas sus propiedades serán copiadas
|
|
||||||
Clone: Clonar
|
|
|
@ -1,11 +0,0 @@
|
||||||
@import "variables";
|
|
||||||
|
|
||||||
vn-travel-index {
|
|
||||||
vn-icon {
|
|
||||||
color: $color-font-secondary
|
|
||||||
}
|
|
||||||
|
|
||||||
vn-icon.active {
|
|
||||||
color: $color-success
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
<vn-log url="TravelLogs" origin-id="$ctrl.$params.id"></vn-log>
|
|
|
@ -1,7 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelLog', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Section,
|
|
||||||
});
|
|
|
@ -1,6 +0,0 @@
|
||||||
<vn-portal slot="topbar">
|
|
||||||
</vn-portal>
|
|
||||||
<vn-portal slot="menu">
|
|
||||||
<vn-left-menu></vn-left-menu>
|
|
||||||
</vn-portal>
|
|
||||||
<ui-view></ui-view>
|
|
|
@ -5,6 +5,10 @@ export default class Travel extends ModuleMain {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
async $onInit() {
|
||||||
|
this.$state.go('home');
|
||||||
|
window.location.href = await this.vnApp.getUrl(`travel/`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravel', {
|
ngModule.vnComponent('vnTravel', {
|
||||||
|
|
|
@ -27,80 +27,6 @@
|
||||||
"state": "travel.index",
|
"state": "travel.index",
|
||||||
"component": "vn-travel-index",
|
"component": "vn-travel-index",
|
||||||
"description": "Travels"
|
"description": "Travels"
|
||||||
}, {
|
|
||||||
"url": "/:id",
|
|
||||||
"state": "travel.card",
|
|
||||||
"abstract": true,
|
|
||||||
"component": "vn-travel-card"
|
|
||||||
}, {
|
|
||||||
"url": "/summary",
|
|
||||||
"state": "travel.card.summary",
|
|
||||||
"component": "vn-travel-summary",
|
|
||||||
"description": "Summary",
|
|
||||||
"params": {
|
|
||||||
"travel": "$ctrl.travel"
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"url": "/basic-data",
|
|
||||||
"state": "travel.card.basicData",
|
|
||||||
"component": "vn-travel-basic-data",
|
|
||||||
"description": "Basic data",
|
|
||||||
"acl": ["buyer","logistic"],
|
|
||||||
"params": {
|
|
||||||
"travel": "$ctrl.travel"
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"url" : "/log",
|
|
||||||
"state": "travel.card.log",
|
|
||||||
"component": "vn-travel-log",
|
|
||||||
"description": "Log"
|
|
||||||
}, {
|
|
||||||
"url": "/create?q",
|
|
||||||
"state": "travel.create",
|
|
||||||
"component": "vn-travel-create",
|
|
||||||
"description": "New travel"
|
|
||||||
}, {
|
|
||||||
"url": "/thermograph",
|
|
||||||
"state": "travel.card.thermograph",
|
|
||||||
"abstract": true,
|
|
||||||
"component": "ui-view"
|
|
||||||
}, {
|
|
||||||
"url" : "/index",
|
|
||||||
"state": "travel.card.thermograph.index",
|
|
||||||
"component": "vn-travel-thermograph-index",
|
|
||||||
"description": "Thermographs",
|
|
||||||
"params": {
|
|
||||||
"travel": "$ctrl.travel"
|
|
||||||
},
|
|
||||||
"acl": ["buyer"]
|
|
||||||
}, {
|
|
||||||
"url" : "/create",
|
|
||||||
"state": "travel.card.thermograph.create",
|
|
||||||
"component": "vn-travel-thermograph-create",
|
|
||||||
"description": "Add thermograph",
|
|
||||||
"params": {
|
|
||||||
"travel": "$ctrl.travel"
|
|
||||||
},
|
|
||||||
"acl": ["buyer"]
|
|
||||||
}, {
|
|
||||||
"url" : "/:thermographId/edit",
|
|
||||||
"state": "travel.card.thermograph.edit",
|
|
||||||
"component": "vn-travel-thermograph-edit",
|
|
||||||
"description": "Edit thermograph",
|
|
||||||
"params": {
|
|
||||||
"travel": "$ctrl.travel"
|
|
||||||
},
|
|
||||||
"acl": ["buyer"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/extra-community?q",
|
|
||||||
"state": "travel.extraCommunity",
|
|
||||||
"component": "vn-travel-extra-community",
|
|
||||||
"description": "Extra community",
|
|
||||||
"acl": ["buyer"],
|
|
||||||
"params": {
|
|
||||||
"travel": "$ctrl.travel"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
<vn-side-menu side="right">
|
|
||||||
<vn-horizontal class="input">
|
|
||||||
<vn-textfield
|
|
||||||
label="General search"
|
|
||||||
info="Search travels by id"
|
|
||||||
ng-model="$ctrl.search"
|
|
||||||
ng-keydown="$ctrl.onKeyPress($event, 'search')">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal class="input horizontal">
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-id="agency"
|
|
||||||
label="Agency"
|
|
||||||
ng-model="$ctrl.filter.agencyModeFk"
|
|
||||||
data="$ctrl.agencyModes"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
on-change="$ctrl.applyFilters()">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal class="input horizontal">
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-id="warehouseOut"
|
|
||||||
label="Warehouse Out"
|
|
||||||
ng-model="$ctrl.filter.warehouseOutFk"
|
|
||||||
data="$ctrl.warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
on-change="$ctrl.applyFilters()">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-id="warehouseIn"
|
|
||||||
label="Warehouse In"
|
|
||||||
ng-model="$ctrl.filter.warehouseInFk"
|
|
||||||
data="$ctrl.warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
on-change="$ctrl.applyFilters()">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal class="input horizontal">
|
|
||||||
<vn-input-number
|
|
||||||
min="0"
|
|
||||||
step="1"
|
|
||||||
label="Days onward"
|
|
||||||
ng-model="$ctrl.filter.scopeDays"
|
|
||||||
on-change="$ctrl.applyFilters()"
|
|
||||||
display-controls="true"
|
|
||||||
info="Cannot choose a range of dates and days onward at the same time">
|
|
||||||
</vn-input-number>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal class="input horizontal">
|
|
||||||
<vn-date-picker
|
|
||||||
label="Landed from"
|
|
||||||
ng-model="$ctrl.filter.landedFrom"
|
|
||||||
on-change="$ctrl.applyFilters()">
|
|
||||||
</vn-date-picker>
|
|
||||||
<vn-date-picker
|
|
||||||
label="Landed to"
|
|
||||||
ng-model="$ctrl.filter.landedTo"
|
|
||||||
on-change="$ctrl.applyFilters()">
|
|
||||||
</vn-date-picker>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal class="input horizontal">
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-id="continent"
|
|
||||||
label="Continent Out"
|
|
||||||
ng-model="$ctrl.filter.continent"
|
|
||||||
data="$ctrl.continents"
|
|
||||||
show-field="name"
|
|
||||||
value-field="code"
|
|
||||||
on-change="$ctrl.applyFilters()">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-input-number
|
|
||||||
min="0"
|
|
||||||
label="Total entries"
|
|
||||||
ng-model="$ctrl.totalEntries"
|
|
||||||
ng-keydown="$ctrl.onKeyPress($event, 'totalEntries')">
|
|
||||||
</vn-input-number>
|
|
||||||
</vn-horizontal>
|
|
||||||
<div class="chips">
|
|
||||||
<vn-chip
|
|
||||||
ng-if="$ctrl.filter.search"
|
|
||||||
removable="true"
|
|
||||||
on-remove="$ctrl.removeParamFilter('search')"
|
|
||||||
class="colored">
|
|
||||||
<span>Id/{{$ctrl.$t('Reference')}}: {{$ctrl.filter.search}}</span>
|
|
||||||
</vn-chip>
|
|
||||||
<vn-chip
|
|
||||||
ng-if="agency.selection"
|
|
||||||
removable="true"
|
|
||||||
on-remove="$ctrl.removeParamFilter('agencyModeFk')"
|
|
||||||
class="colored">
|
|
||||||
<span>{{$ctrl.$t('Agency')}}: {{agency.selection.name}}</span>
|
|
||||||
</vn-chip>
|
|
||||||
<vn-chip
|
|
||||||
ng-if="warehouseOut.selection"
|
|
||||||
removable="true"
|
|
||||||
on-remove="$ctrl.removeParamFilter('warehouseOutFk')"
|
|
||||||
class="colored">
|
|
||||||
<span>{{$ctrl.$t('Warehouse Out')}}: {{warehouseOut.selection.name}}</span>
|
|
||||||
</vn-chip>
|
|
||||||
<vn-chip
|
|
||||||
ng-if="warehouseIn.selection"
|
|
||||||
removable="true"
|
|
||||||
on-remove="$ctrl.removeParamFilter('warehouseInFk')"
|
|
||||||
class="colored">
|
|
||||||
<span>{{$ctrl.$t('Warehouse In')}}: {{warehouseIn.selection.name}}</span>
|
|
||||||
</vn-chip>
|
|
||||||
<vn-chip
|
|
||||||
ng-if="$ctrl.filter.scopeDays"
|
|
||||||
removable="true"
|
|
||||||
on-remove="$ctrl.removeParamFilter('scopeDays')"
|
|
||||||
class="colored">
|
|
||||||
<span>{{$ctrl.$t('Days onward')}}: {{$ctrl.filter.scopeDays}}</span>
|
|
||||||
</vn-chip>
|
|
||||||
<vn-chip
|
|
||||||
ng-if="$ctrl.filter.landedFrom"
|
|
||||||
removable="true"
|
|
||||||
on-remove="$ctrl.removeParamFilter('landedFrom')"
|
|
||||||
class="colored">
|
|
||||||
<span>{{$ctrl.$t('Landed from')}}: {{$ctrl.filter.landedFrom | date:'dd/MM/yyyy'}}</span>
|
|
||||||
</vn-chip>
|
|
||||||
<vn-chip
|
|
||||||
ng-if="$ctrl.filter.landedTo"
|
|
||||||
removable="true"
|
|
||||||
on-remove="$ctrl.removeParamFilter('landedTo')"
|
|
||||||
class="colored">
|
|
||||||
<span>{{$ctrl.$t('Landed to')}}: {{$ctrl.filter.landedTo | date:'dd/MM/yyyy'}}</span>
|
|
||||||
</vn-chip>
|
|
||||||
<vn-chip
|
|
||||||
ng-if="continent.selection"
|
|
||||||
removable="true"
|
|
||||||
on-remove="$ctrl.removeParamFilter('continent')"
|
|
||||||
class="colored">
|
|
||||||
<span>{{$ctrl.$t('Continent Out')}}: {{continent.selection.name}}</span>
|
|
||||||
</vn-chip>
|
|
||||||
<vn-chip
|
|
||||||
ng-if="$ctrl.filter.totalEntries"
|
|
||||||
removable="true"
|
|
||||||
on-remove="$ctrl.removeParamFilter('totalEntries')"
|
|
||||||
class="colored">
|
|
||||||
<span>{{$ctrl.$t('Total entries')}}: {{$ctrl.filter.totalEntries}}</span>
|
|
||||||
</vn-chip>
|
|
||||||
</div>
|
|
||||||
</vn-side-menu>
|
|
|
@ -1,72 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends SearchPanel {
|
|
||||||
constructor($, $element) {
|
|
||||||
super($, $element);
|
|
||||||
this.initFilter();
|
|
||||||
this.fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
$onChanges() {
|
|
||||||
if (this.model)
|
|
||||||
this.applyFilters();
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchData() {
|
|
||||||
this.$http.get('AgencyModes').then(res => {
|
|
||||||
this.agencyModes = res.data;
|
|
||||||
});
|
|
||||||
this.$http.get('Warehouses').then(res => {
|
|
||||||
this.warehouses = res.data;
|
|
||||||
});
|
|
||||||
this.$http.get('Continents').then(res => {
|
|
||||||
this.continents = res.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
initFilter() {
|
|
||||||
this.filter = {};
|
|
||||||
if (this.$params.q) {
|
|
||||||
this.filter = JSON.parse(this.$params.q);
|
|
||||||
this.search = this.filter.search;
|
|
||||||
this.totalEntries = this.filter.totalEntries;
|
|
||||||
}
|
|
||||||
if (!this.filter.scopeDays) this.filter.scopeDays = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyFilters(param) {
|
|
||||||
if (this.filter?.search)
|
|
||||||
delete this.filter.scopeDays;
|
|
||||||
|
|
||||||
this.model.applyFilter({}, this.filter)
|
|
||||||
.then(() => {
|
|
||||||
if (param && this.model._orgData.length === 1)
|
|
||||||
this.$state.go('travel.card.summary', {id: this.model._orgData[0].id});
|
|
||||||
else
|
|
||||||
this.$state.go(this.$state.current.name, {q: JSON.stringify(this.filter)}, {location: 'replace'});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
removeParamFilter(param) {
|
|
||||||
if (this[param]) delete this[param];
|
|
||||||
delete this.filter[param];
|
|
||||||
this.applyFilters();
|
|
||||||
}
|
|
||||||
|
|
||||||
onKeyPress($event, param) {
|
|
||||||
if ($event.key === 'Enter') {
|
|
||||||
this.filter[param] = this[param];
|
|
||||||
this.applyFilters(param === 'search');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelSearchPanel', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
model: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,38 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Travel Component vnTravelSearchPanel', () => {
|
|
||||||
let controller;
|
|
||||||
|
|
||||||
beforeEach(ngModule('travel'));
|
|
||||||
|
|
||||||
beforeEach(inject($componentController => {
|
|
||||||
controller = $componentController('vnTravelSearchPanel', {$element: null});
|
|
||||||
controller.$t = () => {};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('applyFilters()', () => {
|
|
||||||
it('should apply filters', async() => {
|
|
||||||
controller.filter = {foo: 'bar'};
|
|
||||||
controller.model = {
|
|
||||||
applyFilter: jest.fn().mockResolvedValue(),
|
|
||||||
_orgData: [{id: 1}]
|
|
||||||
};
|
|
||||||
controller.$state = {
|
|
||||||
current: {
|
|
||||||
name: 'foo'
|
|
||||||
},
|
|
||||||
go: jest.fn()
|
|
||||||
};
|
|
||||||
|
|
||||||
await controller.applyFilters(true);
|
|
||||||
|
|
||||||
expect(controller.model.applyFilter).toHaveBeenCalledWith({}, controller.filter);
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('travel.card.summary', {id: 1});
|
|
||||||
|
|
||||||
await controller.applyFilters(false);
|
|
||||||
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith(controller.$state.current.name,
|
|
||||||
{q: JSON.stringify(controller.filter)}, {location: 'replace'});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,7 +0,0 @@
|
||||||
Ticket id: Id ticket
|
|
||||||
Client id: Id cliente
|
|
||||||
Nickname: Alias
|
|
||||||
From: Desde
|
|
||||||
To: Hasta
|
|
||||||
Agency: Agencia
|
|
||||||
Warehouse: Almacén
|
|
|
@ -1,37 +0,0 @@
|
||||||
@import "variables";
|
|
||||||
|
|
||||||
vn-travel-search-panel vn-side-menu {
|
|
||||||
.menu {
|
|
||||||
min-width: $menu-width;
|
|
||||||
}
|
|
||||||
& > div {
|
|
||||||
.input {
|
|
||||||
padding-left: $spacing-md;
|
|
||||||
padding-right: $spacing-md;
|
|
||||||
border-color: $color-spacer;
|
|
||||||
border-bottom: $border-thin;
|
|
||||||
}
|
|
||||||
.horizontal {
|
|
||||||
padding-left: $spacing-md;
|
|
||||||
padding-right: $spacing-md;
|
|
||||||
grid-auto-flow: column;
|
|
||||||
grid-column-gap: $spacing-sm;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.chips {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
padding: $spacing-md;
|
|
||||||
overflow: hidden;
|
|
||||||
max-width: 100%;
|
|
||||||
border-color: $color-spacer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.or {
|
|
||||||
align-self: center;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 26px;
|
|
||||||
color: $color-font-secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
<vn-card class="summary">
|
|
||||||
<h5>
|
|
||||||
<a
|
|
||||||
ng-if="::$ctrl.travelData.id"
|
|
||||||
vn-tooltip="Go to the travel"
|
|
||||||
ui-sref="travel.card.summary({id: {{::$ctrl.travelData.id}}})"
|
|
||||||
name="goToSummary">
|
|
||||||
<vn-icon-button icon="launch"></vn-icon-button>
|
|
||||||
</a>
|
|
||||||
<span>{{$ctrl.travelData.id}} - {{$ctrl.travelData.ref}}</span>
|
|
||||||
<vn-travel-descriptor-menu travel-id="$ctrl.travel.id"/>
|
|
||||||
</h5>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-one>
|
|
||||||
<vn-label-value
|
|
||||||
label="Shipped"
|
|
||||||
value="{{$ctrl.travelData.shipped | date: 'dd/MM/yyyy'}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Warehouse Out"
|
|
||||||
value="{{$ctrl.travelData.warehouseOut.name}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-check
|
|
||||||
label="Delivered"
|
|
||||||
ng-model="$ctrl.travelData.isDelivered"
|
|
||||||
disabled="true">
|
|
||||||
</vn-check>
|
|
||||||
</vn-one>
|
|
||||||
<vn-one>
|
|
||||||
<vn-label-value
|
|
||||||
label="Landed"
|
|
||||||
value="{{$ctrl.travelData.landed | date: 'dd/MM/yyyy'}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Warehouse In"
|
|
||||||
value="{{$ctrl.travelData.warehouseIn.name}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-check
|
|
||||||
label="Received"
|
|
||||||
ng-model="$ctrl.travelData.isReceived"
|
|
||||||
disabled="true">
|
|
||||||
</vn-check>
|
|
||||||
</vn-one>
|
|
||||||
<vn-one>
|
|
||||||
<vn-label-value
|
|
||||||
label="Agency"
|
|
||||||
value="{{$ctrl.travelData.agency.name}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Reference"
|
|
||||||
value="{{$ctrl.travelData.ref}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="m³"
|
|
||||||
value="{{$ctrl.travelData.m3}}">
|
|
||||||
</vn-label-value>
|
|
||||||
<vn-label-value
|
|
||||||
label="Total entries"
|
|
||||||
value="{{$ctrl.travelData.totalEntries}}">
|
|
||||||
</vn-label-value>
|
|
||||||
</vn-one>
|
|
||||||
<vn-auto>
|
|
||||||
<h4 translate>Entries</h4>
|
|
||||||
<vn-table>
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th shrink>Confirmed</vn-th>
|
|
||||||
<vn-th shrink>Entry Id</vn-th>
|
|
||||||
<vn-th shrink>Supplier</vn-th>
|
|
||||||
<vn-th shrink>Reference</vn-th>
|
|
||||||
<vn-th shrink title="Half box">HB</vn-th>
|
|
||||||
<vn-th shrink>Freight</vn-th>
|
|
||||||
<vn-th shrink>Package</vn-th>
|
|
||||||
<vn-th shrink>CC</vn-th>
|
|
||||||
<vn-th shrink>Pallet</vn-th>
|
|
||||||
<vn-th shrink>m³</vn-th>
|
|
||||||
<vn-th shrink></vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="entry in $ctrl.entries">
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-check
|
|
||||||
ng-model="entry.isConfirmed"
|
|
||||||
disabled="true">
|
|
||||||
</vn-check>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<span class="link"
|
|
||||||
vn-click-stop="entryDescriptor.show($event, entry.id)">
|
|
||||||
{{entry.id}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td expand>{{entry.supplierName}}</vn-td>
|
|
||||||
<vn-td shrink>{{entry.reference}}</vn-td>
|
|
||||||
<vn-td shrink>{{entry.hb}}</vn-td>
|
|
||||||
<vn-td shrink>{{entry.freightValue | currency: 'EUR': 2}}</vn-td>
|
|
||||||
<vn-td shrink>{{entry.packageValue | currency: 'EUR': 2}}</vn-td>
|
|
||||||
<vn-td shrink>{{entry.cc}}</vn-td>
|
|
||||||
<vn-td shrink>{{entry.pallet}}</vn-td>
|
|
||||||
<vn-td shrink>{{entry.m3}}</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-icon
|
|
||||||
ng-if="entry.observation.length"
|
|
||||||
vn-tooltip="{{entry.observation}}"
|
|
||||||
icon="insert_drive_file"
|
|
||||||
class="bright">
|
|
||||||
</vn-icon>
|
|
||||||
</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
<vn-tfoot>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-td></vn-td>
|
|
||||||
<vn-td></vn-td>
|
|
||||||
<vn-td></vn-td>
|
|
||||||
<vn-td></vn-td>
|
|
||||||
<vn-td shrink><strong>{{$ctrl.total('hb')}}</strong></vn-td>
|
|
||||||
<vn-td shrink><strong>{{$ctrl.total('freightValue') | currency: 'EUR': 2}}</strong></vn-td>
|
|
||||||
<vn-td shrink><strong>{{$ctrl.total('packageValue') | currency: 'EUR': 2}}</strong></vn-td>
|
|
||||||
<vn-td shrink><strong>{{$ctrl.total('cc') | number:2}}</strong></vn-td>
|
|
||||||
<vn-td shrink><strong>{{$ctrl.total('pallet') | number:2}}</strong></vn-td>
|
|
||||||
<vn-td shrink><strong>{{$ctrl.total('m3') | number:2}}</strong></vn-td>
|
|
||||||
<vn-td></vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tfoot>
|
|
||||||
</vn-table>
|
|
||||||
</vn-auto>
|
|
||||||
<vn-auto ng-if="$ctrl.travelThermographs.length != 0">
|
|
||||||
<h4 ng-show="$ctrl.isBuyer">
|
|
||||||
<a
|
|
||||||
ui-sref="travel.card.thermograph.index({id:$ctrl.travelData.id})"
|
|
||||||
target="_self">
|
|
||||||
<span translate vn-tooltip="Go to">Thermograph</span>
|
|
||||||
</a>
|
|
||||||
</h4>
|
|
||||||
<h4
|
|
||||||
translate
|
|
||||||
ng-show="!$ctrl.isBuyer">
|
|
||||||
Thermograph
|
|
||||||
</h4>
|
|
||||||
<vn-table>
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th>Code</vn-th>
|
|
||||||
<vn-th>Temperature</vn-th>
|
|
||||||
<vn-th expand>State</vn-th>
|
|
||||||
<vn-th>Destination</vn-th>
|
|
||||||
<vn-th expand>Created</vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="thermograph in $ctrl.travelThermographs">
|
|
||||||
<vn-td>{{thermograph.thermographFk}} </vn-td>
|
|
||||||
<vn-td>{{thermograph.temperatureFk}}</vn-td>
|
|
||||||
<vn-td>{{thermograph.result}}</vn-td>
|
|
||||||
<vn-td>{{thermograph.warehouse.name}}</vn-td>
|
|
||||||
<vn-td expand>{{thermograph.created | date: 'dd/MM/yyyy'}}</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-auto>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-entry-descriptor-popover
|
|
||||||
vn-id="entryDescriptor">
|
|
||||||
</vn-entry-descriptor-popover>
|
|
|
@ -1,71 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Summary from 'salix/components/summary';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Summary {
|
|
||||||
$onInit() {
|
|
||||||
this.entries = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
get travel() {
|
|
||||||
return this._travel;
|
|
||||||
}
|
|
||||||
|
|
||||||
set travel(value) {
|
|
||||||
this._travel = value;
|
|
||||||
|
|
||||||
if (value && value.id) {
|
|
||||||
this.getTravel();
|
|
||||||
this.getEntries();
|
|
||||||
this.getThermographs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getTravel() {
|
|
||||||
return this.$http.get(`Travels/${this.travel.id}/getTravel`)
|
|
||||||
.then(res => this.travelData = res.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
getEntries() {
|
|
||||||
return this.$http.get(`Travels/${this.travel.id}/getEntries`)
|
|
||||||
.then(res => this.entries = res.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
getThermographs() {
|
|
||||||
const filter = {
|
|
||||||
include: {
|
|
||||||
relation: 'warehouse',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'name']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
travelFk: this.travel.id
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.$http.get(`TravelThermographs`, {filter})
|
|
||||||
.then(res => this.travelThermographs = res.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
total(field) {
|
|
||||||
let total = 0;
|
|
||||||
|
|
||||||
for (let entry of this.entries)
|
|
||||||
total += entry[field];
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
get isBuyer() {
|
|
||||||
return this.aclService.hasAny(['buyer']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelSummary', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
travel: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,86 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('component vnTravelSummary', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let $scope;
|
|
||||||
let $httpParamSerializer;
|
|
||||||
|
|
||||||
beforeEach(angular.mock.module('travel', $translateProvider => {
|
|
||||||
$translateProvider.translations('en', {});
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$httpParamSerializer = _$httpParamSerializer_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
const $element = angular.element(`<vn-travel-summary></vn-travel-summary>`);
|
|
||||||
controller = $componentController('vnTravelSummary', {$element, $scope});
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('travel setter/getter', () => {
|
|
||||||
it('should return the travel and then call both getTravel() and getEntries()', () => {
|
|
||||||
jest.spyOn(controller, 'getTravel');
|
|
||||||
jest.spyOn(controller, 'getEntries');
|
|
||||||
jest.spyOn(controller, 'getThermographs');
|
|
||||||
controller.travel = {id: 99};
|
|
||||||
|
|
||||||
expect(controller._travel.id).toEqual(99);
|
|
||||||
expect(controller.getTravel).toHaveBeenCalledWith();
|
|
||||||
expect(controller.getEntries).toHaveBeenCalledWith();
|
|
||||||
expect(controller.getThermographs).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getTravel()', () => {
|
|
||||||
it('should perform a get and then store data on the controller', () => {
|
|
||||||
controller._travel = {id: 999};
|
|
||||||
|
|
||||||
const query = `Travels/${controller._travel.id}/getTravel`;
|
|
||||||
$httpBackend.expectGET(query).respond('I am the travelData');
|
|
||||||
controller.getTravel();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.travelData).toEqual('I am the travelData');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getEntries()', () => {
|
|
||||||
it('should call the getEntries method to get the entries data', () => {
|
|
||||||
controller._travel = {id: 999};
|
|
||||||
|
|
||||||
const query = `Travels/${controller._travel.id}/getEntries`;
|
|
||||||
$httpBackend.expectGET(query).respond('I am the entries');
|
|
||||||
controller.getEntries();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.entries).toEqual('I am the entries');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getThermographs()', () => {
|
|
||||||
it('should call the getThermographs method to get the thermographs', () => {
|
|
||||||
controller._travel = {id: 2};
|
|
||||||
|
|
||||||
$httpBackend.expectGET(`TravelThermographs`).respond('I am the thermographs');
|
|
||||||
controller.getThermographs();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.travelThermographs).toEqual('I am the thermographs');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('total()', () => {
|
|
||||||
it('should calculate the total amount of a given property for every row', () => {
|
|
||||||
controller.entries = [
|
|
||||||
{id: 1, freightValue: 1, packageValue: 2, cc: 0.01},
|
|
||||||
{id: 2, freightValue: 1, packageValue: 2, cc: 0.01},
|
|
||||||
{id: 3, freightValue: 1, packageValue: 2, cc: 0.01}
|
|
||||||
];
|
|
||||||
|
|
||||||
expect(controller.total('freightValue')).toEqual(3);
|
|
||||||
expect(controller.total('packageValue')).toEqual(6);
|
|
||||||
expect(controller.total('cc')).toEqual(0.03);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,18 +0,0 @@
|
||||||
Reference: Referencia
|
|
||||||
Warehouse In: Alm. entrada
|
|
||||||
Warehouse Out: Alm. salida
|
|
||||||
Shipped: F. envío
|
|
||||||
Landed: F. entrega
|
|
||||||
Total entries: Ent. totales
|
|
||||||
Delivered: Enviada
|
|
||||||
Received: Recibida
|
|
||||||
Agency: Agencia
|
|
||||||
Entries: Entradas
|
|
||||||
Confirmed: Confirmada
|
|
||||||
Entry Id: Id entrada
|
|
||||||
Supplier: Proveedor
|
|
||||||
Pallet: Pallet
|
|
||||||
Freight: Porte
|
|
||||||
Package: Embalaje
|
|
||||||
Half box: Media caja
|
|
||||||
Go to the travel: Ir al envío
|
|
|
@ -1,6 +0,0 @@
|
||||||
@import "variables";
|
|
||||||
|
|
||||||
|
|
||||||
vn-travel-summary .summary {
|
|
||||||
max-width: $width-lg;
|
|
||||||
}
|
|
|
@ -1,177 +0,0 @@
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
data="$ctrl.dms">
|
|
||||||
</vn-watcher>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="DmsTypes"
|
|
||||||
data="dmsTypes"
|
|
||||||
order="name">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Companies"
|
|
||||||
data="companies"
|
|
||||||
order="code">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-crud-model
|
|
||||||
auto-load="true"
|
|
||||||
url="Warehouses"
|
|
||||||
data="warehouses"
|
|
||||||
order="name">
|
|
||||||
</vn-crud-model>
|
|
||||||
<form
|
|
||||||
name="form"
|
|
||||||
ng-submit="$ctrl.onSubmit()"
|
|
||||||
class="vn-ma-md"
|
|
||||||
enctype="multipart/form-data">
|
|
||||||
<div class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Thermograph"
|
|
||||||
ng-model="$ctrl.dms.thermographId"
|
|
||||||
url="TravelThermographs"
|
|
||||||
where="{travelFk: null}"
|
|
||||||
show-field="thermographFk"
|
|
||||||
value-field="thermographFk">
|
|
||||||
<tpl-item>
|
|
||||||
{{thermographFk}}
|
|
||||||
</tpl-item>
|
|
||||||
<append>
|
|
||||||
<vn-icon-button
|
|
||||||
icon="add_circle"
|
|
||||||
vn-tooltip="New thermograph"
|
|
||||||
ng-click="$ctrl.onAddThermographClick($event)"
|
|
||||||
vn-acl="buyer"
|
|
||||||
vn-acl-action="remove">
|
|
||||||
</vn-icon-button>
|
|
||||||
</append>
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-textfield vn-one
|
|
||||||
label="State"
|
|
||||||
ng-model="$ctrl.dms.state"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield vn-one
|
|
||||||
label="Reference"
|
|
||||||
ng-model="$ctrl.dms.reference"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Type"
|
|
||||||
ng-model="$ctrl.dms.dmsTypeId"
|
|
||||||
data="dmsTypes"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Company"
|
|
||||||
ng-model="$ctrl.dms.companyId"
|
|
||||||
data="companies"
|
|
||||||
show-field="code"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Warehouse"
|
|
||||||
ng-model="$ctrl.dms.warehouseId"
|
|
||||||
data="warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-file
|
|
||||||
vn-one
|
|
||||||
label="File"
|
|
||||||
ng-model="$ctrl.dms.files"
|
|
||||||
accept="{{$ctrl.allowedContentTypes}}"
|
|
||||||
multiple="true">
|
|
||||||
<append>
|
|
||||||
<vn-icon vn-none
|
|
||||||
color-marginal
|
|
||||||
title="{{$ctrl.contentTypesInfo}}"
|
|
||||||
icon="info">
|
|
||||||
</vn-icon>
|
|
||||||
</append>
|
|
||||||
</vn-input-file>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit
|
|
||||||
disabled="!watcher.dataChanged()"
|
|
||||||
label="Upload">
|
|
||||||
</vn-submit>
|
|
||||||
<vn-button
|
|
||||||
class="cancel"
|
|
||||||
label="Cancel"
|
|
||||||
ui-sref="travel.card.thermograph.index">
|
|
||||||
</vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<!-- Create thermograph dialog -->
|
|
||||||
<vn-crud-model
|
|
||||||
vn-id="modelsModel"
|
|
||||||
url="Thermographs/getThermographModels"
|
|
||||||
data="thermographModels">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-crud-model
|
|
||||||
vn-id="temperaturesModel"
|
|
||||||
url="Temperatures"
|
|
||||||
data="Temperatures"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-dialog class="edit"
|
|
||||||
vn-id="newThermographDialog"
|
|
||||||
on-accept="$ctrl.onNewThermographAccept()"
|
|
||||||
message="New thermograph">
|
|
||||||
<tpl-body>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
vn-one
|
|
||||||
required="true"
|
|
||||||
label="Identifier"
|
|
||||||
ng-model="$ctrl.newThermograph.thermographId"
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
required="true"
|
|
||||||
label="Model"
|
|
||||||
ng-model="$ctrl.newThermograph.model"
|
|
||||||
data="thermographModels"
|
|
||||||
show-field="value"
|
|
||||||
value-field="value">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
required="true"
|
|
||||||
label="Warehouse"
|
|
||||||
ng-model="$ctrl.newThermograph.warehouseId"
|
|
||||||
url="Warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
required="true"
|
|
||||||
label="Temperature"
|
|
||||||
ng-model="$ctrl.newThermograph.temperatureFk"
|
|
||||||
data='Temperatures'
|
|
||||||
show-field="name"
|
|
||||||
value-field="code">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
</tpl-body>
|
|
||||||
<tpl-buttons>
|
|
||||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
|
||||||
<button response="accept" translate>Create</button>
|
|
||||||
</tpl-buttons>
|
|
||||||
</vn-dialog>
|
|
|
@ -1,122 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import UserError from 'core/lib/user-error';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $) {
|
|
||||||
super($element, $);
|
|
||||||
this.dms = {files: [], state: 'Ok'};
|
|
||||||
}
|
|
||||||
|
|
||||||
get travel() {
|
|
||||||
return this._travel;
|
|
||||||
}
|
|
||||||
|
|
||||||
set travel(value) {
|
|
||||||
this._travel = value;
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
this.setDefaultParams();
|
|
||||||
this.getAllowedContentTypes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllowedContentTypes() {
|
|
||||||
this.$http.get('DmsContainers/allowedContentTypes').then(res => {
|
|
||||||
const contentTypes = res.data.join(', ');
|
|
||||||
this.allowedContentTypes = contentTypes;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get contentTypesInfo() {
|
|
||||||
return this.$t('ContentTypesInfo', {
|
|
||||||
allowedContentTypes: this.allowedContentTypes
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setDefaultParams() {
|
|
||||||
const params = {filter: {
|
|
||||||
where: {code: 'miscellaneous'}
|
|
||||||
}};
|
|
||||||
this.$http.get('DmsTypes/findOne', {params}).then(res => {
|
|
||||||
const dmsTypeId = res.data && res.data.id;
|
|
||||||
const companyId = this.vnConfig.companyFk;
|
|
||||||
const warehouseId = this.vnConfig.warehouseFk;
|
|
||||||
const defaultParams = {
|
|
||||||
reference: this.travel.id,
|
|
||||||
warehouseId: warehouseId,
|
|
||||||
companyId: companyId,
|
|
||||||
dmsTypeId: dmsTypeId,
|
|
||||||
description: this.$t('TravelFileDescription', {
|
|
||||||
travelId: this.travel.id
|
|
||||||
}).toUpperCase()
|
|
||||||
};
|
|
||||||
|
|
||||||
this.dms = Object.assign(this.dms, defaultParams);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onAddThermographClick(event) {
|
|
||||||
const defaultTemperature = 'cool';
|
|
||||||
const defaultModel = 'DISPOSABLE';
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
this.newThermograph = {
|
|
||||||
thermographId: this.thermographId,
|
|
||||||
warehouseId: this.warehouseId,
|
|
||||||
temperatureFk: defaultTemperature,
|
|
||||||
model: defaultModel
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$.modelsModel.refresh();
|
|
||||||
this.$.newThermographDialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
onNewThermographAccept() {
|
|
||||||
const hasMissingField =
|
|
||||||
!this.newThermograph.thermographId ||
|
|
||||||
!this.newThermograph.warehouseId ||
|
|
||||||
!this.newThermograph.temperatureFk ||
|
|
||||||
!this.newThermograph.model;
|
|
||||||
|
|
||||||
if (hasMissingField)
|
|
||||||
throw new UserError(`Some fields are invalid`);
|
|
||||||
|
|
||||||
return this.$http.post(`Thermographs/createThermograph`, this.newThermograph)
|
|
||||||
.then(res => this.dms.thermographId = res.data.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
const query = `Travels/${this.travel.id}/saveThermograph`;
|
|
||||||
const options = {
|
|
||||||
method: 'POST',
|
|
||||||
url: query,
|
|
||||||
params: this.dms,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': undefined
|
|
||||||
},
|
|
||||||
transformRequest: files => {
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++)
|
|
||||||
formData.append(files[i].name, files[i]);
|
|
||||||
|
|
||||||
return formData;
|
|
||||||
},
|
|
||||||
data: this.dms.files
|
|
||||||
};
|
|
||||||
this.$http(options).then(res => {
|
|
||||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
|
||||||
this.$.watcher.updateOriginalData();
|
|
||||||
this.$state.go('travel.card.thermograph.index');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelThermographCreate', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
travel: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,108 +0,0 @@
|
||||||
import './index';
|
|
||||||
|
|
||||||
describe('Ticket', () => {
|
|
||||||
describe('Component vnTravelThermographCreate', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let $httpParamSerializer;
|
|
||||||
const travelId = 3;
|
|
||||||
const dmsTypeId = 5;
|
|
||||||
|
|
||||||
beforeEach(ngModule('travel'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, _$httpBackend_, _$httpParamSerializer_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$httpParamSerializer = _$httpParamSerializer_;
|
|
||||||
const $element = angular.element('<vn-travel-thermograph-create></vn-travel-thermograph-create>');
|
|
||||||
controller = $componentController('vnTravelThermographCreate', {$element});
|
|
||||||
controller._travel = {
|
|
||||||
id: travelId
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('travel() setter', () => {
|
|
||||||
it('should set the travel data and then call setDefaultParams() and getAllowedContentTypes()', () => {
|
|
||||||
jest.spyOn(controller, 'setDefaultParams');
|
|
||||||
jest.spyOn(controller, 'getAllowedContentTypes');
|
|
||||||
controller.travel = {
|
|
||||||
id: travelId
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.travel).toBeDefined();
|
|
||||||
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
|
||||||
expect(controller.getAllowedContentTypes).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('setDefaultParams()', () => {
|
|
||||||
it('should perform a GET query and define the dms property on controller', () => {
|
|
||||||
const params = {filter: {
|
|
||||||
where: {code: 'miscellaneous'}
|
|
||||||
}};
|
|
||||||
let serializedParams = $httpParamSerializer(params);
|
|
||||||
$httpBackend.expect('GET', `DmsTypes/findOne?${serializedParams}`).respond({id: dmsTypeId, code: 'miscellaneous'});
|
|
||||||
controller.setDefaultParams();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.dms).toBeDefined();
|
|
||||||
expect(controller.dms.reference).toEqual(travelId);
|
|
||||||
expect(controller.dms.dmsTypeId).toEqual(dmsTypeId);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getAllowedContentTypes()', () => {
|
|
||||||
it('should make an HTTP GET request to get the allowed content types', () => {
|
|
||||||
const expectedResponse = ['application/pdf', 'image/png', 'image/jpg'];
|
|
||||||
$httpBackend.expect('GET', `DmsContainers/allowedContentTypes`).respond(expectedResponse);
|
|
||||||
controller.getAllowedContentTypes();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.allowedContentTypes).toBeDefined();
|
|
||||||
expect(controller.allowedContentTypes).toEqual('application/pdf, image/png, image/jpg');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onAddThermographClick()', () => {
|
|
||||||
it('should call the show() function of the create thermograph dialog', () => {
|
|
||||||
controller.$.newThermographDialog = {show: jest.fn()};
|
|
||||||
controller.$.modelsModel = {refresh: jest.fn()};
|
|
||||||
controller.$.temperaturesModel = {refresh: jest.fn()};
|
|
||||||
|
|
||||||
const event = new Event('click');
|
|
||||||
jest.spyOn(event, 'preventDefault');
|
|
||||||
|
|
||||||
controller.onAddThermographClick(event);
|
|
||||||
|
|
||||||
expect(event.preventDefault).toHaveBeenCalledTimes(1);
|
|
||||||
expect(controller.$.newThermographDialog.show).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onNewThermographAccept()', () => {
|
|
||||||
it('should set the created thermograph data on to the controller for the autocomplete to use it', () => {
|
|
||||||
const id = 'the created id';
|
|
||||||
const warehouseId = 1;
|
|
||||||
const temperatureId = 'cool';
|
|
||||||
const model = 'my model';
|
|
||||||
|
|
||||||
controller.newThermograph = {
|
|
||||||
thermographId: id,
|
|
||||||
warehouseId: warehouseId,
|
|
||||||
temperatureFk: temperatureId,
|
|
||||||
model: model
|
|
||||||
};
|
|
||||||
const response = {
|
|
||||||
id: id,
|
|
||||||
warehouseId: warehouseId,
|
|
||||||
temperatureFk: temperatureId,
|
|
||||||
model: model
|
|
||||||
};
|
|
||||||
$httpBackend.when('POST', `Thermographs/createThermograph`).respond(response);
|
|
||||||
controller.onNewThermographAccept();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.dms.thermographId).toEqual(response.id);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,87 +0,0 @@
|
||||||
<vn-watcher
|
|
||||||
vn-id="watcher"
|
|
||||||
data="$ctrl.dms">
|
|
||||||
</vn-watcher>
|
|
||||||
<form
|
|
||||||
name="form"
|
|
||||||
ng-submit="$ctrl.onSubmit()"
|
|
||||||
class="vn-ma-md"
|
|
||||||
enctype="multipart/form-data">
|
|
||||||
<div class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-lg">
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Thermograph"
|
|
||||||
ng-model="$ctrl.thermograph.thermographId"
|
|
||||||
url="TravelThermographs"
|
|
||||||
show-field="thermographFk"
|
|
||||||
value-field="thermographFk"
|
|
||||||
disabled="true">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-textfield vn-one
|
|
||||||
label="State"
|
|
||||||
ng-model="$ctrl.thermograph.state"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield vn-one
|
|
||||||
label="Reference"
|
|
||||||
ng-model="$ctrl.thermograph.reference"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Type"
|
|
||||||
ng-model="$ctrl.thermograph.dmsTypeId"
|
|
||||||
url="DmsTypes"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Company"
|
|
||||||
ng-model="$ctrl.thermograph.companyId"
|
|
||||||
url="Companies"
|
|
||||||
show-field="code"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
label="Warehouse"
|
|
||||||
ng-model="$ctrl.thermograph.warehouseId"
|
|
||||||
url="Warehouses"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textarea vn-one vn-focus
|
|
||||||
label="Description"
|
|
||||||
ng-model="$ctrl.thermograph.description"
|
|
||||||
rule>
|
|
||||||
</vn-textarea>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-file
|
|
||||||
vn-one
|
|
||||||
label="File"
|
|
||||||
ng-model="$ctrl.thermograph.files"
|
|
||||||
on-change="$ctrl.onFileChange($files)"
|
|
||||||
accept="{{$ctrl.allowedContentTypes}}"
|
|
||||||
multiple="true">
|
|
||||||
<append>
|
|
||||||
<vn-icon vn-none
|
|
||||||
color-marginal
|
|
||||||
title="{{$ctrl.contentTypesInfo}}"
|
|
||||||
icon="info">
|
|
||||||
</vn-icon>
|
|
||||||
</append>
|
|
||||||
</vn-input-file>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-card>
|
|
||||||
<vn-button-bar>
|
|
||||||
<vn-submit label="Save"></vn-submit>
|
|
||||||
<vn-button ui-sref="travel.card.thermograph.index" label="Cancel"></vn-button>
|
|
||||||
</vn-button-bar>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
|
@ -1,98 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
get travel() {
|
|
||||||
return this._travel;
|
|
||||||
}
|
|
||||||
|
|
||||||
set travel(value) {
|
|
||||||
this._travel = value;
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
this.setDefaultParams();
|
|
||||||
this.getAllowedContentTypes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllowedContentTypes() {
|
|
||||||
this.$http.get('DmsContainers/allowedContentTypes').then(res => {
|
|
||||||
const contentTypes = res.data.join(', ');
|
|
||||||
this.allowedContentTypes = contentTypes;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get contentTypesInfo() {
|
|
||||||
return this.$t('ContentTypesInfo', {
|
|
||||||
allowedContentTypes: this.allowedContentTypes
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setDefaultParams() {
|
|
||||||
const filterObj = {include: {relation: 'dms'}};
|
|
||||||
const filter = encodeURIComponent(JSON.stringify(filterObj));
|
|
||||||
const path = `TravelThermographs/${this.$params.thermographId}?filter=${filter}`;
|
|
||||||
this.$http.get(path).then(res => {
|
|
||||||
const thermograph = res.data;
|
|
||||||
this.thermograph = {
|
|
||||||
thermographId: thermograph.thermographFk,
|
|
||||||
state: thermograph.result,
|
|
||||||
reference: thermograph.dms.reference,
|
|
||||||
warehouseId: thermograph.dms.warehouseFk,
|
|
||||||
companyId: thermograph.dms.companyFk,
|
|
||||||
dmsTypeId: thermograph.dms.dmsTypeFk,
|
|
||||||
description: thermograph.dms.description,
|
|
||||||
hasFile: thermograph.dms.hasFile,
|
|
||||||
hasFileAttached: false,
|
|
||||||
files: []
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
const query = `travels/${this.$params.id}/saveThermograph`;
|
|
||||||
const options = {
|
|
||||||
method: 'POST',
|
|
||||||
url: query,
|
|
||||||
params: this.thermograph,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': undefined
|
|
||||||
},
|
|
||||||
transformRequest: files => {
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
for (const element of files)
|
|
||||||
formData.append(element.name, element);
|
|
||||||
|
|
||||||
return formData;
|
|
||||||
},
|
|
||||||
data: this.thermograph.files
|
|
||||||
};
|
|
||||||
this.$http(options).then(res => {
|
|
||||||
if (res) {
|
|
||||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
|
||||||
this.$.watcher.updateOriginalData();
|
|
||||||
this.$state.go('travel.card.thermograph.index');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onFileChange(files) {
|
|
||||||
let hasFileAttached = false;
|
|
||||||
if (files.length > 0)
|
|
||||||
hasFileAttached = true;
|
|
||||||
|
|
||||||
this.$.$applyAsync(() => {
|
|
||||||
this.thermograph.hasFileAttached = hasFileAttached;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelThermographEdit', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
travel: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,120 +0,0 @@
|
||||||
import './index';
|
|
||||||
import watcher from 'core/mocks/watcher.js';
|
|
||||||
|
|
||||||
describe('Worker', () => {
|
|
||||||
describe('Component vnTravelThermographEdit', () => {
|
|
||||||
let controller;
|
|
||||||
let $scope;
|
|
||||||
let $httpBackend;
|
|
||||||
let $httpParamSerializer;
|
|
||||||
|
|
||||||
beforeEach(ngModule('travel'));
|
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$httpParamSerializer = _$httpParamSerializer_;
|
|
||||||
const $element = angular.element(`<vn-travel-thermograph-edit></vn-travel-thermograph-edit`);
|
|
||||||
controller = $componentController('vnTravelThermographEdit', {$element, $scope});
|
|
||||||
controller._travel = {id: 3};
|
|
||||||
controller.$params = {id: 3, thermographId: 6};
|
|
||||||
controller.$.watcher = watcher;
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('travel() setter', () => {
|
|
||||||
it('should set the travel data and then call setDefaultParams() and getAllowedContentTypes()', () => {
|
|
||||||
jest.spyOn(controller, 'setDefaultParams');
|
|
||||||
jest.spyOn(controller, 'getAllowedContentTypes');
|
|
||||||
controller._travel = undefined;
|
|
||||||
controller.travel = {
|
|
||||||
id: 3
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.setDefaultParams).toHaveBeenCalledWith();
|
|
||||||
expect(controller.travel).toBeDefined();
|
|
||||||
expect(controller.getAllowedContentTypes).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('setDefaultParams()', () => {
|
|
||||||
it('should perform a GET query and define the dms property on controller', () => {
|
|
||||||
const thermographId = 6;
|
|
||||||
const expectedResponse = {
|
|
||||||
thermographFk: 6,
|
|
||||||
result: 'Ok',
|
|
||||||
dms: {
|
|
||||||
reference: '123456-01',
|
|
||||||
warehouseFk: 1,
|
|
||||||
companyFk: 442,
|
|
||||||
dmsTypeFk: 3,
|
|
||||||
description: 'Test'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const filterObj = {include: {relation: 'dms'}};
|
|
||||||
const filter = encodeURIComponent(JSON.stringify(filterObj));
|
|
||||||
const query = `TravelThermographs/${thermographId}?filter=${filter}`;
|
|
||||||
$httpBackend.expect('GET', query).respond(expectedResponse);
|
|
||||||
controller.setDefaultParams();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.thermograph).toBeDefined();
|
|
||||||
expect(controller.thermograph.reference).toEqual('123456-01');
|
|
||||||
expect(controller.thermograph.dmsTypeId).toEqual(3);
|
|
||||||
expect(controller.thermograph.state).toEqual('Ok');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onFileChange()', () => {
|
|
||||||
it('should set dms hasFileAttached property to true if has any files', () => {
|
|
||||||
const files = [{id: 1, name: 'MyFile'}];
|
|
||||||
controller.thermograph = {hasFileAttached: false};
|
|
||||||
controller.onFileChange(files);
|
|
||||||
$scope.$apply();
|
|
||||||
|
|
||||||
expect(controller.thermograph.hasFileAttached).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getAllowedContentTypes()', () => {
|
|
||||||
it('should make an HTTP GET request to get the allowed content types', () => {
|
|
||||||
const expectedResponse = ['image/png', 'image/jpg'];
|
|
||||||
$httpBackend.expect('GET', `DmsContainers/allowedContentTypes`).respond(expectedResponse);
|
|
||||||
controller.getAllowedContentTypes();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.allowedContentTypes).toBeDefined();
|
|
||||||
expect(controller.allowedContentTypes).toEqual('image/png, image/jpg');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('contentTypesInfo()', () => {
|
|
||||||
it('should return a description with a list of allowed content types', () => {
|
|
||||||
controller.allowedContentTypes = ['image/png', 'image/jpg'];
|
|
||||||
const expectedTypes = controller.allowedContentTypes.join(', ');
|
|
||||||
|
|
||||||
const expectedResult = `Allowed content types: ${expectedTypes}`;
|
|
||||||
jest.spyOn(controller.$translate, 'instant').mockReturnValue(expectedResult);
|
|
||||||
|
|
||||||
const result = controller.contentTypesInfo;
|
|
||||||
|
|
||||||
expect(result).toEqual(expectedResult);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onSubmit()', () => {
|
|
||||||
it('should make an HTTP POST request to save the form data', () => {
|
|
||||||
jest.spyOn(controller.$.watcher, 'updateOriginalData');
|
|
||||||
|
|
||||||
const files = [{id: 1, name: 'MyFile'}];
|
|
||||||
controller.thermograph = {files};
|
|
||||||
const serializedParams = $httpParamSerializer(controller.thermograph);
|
|
||||||
const query = `travels/${controller.$params.id}/saveThermograph?${serializedParams}`;
|
|
||||||
|
|
||||||
$httpBackend.expect('POST', query).respond({});
|
|
||||||
controller.onSubmit();
|
|
||||||
$httpBackend.flush();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,7 +0,0 @@
|
||||||
vn-ticket-request {
|
|
||||||
.vn-textfield {
|
|
||||||
margin: 0!important;
|
|
||||||
max-width: 100px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="TravelThermographs"
|
|
||||||
data="$ctrl.travelThermographs"
|
|
||||||
order="created"
|
|
||||||
link="{travelFk: $ctrl.$params.id}"
|
|
||||||
filter="$ctrl.filter"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-data-viewer model="model">
|
|
||||||
<form name="form">
|
|
||||||
<vn-card class="vn-mt-md">
|
|
||||||
<vn-table model="model" auto-load="false">
|
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th>Code</vn-th>
|
|
||||||
<vn-th>Temperature</vn-th>
|
|
||||||
<vn-th expand>State</vn-th>
|
|
||||||
<vn-th>Destination</vn-th>
|
|
||||||
<vn-th expand>Created</vn-th>
|
|
||||||
<vn-th shrink></vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="thermograph in $ctrl.travelThermographs">
|
|
||||||
<vn-td>{{::thermograph.thermographFk}} </vn-td>
|
|
||||||
<vn-td>{{::thermograph.temperatureFk}} </vn-td>
|
|
||||||
<vn-td expand>{{::thermograph.result}}</vn-td>
|
|
||||||
<vn-td>{{::thermograph.warehouse.name}}</vn-td>
|
|
||||||
<vn-td expand>{{::thermograph.created | date: 'dd/MM/yyyy'}}</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-icon-button title="{{'Download file' | translate}}"
|
|
||||||
icon="cloud_download"
|
|
||||||
ng-click="$ctrl.downloadFile(thermograph.dmsFk)">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-icon-button ui-sref="travel.card.thermograph.edit({thermographId: {{::thermograph.id}}})"
|
|
||||||
icon="edit"
|
|
||||||
title="{{'Edit file' | translate}}">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-icon-button
|
|
||||||
icon="delete"
|
|
||||||
ng-click="$ctrl.showDeleteConfirm($index)"
|
|
||||||
title="{{'Remove thermograph' | translate}}"
|
|
||||||
tabindex="-1">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-card>
|
|
||||||
</form>
|
|
||||||
</vn-data-viewer>
|
|
||||||
|
|
||||||
<vn-confirm
|
|
||||||
vn-id="confirm"
|
|
||||||
question="Are you sure you want to remove the thermograph?"
|
|
||||||
on-accept="$ctrl.deleteThermograph()">
|
|
||||||
</vn-confirm>
|
|
||||||
|
|
||||||
<a
|
|
||||||
ui-sref="travel.card.thermograph.create"
|
|
||||||
vn-tooltip="Add thermograph"
|
|
||||||
vn-bind="+"
|
|
||||||
fixed-bottom-right>
|
|
||||||
<vn-float-button icon="add"></vn-float-button>
|
|
||||||
</a>
|
|
|
@ -1,51 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Section from 'salix/components/section';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
class Controller extends Section {
|
|
||||||
constructor($element, $, vnFile) {
|
|
||||||
super($element, $);
|
|
||||||
this.vnFile = vnFile;
|
|
||||||
this.filter = {
|
|
||||||
include:
|
|
||||||
{relation: 'warehouse',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'name']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
showDeleteConfirm(index) {
|
|
||||||
this.thermographIndex = index;
|
|
||||||
this.$.confirm.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteThermograph() {
|
|
||||||
const data = this.travelThermographs;
|
|
||||||
const thermographId = data[this.thermographIndex].id;
|
|
||||||
const query = `Travels/deleteThermograph?id=${thermographId}`;
|
|
||||||
this.$http.delete(query).then(() => {
|
|
||||||
this.vnApp.showSuccess(this.$t('Thermograph deleted'));
|
|
||||||
this.$.model.remove(this.thermographIndex);
|
|
||||||
this.thermographIndex = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
downloadFile(dmsId) {
|
|
||||||
this.vnFile.download(`api/dms/${dmsId}/downloadFile`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope', 'vnFile'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnTravelThermographIndex', {
|
|
||||||
template: require('./index.html'),
|
|
||||||
controller: Controller,
|
|
||||||
require: {
|
|
||||||
card: '^vnTravelCard'
|
|
||||||
},
|
|
||||||
bindings: {
|
|
||||||
travel: '<'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,6 +0,0 @@
|
||||||
@import "variables";
|
|
||||||
|
|
||||||
vn-route-tickets form{
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width: $width-lg;
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
Code: Código
|
|
||||||
Temperature: Temperatura
|
|
||||||
State: Estado
|
|
||||||
Destination: Destino
|
|
||||||
Created: Creado
|
|
||||||
Remove thermograph: Eliminar termógrafo
|
|
||||||
Upload file: Subir fichero
|
|
||||||
Edit file: Editar fichero
|
|
||||||
Upload: Subir
|
|
||||||
File: Fichero
|
|
||||||
TravelFileDescription: Travel id {{travelId}}
|
|
||||||
ContentTypesInfo: 'Tipos de archivo permitidos: {{allowedContentTypes}}'
|
|
||||||
Are you sure you want to continue?: ¿Seguro que quieres continuar?
|
|
||||||
Add thermograph: Añadir termógrafo
|
|
||||||
Edit thermograph: Editar termógrafo
|
|
||||||
Thermograph deleted: Termógrafo eliminado
|
|
||||||
Thermograph: Termógrafo
|
|
||||||
New thermograph: Nuevo termógrafo
|
|
||||||
Are you sure you want to remove the thermograph?: ¿Seguro que quieres quitar el termógrafo?
|
|
||||||
Identifier: Identificador
|
|
Loading…
Reference in New Issue