added zone index & zone create
This commit is contained in:
parent
fd08bb96dd
commit
d5ca385ccd
|
@ -49,6 +49,9 @@
|
||||||
</vn-td>
|
</vn-td>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-tbody>
|
</vn-tbody>
|
||||||
|
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||||
|
No results
|
||||||
|
</vn-empty-rows>
|
||||||
</vn-table>
|
</vn-table>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-pagination
|
<vn-pagination
|
||||||
|
|
|
@ -41,3 +41,4 @@ import './th';
|
||||||
import './input-range';
|
import './input-range';
|
||||||
import './chip';
|
import './chip';
|
||||||
import './input-number';
|
import './input-number';
|
||||||
|
import './input-time';
|
||||||
|
|
|
@ -45,7 +45,7 @@ export default class InputNumber extends Textfield {
|
||||||
}
|
}
|
||||||
|
|
||||||
get step() {
|
get step() {
|
||||||
return parseInt(this.input.step);
|
return parseFloat(this.input.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
set step(value) {
|
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 {
|
.infix {
|
||||||
position: relative;
|
|
||||||
display: block;
|
display: block;
|
||||||
flex: auto;
|
flex: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -49,6 +48,7 @@ vn-textfield {
|
||||||
label {
|
label {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
padding: 4px 0!important;
|
padding: 4px 0!important;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
color: $secondary-font-color;
|
color: $secondary-font-color;
|
||||||
|
|
|
@ -7,5 +7,6 @@ module.exports.watcher = {
|
||||||
check: () => {},
|
check: () => {},
|
||||||
notifySaved: () => {},
|
notifySaved: () => {},
|
||||||
setDirty: () => {},
|
setDirty: () => {},
|
||||||
setPristine: () => {}
|
setPristine: () => {},
|
||||||
|
updateOriginalData: () => {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,3 +6,4 @@ salix: []
|
||||||
ticket: [item, client]
|
ticket: [item, client]
|
||||||
order: [item, ticket]
|
order: [item, ticket]
|
||||||
claim: [item, client]
|
claim: [item, client]
|
||||||
|
route: []
|
||||||
|
|
|
@ -4,19 +4,57 @@
|
||||||
"icon" : "local_shipping",
|
"icon" : "local_shipping",
|
||||||
"validations" : true,
|
"validations" : true,
|
||||||
"routes": [
|
"routes": [
|
||||||
{
|
/* {
|
||||||
"url": "/routes",
|
"url": "/route",
|
||||||
"state": "routes",
|
"state": "route",
|
||||||
"abstract": true,
|
"abstract": true,
|
||||||
"component": "ui-view",
|
"component": "ui-view",
|
||||||
"description": "Routes"
|
"description": "Routes"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url": "/index?q",
|
"url": "/index?q",
|
||||||
"state": "routes.index",
|
"state": "route.index",
|
||||||
"component": "vn-route-index",
|
"component": "vn-route-index",
|
||||||
"description": "List",
|
"description": "List",
|
||||||
"acl": ["developer"]
|
"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';
|
export * from './module';
|
||||||
|
|
||||||
// import components
|
// 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
|
Name: Nombre
|
||||||
Logistic data: Datos logísticos
|
|
||||||
Assigned tickets: Tickets asignados
|
|
||||||
Routes: Rutas
|
|
||||||
Route: Ruta
|
|
||||||
Date: Fecha
|
|
||||||
Agency: Agencia
|
Agency: Agencia
|
||||||
Driver: Conductor
|
Warehouse: Almacén
|
||||||
Vehicle: Vehículo
|
Hour: Hora (ETD)
|
||||||
Start Hour: Hora Inicio
|
Price: Precio
|
||||||
End Hour: Hora Fin
|
Create: Crear
|
||||||
Start Km: Km Inicio
|
|
||||||
End Km: Km Fin
|
Zones: Zonas
|
||||||
Packages: Bultos
|
List: Listado
|
||||||
Route document: Documento de Ruta
|
New zone: Nueva zona
|
||||||
|
Basic data: Datos básicos
|
|
@ -1,5 +1,5 @@
|
||||||
import {ng} from 'vendor';
|
import {ng} from 'vendor';
|
||||||
import 'core';
|
import 'core';
|
||||||
|
|
||||||
const ngModule = ng.module('route', []);
|
const ngModule = ng.module('route', ['vnCore']);
|
||||||
export default ngModule;
|
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>
|
</vn-td>
|
||||||
</a>
|
</a>
|
||||||
</vn-tbody>
|
</vn-tbody>
|
||||||
|
<vn-empty-rows ng-if="model.data.length === 0" translate>
|
||||||
|
No results
|
||||||
|
</vn-empty-rows>
|
||||||
</vn-table>
|
</vn-table>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-pagination
|
<vn-pagination
|
||||||
|
|
|
@ -87,7 +87,7 @@ describe('Ticket Create packages path', () => {
|
||||||
.click(selectors.ticketPackages.savePackagesButton)
|
.click(selectors.ticketPackages.savePackagesButton)
|
||||||
.waitForLastSnackbar()
|
.waitForLastSnackbar()
|
||||||
.then(result => {
|
.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",
|
"Is invalid": "Is invalid",
|
||||||
"Quantity cannot be zero": "La cantidad no puede ser cero",
|
"Quantity cannot be zero": "La cantidad no puede ser cero",
|
||||||
"Enter an integer different to zero": "Introduce un entero distinto de 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",
|
"The company name must be unique": "La razón social debe ser única",
|
||||||
"Invalid email": "Correo electrónico inválido",
|
"Invalid email": "Correo electrónico inválido",
|
||||||
"The IBAN does not have the correct format": "El IBAN no tiene el formato correcto",
|
"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 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",
|
"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",
|
"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",
|
"name": "Zone",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "zone"
|
"table": "zone"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"id": true,
|
"id": true,
|
||||||
"type": "Number",
|
"type": "Number"
|
||||||
"forceId": false
|
},
|
||||||
},
|
"name": {
|
||||||
"name": {
|
"type": "String",
|
||||||
"type": "String"
|
"required": true
|
||||||
},
|
},
|
||||||
"printingOrder":{
|
"hour": {
|
||||||
"type": "Number"
|
"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": {
|
"Zone": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"ZoneGeo": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"ZoneCalendar": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"ZoneIncluded": {
|
||||||
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<html ng-app="salix">
|
<html ng-app="salix">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title vn-title translate>Salix</title>
|
<title vn-title translate></title>
|
||||||
<script src="/acl"></script>
|
<script src="/acl"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -9,5 +9,5 @@ module.exports = function(Self) {
|
||||||
return !isNaN(quantity) && quantity != 0;
|
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