added zone index & zone create
This commit is contained in:
parent
fd08bb96dd
commit
d5ca385ccd
|
@ -49,6 +49,9 @@
|
|||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
<vn-pagination
|
||||
|
|
|
@ -41,3 +41,4 @@ import './th';
|
|||
import './input-range';
|
||||
import './chip';
|
||||
import './input-number';
|
||||
import './input-time';
|
||||
|
|
|
@ -45,7 +45,7 @@ export default class InputNumber extends Textfield {
|
|||
}
|
||||
|
||||
get step() {
|
||||
return parseInt(this.input.step);
|
||||
return parseFloat(this.input.step);
|
||||
}
|
||||
|
||||
set step(value) {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<div class="container"
|
||||
ng-class="{selected: $ctrl.hasFocus}">
|
||||
<div class="textField">
|
||||
<div class="leftIcons" ng-transclude="leftIcons"></div>
|
||||
<div class="infix">
|
||||
<input
|
||||
class="mdl-textfield__input"
|
||||
type="time"
|
||||
ng-model="$ctrl.value"
|
||||
vn-validation="{{$ctrl.rule}}"
|
||||
ng-disabled="$ctrl.disabled"
|
||||
ng-readonly="$ctrl.readonly"
|
||||
ng-focus="$ctrl.hasFocus = true"
|
||||
ng-blur="$ctrl.hasFocus = false"
|
||||
tabindex="{{$ctrl.input.tabindex}}"/>
|
||||
<label class="label" translate>{{::$ctrl.label}}</label>
|
||||
</div>
|
||||
<div class="underline"></div>
|
||||
<div class="selected underline"></div>
|
||||
<div class="suffix">
|
||||
<i class="material-icons clear"
|
||||
translate-attr="{title: 'Clear'}"
|
||||
ng-show="!$ctrl.disabled
|
||||
&& $ctrl.hasValue
|
||||
&& !$ctrl.unclearable"
|
||||
ng-click="$ctrl.clear()">
|
||||
clear
|
||||
</i>
|
||||
<i class="material-icons"
|
||||
ng-if="$ctrl.hasInfo"
|
||||
vn-tooltip="{{$ctrl.info}}">
|
||||
info_outline
|
||||
</i>
|
||||
</div>
|
||||
<div class="rightIcons" ng-transclude="rightIcons"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,55 @@
|
|||
import ngModule from '../../module';
|
||||
import Textfield from '../textfield/textfield';
|
||||
import './style.scss';
|
||||
|
||||
export default class InputTime extends Textfield {
|
||||
|
||||
constructor($element, $scope, $attrs, vnTemplate, $transclude, $filter) {
|
||||
super($element, $scope, $attrs, vnTemplate, $transclude);
|
||||
|
||||
this.$filter = $filter;
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
set value(value) {
|
||||
this._value = value;
|
||||
this.hasValue = this._value !== null;
|
||||
|
||||
if (this.hasValue) this.element.classList.add('not-empty');
|
||||
|
||||
this.element.querySelector('.infix').classList.remove('invalid', 'validated');
|
||||
}
|
||||
|
||||
get step() {
|
||||
return parseFloat(this.input.step);
|
||||
}
|
||||
|
||||
set step(value) {
|
||||
this.input.step = value;
|
||||
}
|
||||
}
|
||||
|
||||
InputTime.$inject = ['$element', '$scope', '$attrs', 'vnTemplate', '$transclude', '$filter'];
|
||||
|
||||
ngModule.component('vnInputTime', {
|
||||
template: require('./index.html'),
|
||||
controller: InputTime,
|
||||
transclude: {
|
||||
leftIcons: '?tLeftIcons',
|
||||
rightIcons: '?tRightIcons'
|
||||
},
|
||||
bindings: {
|
||||
label: '@?',
|
||||
disabled: '<?',
|
||||
readonly: '<?',
|
||||
step: '<?',
|
||||
rule: '@?',
|
||||
value: '=model',
|
||||
vnTabIndex: '@?',
|
||||
onChange: '&',
|
||||
onClear: '&'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,60 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Component vnInputNumber', () => {
|
||||
let $componentController;
|
||||
let $scope;
|
||||
let $attrs;
|
||||
let $timeout;
|
||||
let $element;
|
||||
let controller;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('claim');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _$timeout_) => {
|
||||
$componentController = _$componentController_;
|
||||
$scope = $rootScope.$new();
|
||||
$attrs = {};
|
||||
$timeout = _$timeout_;
|
||||
$element = angular.element('<div><input><div class="infix invalid validated"><div class="rightIcons"></div></div>');
|
||||
controller = $componentController('vnInputNumber', {$element, $scope, $attrs, $timeout, $transclude: () => {}});
|
||||
}));
|
||||
|
||||
describe('value() setter', () => {
|
||||
it(`should set _value to a given value, add the class not-empty and remove invalid and validated`, () => {
|
||||
controller.value = 'pepino';
|
||||
let classes = controller.element.classList.toString();
|
||||
|
||||
expect(classes).toContain('not-empty');
|
||||
expect(controller._value).toEqual('pepino');
|
||||
|
||||
classes = controller.element.querySelector('.infix').classList.toString();
|
||||
|
||||
expect(classes).not.toContain('invalid validated');
|
||||
});
|
||||
|
||||
it(`should set _value to a given value and not add the class not-empty if the given value is null`, () => {
|
||||
controller.value = null;
|
||||
let classes = controller.element.classList.toString();
|
||||
|
||||
expect(classes).not.toContain('not-empty');
|
||||
expect(controller._value).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('step() setter/getter', () => {
|
||||
it(`should set input.step to a given value`, () => {
|
||||
controller.step = 50;
|
||||
|
||||
expect(controller.input.step).toEqual('50');
|
||||
});
|
||||
|
||||
it(`should return a number`, () => {
|
||||
controller.step = 50;
|
||||
|
||||
expect(controller.step).toEqual(50);
|
||||
expect(typeof controller.step).toEqual('number');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
@import 'colors';
|
||||
@import '../textfield/style.scss';
|
||||
|
||||
vn-input-time {
|
||||
@extend vn-textfield;
|
||||
|
||||
input[type="time"] {
|
||||
clip-path: inset(0 17px 0 0);
|
||||
outline:none;
|
||||
outline:0;
|
||||
}
|
||||
}
|
|
@ -26,7 +26,6 @@ vn-textfield {
|
|||
}
|
||||
}
|
||||
.infix {
|
||||
position: relative;
|
||||
display: block;
|
||||
flex: auto;
|
||||
width: 100%;
|
||||
|
@ -49,6 +48,7 @@ vn-textfield {
|
|||
label {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 4px 0!important;
|
||||
pointer-events: none;
|
||||
color: $secondary-font-color;
|
||||
|
|
|
@ -7,5 +7,6 @@ module.exports.watcher = {
|
|||
check: () => {},
|
||||
notifySaved: () => {},
|
||||
setDirty: () => {},
|
||||
setPristine: () => {}
|
||||
setPristine: () => {},
|
||||
updateOriginalData: () => {}
|
||||
};
|
||||
|
|
|
@ -6,3 +6,4 @@ salix: []
|
|||
ticket: [item, client]
|
||||
order: [item, ticket]
|
||||
claim: [item, client]
|
||||
route: []
|
||||
|
|
|
@ -4,19 +4,57 @@
|
|||
"icon" : "local_shipping",
|
||||
"validations" : true,
|
||||
"routes": [
|
||||
{
|
||||
"url": "/routes",
|
||||
"state": "routes",
|
||||
/* {
|
||||
"url": "/route",
|
||||
"state": "route",
|
||||
"abstract": true,
|
||||
"component": "ui-view",
|
||||
"description": "Routes"
|
||||
},
|
||||
{
|
||||
"url": "/index?q",
|
||||
"state": "routes.index",
|
||||
"state": "route.index",
|
||||
"component": "vn-route-index",
|
||||
"description": "List",
|
||||
"acl": ["developer"]
|
||||
}, */
|
||||
{
|
||||
"url": "/zone",
|
||||
"state": "zone",
|
||||
"abstract": true,
|
||||
"component": "ui-view",
|
||||
"description": "Zones"
|
||||
},
|
||||
{
|
||||
"url": "/index?q",
|
||||
"state": "zone.index",
|
||||
"component": "vn-zone-index",
|
||||
"description": "List",
|
||||
"acl": ["developer"]
|
||||
},
|
||||
{
|
||||
"url": "/create",
|
||||
"state": "zone.create",
|
||||
"component": "vn-zone-create",
|
||||
"description": "New zone"
|
||||
},
|
||||
{
|
||||
"url": "/:id",
|
||||
"state": "zone.card",
|
||||
"abstract": true,
|
||||
"component": "vn-zone-card"
|
||||
},
|
||||
{
|
||||
"url": "/basic-data",
|
||||
"state": "zone.card.basicData",
|
||||
"component": "vn-zone-basic-data",
|
||||
"description": "Basic data",
|
||||
"params": {
|
||||
"client": "$ctrl.client"
|
||||
},
|
||||
"menu": {
|
||||
"icon": "settings"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,3 +1,8 @@
|
|||
export * from './module';
|
||||
|
||||
// import components
|
||||
import './zone/card';
|
||||
import './zone/descriptor';
|
||||
import './zone/search-panel';
|
||||
import './zone/index';
|
||||
import './zone/create';
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
Basic data: Datos básicos
|
||||
Logistic data: Datos logísticos
|
||||
Assigned tickets: Tickets asignados
|
||||
Routes: Rutas
|
||||
Route: Ruta
|
||||
Date: Fecha
|
||||
Name: Nombre
|
||||
Agency: Agencia
|
||||
Driver: Conductor
|
||||
Vehicle: Vehículo
|
||||
Start Hour: Hora Inicio
|
||||
End Hour: Hora Fin
|
||||
Start Km: Km Inicio
|
||||
End Km: Km Fin
|
||||
Packages: Bultos
|
||||
Route document: Documento de Ruta
|
||||
Warehouse: Almacén
|
||||
Hour: Hora (ETD)
|
||||
Price: Precio
|
||||
Create: Crear
|
||||
|
||||
Zones: Zonas
|
||||
List: Listado
|
||||
New zone: Nueva zona
|
||||
Basic data: Datos básicos
|
|
@ -1,5 +1,5 @@
|
|||
import {ng} from 'vendor';
|
||||
import 'core';
|
||||
|
||||
const ngModule = ng.module('route', []);
|
||||
const ngModule = ng.module('route', ['vnCore']);
|
||||
export default ngModule;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<vn-main-block>
|
||||
<vn-horizontal>
|
||||
<vn-auto class="left-block">
|
||||
<vn-zone-descriptor order="$ctrl.zone"></vn-zone-descriptor>
|
||||
<vn-left-menu></vn-left-menu>
|
||||
</vn-auto>
|
||||
<vn-one>
|
||||
<vn-vertical margin-medium ui-view></vn-vertical>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-main-block>
|
|
@ -0,0 +1,60 @@
|
|||
import ngModule from '../../module';
|
||||
|
||||
class Controller {
|
||||
constructor($http, $state) {
|
||||
this.$http = $http;
|
||||
this.$state = $state;
|
||||
this.order = {};
|
||||
this.filter = {
|
||||
include: [
|
||||
{relation: 'agencyMode', scope: {fields: ['name']}},
|
||||
{relation: 'address', scope: {fields: ['nickname']}},
|
||||
{relation: 'rows', scope: {fields: ['id']}},
|
||||
{
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: ['salesPersonFk', 'name', 'isActive', 'isFreezed', 'isTaxDataChecked'],
|
||||
include: {
|
||||
relation: 'salesPerson',
|
||||
fields: ['firstName', 'name']
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/* getOrder() {
|
||||
let json = encodeURIComponent(JSON.stringify(this.filter));
|
||||
let query = `/order/api/Orders/${this.$state.params.id}?filter=${json}`;
|
||||
this.$http.get(query).then(res => {
|
||||
if (res.data) {
|
||||
this.order = res.data;
|
||||
this.getTotal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getTotal() {
|
||||
let query = `/order/api/Orders/${this.$state.params.id}/getTotal`;
|
||||
this.$http.get(query).then(res => {
|
||||
if (res.data) {
|
||||
this.order.total = res.data.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
$onInit() {
|
||||
this.getOrder();
|
||||
}
|
||||
|
||||
reload() {
|
||||
this.getOrder();
|
||||
} */
|
||||
}
|
||||
|
||||
Controller.$inject = ['$http', '$state'];
|
||||
|
||||
ngModule.component('vnZoneCard', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,68 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Order', () => {
|
||||
describe('Component vnOrderCard', () => {
|
||||
let $componentController;
|
||||
let $scope;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
let $state;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('order');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_) => {
|
||||
$componentController = _$componentController_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
$scope = $rootScope.$new();
|
||||
$scope.card = {createOrder: () => {}};
|
||||
$state = {params: {id: 1}};
|
||||
controller = $componentController('vnOrderCard', {$scope: $scope, $state: $state});
|
||||
}));
|
||||
|
||||
describe('getOrder()', () => {
|
||||
it(`should make a query, save the data in order and call get order if the response has data`, () => {
|
||||
spyOn(controller, 'getTotal');
|
||||
let json = encodeURIComponent(JSON.stringify(controller.filter));
|
||||
$httpBackend.expectGET(`/order/api/Orders/${controller.$state.params.id}?filter=${json}`).respond({id: 1});
|
||||
controller.getOrder();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.order).toEqual({id: 1});
|
||||
expect(controller.getTotal).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it(`should make a query and not call getTotal if the response is not defined`, () => {
|
||||
spyOn(controller, 'getTotal');
|
||||
let json = encodeURIComponent(JSON.stringify(controller.filter));
|
||||
$httpBackend.expectGET(`/order/api/Orders/${controller.$state.params.id}?filter=${json}`).respond(undefined);
|
||||
controller.getOrder();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.order).toEqual({});
|
||||
expect(controller.getTotal).not.toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTotal()', () => {
|
||||
it(`should make a query and save the data in order.total`, () => {
|
||||
$httpBackend.expectGET(`/order/api/Orders/${controller.$state.params.id}/getTotal`).respond({total: '20M'});
|
||||
controller.getTotal();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.order.total).toEqual('20M');
|
||||
});
|
||||
|
||||
it(`should make a query and not save the respones if is not defined`, () => {
|
||||
$httpBackend.expectGET(`/order/api/Orders/${controller.$state.params.id}/getTotal`).respond();
|
||||
controller.getTotal();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.order.total).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.zone"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form name="form" ng-submit="$ctrl.onSubmit()" margin-medium>
|
||||
<div style="max-width: 50em; margin: 0 auto;">
|
||||
<vn-card pad-large>
|
||||
<vn-title>New zone</vn-title>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-two vn-focus
|
||||
label="Name"
|
||||
field="$ctrl.zone.name">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
field="$ctrl.zone.warehouseFk"
|
||||
url="/route/api/Warehouses"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Warehouse">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
field="$ctrl.zone.agencyModeFk"
|
||||
url="/route/api/AgencyModes"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Agency">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
vn-two
|
||||
min="0"
|
||||
value="$ctrl.zone.travelingDays"
|
||||
step="1"
|
||||
label="Traveling days"
|
||||
field="$ctrl.zone.travelingDays">
|
||||
</vn-input-number>
|
||||
<vn-input-time
|
||||
vn-two
|
||||
label="Estimated hour (ETD)"
|
||||
field="$ctrl.zone.hour">
|
||||
</vn-input-time>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number vn-one
|
||||
label="Price"
|
||||
field="$ctrl.zone.price"
|
||||
min="0.00"
|
||||
step="0.50">
|
||||
</vn-input-number>
|
||||
<vn-input-number vn-one
|
||||
label="Bonus"
|
||||
field="$ctrl.zone.bonus"
|
||||
min="0.00"
|
||||
step="0.50">
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Create"></vn-submit>
|
||||
<vn-button ui-sref="zone.index" label="Cancel"></vn-button>
|
||||
</vn-button-bar>
|
||||
</div>
|
||||
</form>
|
|
@ -0,0 +1,34 @@
|
|||
import ngModule from '../../module';
|
||||
|
||||
export default class Controller {
|
||||
constructor($scope, $state, $http) {
|
||||
this.$scope = $scope;
|
||||
this.$state = $state;
|
||||
this.$http = $http;
|
||||
this.zone = {
|
||||
travelingDays: 0,
|
||||
price: 0.50,
|
||||
bonus: 0.50
|
||||
};
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.$scope.watcher.check();
|
||||
|
||||
let data = Object.assign({}, this.zone);
|
||||
data.hour = new Date(this.zone.hour);
|
||||
|
||||
this.$http.post('/route/api/Zones', data).then(res => {
|
||||
this.$scope.watcher.updateOriginalData();
|
||||
this.$scope.watcher.setPristine();
|
||||
this.$scope.watcher.notifySaved();
|
||||
this.$state.go('zone.card.basicData', {id: res.data.id});
|
||||
});
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$scope', '$state', '$http'];
|
||||
|
||||
ngModule.component('vnZoneCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
import './index';
|
||||
import {watcher} from '../../../../helpers/watcherHelper';
|
||||
|
||||
describe('Route', () => {
|
||||
describe('Component vnZoneCreate', () => {
|
||||
let $componentController;
|
||||
let $httpBackend;
|
||||
let $scope;
|
||||
let $state;
|
||||
let controller;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('route');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _$state_) => {
|
||||
$componentController = _$componentController_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
|
||||
$httpBackend.when('GET', 'claim/api/Claims/ClaimBeginnings').respond({});
|
||||
$scope = $rootScope.$new();
|
||||
$state = _$state_;
|
||||
$scope.watcher = watcher;
|
||||
controller = $componentController('vnZoneCreate', {$scope: $scope});
|
||||
}));
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it(`should call submit() on the watcher then expect a callback`, () => {
|
||||
spyOn($state, 'go');
|
||||
|
||||
controller.zone = {
|
||||
name: 'Zone One'
|
||||
};
|
||||
|
||||
$httpBackend.expectPOST(`/route/api/Zones`).respond({id: 1234});
|
||||
controller.onSubmit();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('zone.card.basicData', {id: 1234});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
Traveling days: Días de viaje
|
||||
Estimated hour (ETD): Hora estimada (ETD)
|
||||
Bonus: Bonificación
|
|
@ -0,0 +1,19 @@
|
|||
<vn-card margin-medium-v class="vn-descriptor">
|
||||
<vn-horizontal class="header">
|
||||
<a translate-attr="{title: 'Return to module index'}" ui-sref="zone.index">
|
||||
<vn-icon icon="chevron_left"></vn-icon>
|
||||
</a>
|
||||
<vn-icon icon="my_location"></vn-icon>
|
||||
<a translate-attr="{title: 'Preview'}" ui-sref="order.card.summary">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
</vn-horizontal>
|
||||
<div pad-medium>
|
||||
<vn-label-value label="ID"
|
||||
value="{{$ctrl.zone.id}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Client"
|
||||
value="{{$ctrl.order.client.name}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
</vn-card>
|
|
@ -0,0 +1,18 @@
|
|||
import ngModule from '../../module';
|
||||
import './style.scss';
|
||||
|
||||
class Controller {
|
||||
constructor($translate) {
|
||||
this.translate = $translate;
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$translate'];
|
||||
|
||||
ngModule.component('vnZoneDescriptor', {
|
||||
template: require('./index.html'),
|
||||
bindings: {
|
||||
order: '<'
|
||||
},
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
Client: Cliente
|
||||
Confirmed: Confirmado
|
||||
Not confirmed: Sin confirmar
|
||||
State: Estado
|
||||
Landed: F. entrega
|
||||
Items: Articulos
|
||||
Agency: Agencia
|
||||
Sales person: Comercial
|
|
@ -0,0 +1,5 @@
|
|||
vn-label-value[label=Total]{
|
||||
padding-top: 10px;
|
||||
display: block;
|
||||
font-size: 1.2em;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/route/api/Zones"
|
||||
filter="::$ctrl.filter"
|
||||
limit="20"
|
||||
data="zones"
|
||||
auto-load="false">
|
||||
</vn-crud-model>
|
||||
<div margin-medium>
|
||||
<div class="vn-list">
|
||||
<vn-card pad-medium-h>
|
||||
<vn-searchbar
|
||||
panel="vn-zone-search-panel"
|
||||
model="model"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)"
|
||||
vn-focus>
|
||||
</vn-searchbar>
|
||||
</vn-card>
|
||||
</div>
|
||||
<vn-card margin-medium-v pad-medium>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th field="id" number>Id</vn-th>
|
||||
<vn-th field="name">Name</vn-th>
|
||||
<vn-th field="agencyModeFk">Agency</vn-th>
|
||||
<vn-th field="warehouseFK">Warehouse</vn-th>
|
||||
<vn-th field="hour">Hour</vn-th>
|
||||
<vn-th field="price">Price</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="zone in zones" ui-sref="zone.card.basicData({id: zone.id})" class=clickable>
|
||||
<vn-td number>{{::zone.id}}</vn-td>
|
||||
<vn-td>{{::zone.name}}</vn-td>
|
||||
<vn-td>{{::zone.agencyMode.name}}</vn-td>
|
||||
<vn-td>{{::zone.warehouse.name}}</vn-td>
|
||||
<vn-td>{{::zone.hour | date: 'HH:mm'}}</vn-td>
|
||||
<vn-td number>{{::zone.price | currency:'€':2}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
scroll-selector="ui-view">
|
||||
</vn-pagination>
|
||||
</div>
|
||||
|
||||
<a ui-sref="zone.create" vn-tooltip="New zone" vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add_location"></vn-float-button>
|
||||
</a>
|
|
@ -0,0 +1,32 @@
|
|||
import ngModule from '../../module';
|
||||
|
||||
export default class Controller {
|
||||
constructor($scope) {
|
||||
this.$scope = $scope;
|
||||
this.filter = {
|
||||
include: [
|
||||
{relation: 'agencyMode', fields: ['name']},
|
||||
{relation: 'warehouse', fields: ['name']}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? {id: value}
|
||||
: {name: {regexp: value}};
|
||||
case 'warehouseFk':
|
||||
case 'agencyModeFk':
|
||||
return {[param]: value};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope'];
|
||||
|
||||
ngModule.component('vnZoneIndex', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Route', () => {
|
||||
describe('Component vnZoneIndex', () => {
|
||||
let $componentController;
|
||||
let controller;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('route');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject(_$componentController_ => {
|
||||
$componentController = _$componentController_;
|
||||
controller = $componentController('vnZoneIndex');
|
||||
}));
|
||||
|
||||
describe('exprBuilder()', () => {
|
||||
it('should return a formated object with the id in case of search', () => {
|
||||
let param = 'search';
|
||||
let value = 1;
|
||||
let result = controller.exprBuilder(param, value);
|
||||
|
||||
expect(result).toEqual({id: 1});
|
||||
});
|
||||
|
||||
it('should return a formated object with the warehouseFk in case of warehouseFk', () => {
|
||||
let param = 'warehouseFk';
|
||||
let value = 'Silla';
|
||||
let result = controller.exprBuilder(param, value);
|
||||
|
||||
expect(result).toEqual({warehouseFk: 'Silla'});
|
||||
});
|
||||
|
||||
it('should return a formated object with the warehouseFk in case of warehouseFk', () => {
|
||||
let param = 'agencyModeFk';
|
||||
let value = 'My Delivery';
|
||||
let result = controller.exprBuilder(param, value);
|
||||
|
||||
expect(result).toEqual({agencyModeFk: 'My Delivery'});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
<div pad-large style="min-width: 30em">
|
||||
<form ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Name"
|
||||
model="filter.name"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Agency"
|
||||
field="filter.agencyModeFk"
|
||||
url="/route/api/AgencyModes"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Warehouse"
|
||||
field="filter.warehouseFk"
|
||||
url="/route/api/Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal margin-large-top>
|
||||
<vn-submit label="Search"></vn-submit>
|
||||
</vn-horizontal>
|
||||
</form>
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
import ngModule from '../../module';
|
||||
import SearchPanel from 'core/src/components/searchbar/search-panel';
|
||||
|
||||
ngModule.component('vnZoneSearchPanel', {
|
||||
template: require('./index.html'),
|
||||
controller: SearchPanel
|
||||
});
|
|
@ -75,6 +75,9 @@
|
|||
</vn-td>
|
||||
</a>
|
||||
</vn-tbody>
|
||||
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||
No results
|
||||
</vn-empty-rows>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
<vn-pagination
|
||||
|
|
|
@ -87,7 +87,7 @@ describe('Ticket Create packages path', () => {
|
|||
.click(selectors.ticketPackages.savePackagesButton)
|
||||
.waitForLastSnackbar()
|
||||
.then(result => {
|
||||
expect(result).toEqual('The package cannot be blank');
|
||||
expect(result).toEqual('Package cannot be blank');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
ALTER TABLE `vn`.`zoneGeo`
|
||||
RENAME TO `vn`.`zoneIncluded` ;
|
||||
|
||||
ALTER TABLE `vn`.`zoneNest`
|
||||
RENAME TO `vn`.`zoneGeo` ;
|
||||
|
||||
ALTER TABLE `vn`.`zone`
|
||||
CHANGE COLUMN `agencyFk` `agencyModeFk` INT(11) NOT NULL ;
|
|
@ -11,7 +11,7 @@
|
|||
"Is invalid": "Is invalid",
|
||||
"Quantity cannot be zero": "La cantidad no puede ser cero",
|
||||
"Enter an integer different to zero": "Introduce un entero distinto de cero",
|
||||
"The package cannot be blank": "El embalaje no puede estar en blanco",
|
||||
"Package cannot be blank": "El embalaje no puede estar en blanco",
|
||||
"The company name must be unique": "La razón social debe ser única",
|
||||
"Invalid email": "Correo electrónico inválido",
|
||||
"The IBAN does not have the correct format": "El IBAN no tiene el formato correcto",
|
||||
|
@ -48,5 +48,7 @@
|
|||
"The tag can't be repeated": "El tag no puede repetirse",
|
||||
"The observation type can't be repeated": "El tipo de observación no puede repetirse",
|
||||
"A claim with that sale already exists": "Ya existe una reclamación para esta línea",
|
||||
"You don't have enough privileges to change that field": "You don't have enough privileges to change that field"
|
||||
"You don't have enough privileges to change that field": "You don't have enough privileges to change that field",
|
||||
"Warehouse cannot be blank": "El almacén no puede quedar en blanco",
|
||||
"Agency cannot be blank": "La agencia no puede quedar en blanco"
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "ZoneCalendar",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "ZoneCalendar"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"zoneFk": {
|
||||
"id": true,
|
||||
"type": "Number"
|
||||
},
|
||||
"delivered": {
|
||||
"type": "Date"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"zone": {
|
||||
"type": "belongsTo",
|
||||
"model": "Zone",
|
||||
"foreignKey": "zoneFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "ZoneGeo",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "zoneGeo"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "Number"
|
||||
},
|
||||
"name": {
|
||||
"type": "String"
|
||||
},
|
||||
"lft": {
|
||||
"type": "Number"
|
||||
},
|
||||
"rgt": {
|
||||
"type": "Number"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "ZoneIncluded",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "zoneIncluded"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"zoneFk": {
|
||||
"id": true,
|
||||
"type": "Number"
|
||||
},
|
||||
"isIncluded": {
|
||||
"type": "Boolean"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"zone": {
|
||||
"type": "belongsTo",
|
||||
"model": "Zone",
|
||||
"foreignKey": "zoneFk"
|
||||
},
|
||||
"geo": {
|
||||
"type": "belongsTo",
|
||||
"model": "ZoneGeo",
|
||||
"foreignKey": "geoFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
module.exports = Self => {
|
||||
Self.validatesPresenceOf('warehouseFk', {
|
||||
message: `Warehouse cannot be blank`
|
||||
});
|
||||
|
||||
Self.validatesPresenceOf('agencyModeFk', {
|
||||
message: `Agency cannot be blank`
|
||||
});
|
||||
};
|
|
@ -1,23 +1,47 @@
|
|||
{
|
||||
"name": "Zone",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "zone"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "Number",
|
||||
"forceId": false
|
||||
},
|
||||
"name": {
|
||||
"type": "String"
|
||||
},
|
||||
"printingOrder":{
|
||||
"type": "Number"
|
||||
}
|
||||
"name": "Zone",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "zone"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "Number"
|
||||
},
|
||||
"name": {
|
||||
"type": "String",
|
||||
"required": true
|
||||
},
|
||||
"hour": {
|
||||
"type": "Date",
|
||||
"required": true
|
||||
},
|
||||
"travelingDays": {
|
||||
"type": "Number",
|
||||
"required": true
|
||||
},
|
||||
"price": {
|
||||
"type": "Number",
|
||||
"required": true
|
||||
},
|
||||
"bonus": {
|
||||
"type": "Number",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"warehouse": {
|
||||
"type": "belongsTo",
|
||||
"model": "Warehouse",
|
||||
"foreignKey": "warehouseFk"
|
||||
},
|
||||
"agencyMode": {
|
||||
"type": "belongsTo",
|
||||
"model": "AgencyMode",
|
||||
"foreignKey": "agencyModeFk"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7,5 +7,14 @@
|
|||
},
|
||||
"Zone": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"ZoneGeo": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"ZoneCalendar": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"ZoneIncluded": {
|
||||
"dataSource": "vn"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html ng-app="salix">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title vn-title translate>Salix</title>
|
||||
<title vn-title translate></title>
|
||||
<script src="/acl"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -9,5 +9,5 @@ module.exports = function(Self) {
|
|||
return !isNaN(quantity) && quantity != 0;
|
||||
}
|
||||
|
||||
Self.validatesPresenceOf('packagingFk', {message: 'The package cannot be blank'});
|
||||
Self.validatesPresenceOf('packagingFk', {message: 'Package cannot be blank'});
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue