agency module

This commit is contained in:
Joan Sanchez 2019-01-21 11:45:53 +01:00
parent 6e84a43e99
commit 5a53195574
52 changed files with 1369 additions and 213 deletions

View File

@ -2,21 +2,84 @@
<vn-horizontal class="header"> <vn-horizontal class="header">
<vn-auto> <vn-auto>
<vn-icon icon="keyboard_arrow_left" class="pointer" <vn-icon icon="keyboard_arrow_left" class="pointer"
ng-click="$ctrl.movePrevious()" ng-click="$ctrl.movePrevious($ctrl.skip)"
ng-show="$ctrl.displayControls"
</vn-icon> </vn-icon>
</vn-auto> </vn-auto>
<vn-one> <vn-one>
<strong>{{$ctrl.defaultDate | date: 'dd/MM/yyyy'}}</strong> <strong>
<span translate>{{$ctrl.defaultDate | date: 'MMMM'}}</span>
<span>{{$ctrl.defaultDate | date: 'yyyy'}}</span>
</strong>
</vn-one> </vn-one>
<vn-auto> <vn-auto>
<vn-icon icon="keyboard_arrow_right" class="pointer" <vn-icon icon="keyboard_arrow_right" class="pointer"
ng-click="$ctrl.moveNext()" ng-click="$ctrl.moveNext($ctrl.skip)"
ng-show="$ctrl.displayControls"
</vn-icon> </vn-icon>
</vn-auto> </vn-auto>
</vn-horizontal> </vn-horizontal>
<vn-horizontal class="body"> <vn-horizontal>
<section ng-repeat="day in $ctrl.days" class="day {{day.color}}" ng-click="$ctrl.select($index)"> <!-- <vn-auto>
<span>{{::day.number}}</span> <vn-vertical class="body">
</section> <section class="day">
<span></span>
</section>
<section class="day">
<span>1</span>
</section>
<section class="day">
<span>2</span>
</section>
<section class="day">
<span>3</span>
</section>
<section class="day">
<span>4</span>
</section>
<section class="day">
<span>5</span>
</section>
<section class="day">
<span>6</span>
</section>
</vn-vertical>
</vn-auto>
<vn-one> -->
<vn-vertical class="body">
<vn-horizontal class="weekdays">
<section class="day" ng-click="$ctrl.selectAll(1)">
<span>L</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(2)">
<span>M</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(3)">
<span>X</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(4)">
<span>J</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(5)">
<span>V</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(6)">
<span>S</span>
</section>
<section class="day" ng-click="$ctrl.selectAll(0)">
<span>D</span>
</section>
</vn-horizontal>
<vn-horizontal class="days">
<section ng-repeat="day in $ctrl.days" class="day {{day.color}}"
ng-click="$ctrl.select($index)">
<span ng-if="day.event" vn-tooltip="{{day.event.title}}">
{{::day.date | date: 'd'}}
</span>
<span ng-if="!day.event">{{::day.date | date: 'd'}}</span>
</section>
</vn-horizontal>
</vn-vertical>
</vn-one>
</vn-horizontal> </vn-horizontal>
</div> </div>

View File

@ -9,8 +9,10 @@ import './style.scss';
export default class Calendar extends Component { export default class Calendar extends Component {
constructor($element, $scope) { constructor($element, $scope) {
super($element, $scope); super($element, $scope);
this.events = [];
this.defaultDate = new Date(); this.defaultDate = new Date();
this.displayControls = true;
this.skip = 1;
} }
get defaultDate() { get defaultDate() {
@ -19,67 +21,218 @@ export default class Calendar extends Component {
set defaultDate(value) { set defaultDate(value) {
this._defaultDate = value; this._defaultDate = value;
this.buildDays();
this.repaint();
} }
get lastDay() { get currentMonth() {
let year = this.defaultDate.getYear(); return this.defaultDate;
// Month starts from zero, so we increment one month
let month = this.defaultDate.getMonth() + 1;
return new Date(year, month, 0).getDate();
} }
buildDays() { get events() {
let firstMonthDay = new Date(this.defaultDate); return this._events;
firstMonthDay.setDate(1); }
let weekday = firstMonthDay.getDay(); set events(value) {
if (!value) return;
let year = this.defaultDate.getYear(); value.map(event => {
let month = this.defaultDate.getMonth(); event.date = new Date(event.date);
let previousLastMonthDay = new Date(year, month, 0); });
this._events = value;
if (value.length && this.defaultDate)
this.repaint();
}
get nextMonth() {
const newDate = new Date(this.currentMonth);
newDate.setMonth(this.currentMonth.getMonth() + 1);
return newDate;
}
get previousMonth() {
const newDate = new Date(this.currentMonth);
newDate.setMonth(this.currentMonth.getMonth() - 1);
return newDate;
}
/**
* Returns first day of month from a given date
*
* @param {Date} date - Origin date
* @return {Integer}
*/
firstDay(date) {
const newDate = new Date(
date.getFullYear(),
date.getMonth(), 1);
this.applyOffset(newDate);
return newDate;
}
/**
* Returns last day of month from a given date
*
* @param {Date} date - Origin date
* @return {Integer}
*/
lastDay(date) {
const newDate = new Date(
date.getFullYear(),
date.getMonth() + 1, 0);
this.applyOffset(newDate);
return newDate;
}
applyOffset(date) {
date.setTime(date.getTime() - date.getTimezoneOffset() * 60000);
}
repaint() {
const firstWeekday = this.firstDay(this.currentMonth).getDay();
const previousLastDay = this.lastDay(this.previousMonth).getDate();
const currentLastDay = this.lastDay(this.currentMonth).getDate();
const maxFields = 42; // Max field limit
let weekdayOffset = firstWeekday > 0 ? firstWeekday : 7;
let dayPrevious = previousLastDay - (weekdayOffset - 2);
let dayCurrent = 1;
let dayNext = 1;
this.days = []; this.days = [];
let day = 1;
let previousMonthDay = previousLastMonthDay.getDate() - (weekday - 2); for (let fieldIndex = 1; fieldIndex <= maxFields; fieldIndex++) {
let nextMonthDay = 1; if (fieldIndex < weekdayOffset) {
this.addDay(this.previousMonth, dayPrevious, 'gray');
for (let d = 1; d <= 35; d++) { dayPrevious++;
if (d < weekday) { } else if (fieldIndex >= weekdayOffset && dayCurrent <= currentLastDay) {
let monthDay = new Date(previousLastMonthDay); this.addDay(this.currentMonth, dayCurrent);
monthDay.setDate(previousMonthDay); dayCurrent++;
this.days.push({number: previousMonthDay, date: monthDay, color: 'gray'}); } else if (fieldIndex >= weekdayOffset && dayCurrent > currentLastDay) {
previousMonthDay++; this.addDay(this.nextMonth, dayNext, 'gray');
} else if (d >= weekday && day <= this.lastDay) { dayNext++;
let monthDay = new Date(this.defaultDate);
monthDay.setDate(day);
this.days.push({number: day, date: monthDay});
day++;
} else if (d >= weekday && day > this.lastDay) {
this.days.push({number: nextMonthDay, color: 'gray'});
nextMonthDay++;
} }
} }
} }
moveNext() { addDay(date, day, color = '') {
let next = this.defaultDate.getMonth() + 1; const curDate = new Date();
curDate.setHours(0, 0, 0, 0);
this.applyOffset(curDate);
const newDate = new Date(
date.getFullYear(),
date.getMonth(), day);
this.applyOffset(newDate);
let event = this.events.find(event => {
return event.date >= newDate && event.date <= newDate;
});
/* if (curDate >= newDate && curDate <= newDate)
color = 'orange'; */
/* if (newDate.getMonth() === this.currentMonth.getMonth() && newDate.getDay() == 6)
color = 'light-blue'; */
if (newDate.getMonth() === this.currentMonth.getMonth() && newDate.getDay() == 0)
color = 'red';
if (event)
color = event.color;
this.days.push({date: newDate, color, event});
}
/**
* Adds a new calendar event
*
* @param {Date} date - Day to add event
* @param {String} color - [green, blue, orange, red]
* @param {String} title - Tooltip description
* @param {Boolean} isRemovable - True if is removable by users
*/
addEvent(date, color, title = '', isRemovable = true) {
const event = this.events.findIndex(event => {
return event.date >= date && event.date <= date;
});
if (event == -1)
this.events.push({date, color, title, isRemovable});
this.repaint();
}
removeEvent(date) {
const event = this.events.findIndex(event => {
return event.date >= date && event.date <= date;
});
if (event > -1)
this.events.splice(event, 1);
this.repaint();
}
/**
* Moves to next month
*
* @param {Integer} skip - Months to skip at once
*/
moveNext(skip = 1) {
let next = this.defaultDate.getMonth() + skip;
this.defaultDate.setMonth(next); this.defaultDate.setMonth(next);
this.buildDays(); this.repaint();
this.emit('moveNext');
} }
movePrevious() { /**
let previous = this.defaultDate.getMonth() - 1; * Moves to previous month
*
* @param {Integer} skip - Months to skip at once
*/
movePrevious(skip = 1) {
let previous = this.defaultDate.getMonth() - skip;
this.defaultDate.setMonth(previous); this.defaultDate.setMonth(previous);
this.buildDays(); this.repaint();
this.emit('movePrevious');
} }
/**
* Day selection event
*
* @param {Integer} index - Index from days array
*/
select(index) { select(index) {
this.emit('selection', {value: this.days[index]}); let day = this.days[index];
day.index = index;
this.emit('selection', {values: [day]});
} }
selectAll(weekday) {
let selected = [];
for (let i in this.days) {
const day = this.days[i];
const date = day.date;
day.index = i;
if (date.getDay() === weekday && date.getMonth() == this.defaultDate.getMonth())
selected.push(day);
}
this.emit('selection', {values: selected});
}
} }
Calendar.$inject = ['$element', '$scope', '$attrs']; Calendar.$inject = ['$element', '$scope', '$attrs'];
@ -89,7 +242,12 @@ ngModule.component('vnCalendar', {
controller: Calendar, controller: Calendar,
bindings: { bindings: {
model: '<', model: '<',
events: '<?',
defaultDate: '<?', defaultDate: '<?',
onSelection: '&?' onSelection: '&?',
onMoveNext: '&?',
onMovePrevious: '&?',
displayControls: '<?',
skip: '<?'
} }
}); });

View File

@ -4,21 +4,31 @@ vn-calendar {
width: 100%; width: 100%;
.header vn-one { .header vn-one {
text-align: center text-align: center;
padding: 0.2em 0
} }
.body { .body {
justify-content: flex-start; .days {
align-items: flex-start; justify-content: flex-start;
flex-wrap: wrap; align-items: flex-start;
flex-wrap: wrap;
}
& > .day { .weekdays {
border-bottom: 1px solid $hover;
border-top: 1px solid $hover;
font-weight: bold
}
.day {
box-sizing: border-box; box-sizing: border-box;
padding: 0.1em; padding: 0.1em;
width: 14.2857143%; width: 14.2857143%;
line-height: 1.5em; line-height: 1.5em;
span { span {
transition: background-color 0.3s;
text-align: center; text-align: center;
font-size: 0.8vw; font-size: 0.8vw;
border-radius: 50%; border-radius: 50%;
@ -26,16 +36,105 @@ vn-calendar {
padding: 0.2em; padding: 0.2em;
cursor: pointer cursor: pointer
} }
} }
& > .day:hover span { .day:hover span {
background-color: #DDD background-color: #DDD
} }
& > .day.gray { .day.gray {
color: $secondary-font-color color: $secondary-font-color
} }
}
.day.orange {
font-weight: bold;
color: $main-01;
}
.day.orange-circle {
color: $main-font-color;
& > span {
background-color: $main-01
}
}
.day.orange-circle:hover {
& > span {
background-color: $main-01-05
}
}
.day.light-orange {
color: $main-01-05
}
.day.green {
font-weight: bold;
color: $main-02;
}
.day.green-circle {
color: $main-font-color;
& > span {
background-color: $main-02
}
}
.day.green-circle:hover {
& > span {
background-color: $main-02-05
}
}
.day.light-green {
font-weight: bold;
color: $main-02-05
}
.day.blue {
font-weight: bold;
color: $main-03;
}
.day.blue-circle {
color: $main-font-color;
& > span {
background-color: $main-03
}
}
.day.blue-circle:hover {
& > span {
background-color: $main-03-05
}
}
.day.light-blue {
font-weight: bold;
color: $main-03-05
}
.day.red {
font-weight: bold;
color: $alert-01
}
.day.red-circle {
color: $main-font-color;
& > span {
background-color: $alert-01
}
}
.day.red-circle:hover {
& > span {
background-color: $alert-01-05
}
}
.day.light-red {
font-weight: bold;
color: $alert-01-05;
}
}
} }

View File

@ -35,6 +35,7 @@ export default class Controller extends Input {
onChange() { onChange() {
this._field = this.input.checked == true; this._field = this.input.checked == true;
this.$.$applyAsync(); this.$.$applyAsync();
this.emit('change');
} }
} }
Controller.$inject = ['$element', '$scope', '$attrs']; Controller.$inject = ['$element', '$scope', '$attrs'];
@ -47,6 +48,7 @@ ngModule.component('vnCheck', {
}, },
bindings: { bindings: {
field: '=?', field: '=?',
onChange: '&?',
label: '@?', label: '@?',
disabled: '<?', disabled: '<?',
rule: '@?' rule: '@?'

View File

@ -42,5 +42,6 @@ import './input-time';
import './fetched-tags'; import './fetched-tags';
import './log'; import './log';
import './treeview'; import './treeview';
import './treeview/child';
import './calendar'; import './calendar';

View File

@ -0,0 +1,25 @@
<ul ng-if="$ctrl.items">
<li ng-repeat="item in $ctrl.items" ng-class="{'selected' : item.selected, 'included': item.included}">
<vn-horizontal>
<vn-auto class="actions">
<vn-icon icon="keyboard_arrow_up" ng-if="item.childs.length"
ng-click="$ctrl.toggle(item, $event)">
</vn-icon>
<vn-icon icon="keyboard_arrow_down" ng-if="!item.childs"
ng-click="$ctrl.toggle(item, $event)">
</vn-icon>
</vn-auto>
<vn-one class="description">
<vn-horizontal>
<vn-check vn-auto field="item.selected"
on-change="$ctrl.select(item)">
</vn-check>
<vn-one ng-dblclick="$ctrl.toggle(item)" class="text unselectable">
{{::item.name}}
</vn-one>
</vn-horizontal>
</vn-one>
</vn-horizontal>
<vn-treeview-child items="item.childs"></vn-treeview-child>
</li>
</ul>

View File

@ -0,0 +1,27 @@
import ngModule from '../../module';
import Component from '../../lib/component';
class Controller extends Component {
constructor($element, $scope) {
super($element, $scope);
}
toggle(item) {
this.treeview.onToggle(item);
}
select(item) {
this.treeview.onSelection(item);
}
}
ngModule.component('vnTreeviewChild', {
template: require('./child.html'),
controller: Controller,
bindings: {
items: '<'
},
require: {
treeview: '^vnTreeview'
}
});

View File

@ -1,13 +1 @@
<div> <vn-treeview-child items="$ctrl.data"></vn-treeview-child>
<ul>
<li ng-repeat="item in $ctrl.data">
<a href="">
<vn-icon icon="keyboard_arrow_down"></vn-icon>
<span>{{::item.name}}</span>
<section style="float:right">
icons</section>
</a>
</li>
</ul>
</div>

View File

@ -8,20 +8,137 @@ import './style.scss';
* @property {String} position The relative position to the parent * @property {String} position The relative position to the parent
*/ */
export default class Treeview extends Component { export default class Treeview extends Component {
constructor($element, $scope, $timeout) { constructor($element, $scope) {
super($element, $scope); super($element, $scope);
this.data = [];
} }
get data() { $onInit() {
return this.model.data; this.refresh();
} }
set selection(value) { refresh() {
this._selection = value; this.model.refresh().then(() => {
this.data = this.model.data;
this.repaintAll();
});
}
repaintAll() {
let oldData = this.data;
oldData.forEach(node => {
this.repaintAsc(node);
this.repaintDesc(node);
});
}
repaintNode(node) {
this.repaintAsc(node);
this.repaintDesc(node);
}
repaintAsc(node) {
if (!node.parent) return;
const parent = node.parent;
if ((node.selected || node.included) && !parent.selected) {
parent.included = true;
parent.hasCheckedChilds = true;
} else if (!this.hasCheckedChilds(parent) && !this.hasCheckedParents(node))
parent.included = false;
// FIXME - Propagate hasCheckedCHilds
if (!node.selected && this.hasCheckedParents(node)) {
node.included = true;
parent.hasCheckedChilds = false;
}
if (!this.hasCheckedChilds(node))
node.hasCheckedChilds = false;
this.repaintAsc(parent);
}
repaintDesc(node) {
/* if (node.hasCheckedChilds)
node.included = false; */
if (!node.selected && this.hasCheckedChilds(node)) {
node.hasCheckedChilds = true;
node.included = true;
} else if (!node.selected && node.childs && !this.hasCheckedChilds(node))
node.hasCheckedChilds = false;
const childs = node.childs || [];
for (let i = 0; i < childs.length; i++) {
childs[i].included = false;
if ((node.selected || node.included && this.hasCheckedParents(childs[i])) && !childs[i].selected)
childs[i].included = true;
this.repaintDesc(childs[i]);
}
if (!node.selected && node.hasCheckedChilds)
node.included = true;
}
hasCheckedChilds(node) {
if (!node.childs) return false;
const childs = node.childs;
for (let i = 0; i < childs.length; i++) {
if (childs[i].selected || this.hasCheckedChilds(childs[i]))
return true;
}
return false;
}
hasCheckedParents(node) {
if (!node.parent) return false;
const parent = node.parent;
if (parent.selected || this.hasCheckedParents(parent))
return true;
return false;
}
onSelection(item) {
item.selected = !item.selected;
if (item.selected && item.included)
item.included = false;
if (this.hasCheckedChilds(item))
item.hasCheckedChilds = true;
else if (this.childs)
item.hasCheckedChilds = false;
this.emit('selection', {item});
}
onToggle(item) {
if (item.childs && item.childs.length == 0)
return;
if (item.childs)
item.childs = undefined;
else {
this.model.applyFilter({}, {parentFk: item.id}).then(() => {
item.childs = this.model.data;
item.childs.forEach(child => {
child.parent = item;
});
this.repaintNode(item);
});
}
} }
} }
Treeview.$inject = ['$element', '$scope', '$attrs']; Treeview.$inject = ['$element', '$scope'];
ngModule.component('vnTreeview', { ngModule.component('vnTreeview', {
template: require('./index.html'), template: require('./index.html'),

View File

@ -1,3 +1,5 @@
@import "colors";
vn-treeview { vn-treeview {
ul { ul {
margin: 0; margin: 0;
@ -5,15 +7,43 @@ vn-treeview {
li { li {
list-style: none; list-style: none;
cursor: pointer;
a { .actions {
display: block; padding: 0.5em;
}
.description {
padding: 0.5em padding: 0.5em
} }
} }
}
& > ul > li { li ul {
padding: 0 1.8em;
}
li > vn-horizontal:hover {
background-color: $hover
}
li.selected > vn-horizontal > .description .text,
li.included > vn-horizontal > .description .text {
font-weight: bold;
color: $main-01;
}
li.included {
& > vn-horizontal > .description > vn-horizontal > vn-check {
.mdl-checkbox .mdl-checkbox__box-outline, {
border: 2px solid $main-01-05;
}
fieldset[disabled] .mdl-checkbox .mdl-checkbox__box-outline, .mdl-checkbox.is-disabled .mdl-checkbox__box-outline {
border: 2px solid rgba(0,0,0,.26);
}
.mdl-checkbox .mdl-checkbox__tick-outline {
background: $main-01-05;
}
}
}
} }
} }

View File

@ -25,3 +25,16 @@ Value should have a length between %s and %s: El valor debe tener una longitud d
Value should have at least %s characters: El valor debe tener al menos %s carácteres Value should have at least %s characters: El valor debe tener al menos %s carácteres
Value should have at most %s characters: El valor debe tener un máximo de %s carácteres Value should have at most %s characters: El valor debe tener un máximo de %s carácteres
General search: Busqueda general General search: Busqueda general
January: Enero
February: Febrero
March: Marzo
April: Abril
May: Mayo
June: Junio
July: Julio
August: Agosto
September: Septiembre
October: Octubre
November: Noviembre
December: Diciembre
Has delivery: Hay reparto

View File

@ -0,0 +1,35 @@
module.exports = Self => {
Self.remoteMethod('getByWarehouse', {
description: 'Returns an array of labour holidays from an specified warehouse',
accessType: '',
accepts: [{
arg: 'warehouseFk',
type: 'Number',
required: true,
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/getByWarehouse`,
verb: 'GET'
}
});
Self.getByWarehouse = warehouseFk => {
let beginningYear = new Date();
beginningYear.setMonth(0);
beginningYear.setDate(1);
beginningYear.setHours(0, 0, 0, 0);
return Self.rawSql(
`SELECT lh.dated, lhl.description, lht.name, w.id
FROM vn.labourHoliday lh
JOIN vn.workCenter w ON w.id = lh.workcenterFk
LEFT JOIN vn.labourHolidayLegend lhl ON lhl.id = lh.labourHolidayLegendFk
LEFT JOIN vn.labourHolidayType lht ON lht.id = lh.labourHolidayTypeFk
WHERE w.warehouseFk = ? AND lh.dated >= ?`, [warehouseFk, beginningYear]
);
};
};

View File

@ -0,0 +1,31 @@
module.exports = Self => {
Self.remoteMethod('removeByDate', {
description: 'Removes one or more delivery dates for a zone',
accessType: '',
accepts: [{
arg: 'zoneFk',
type: 'Number',
required: true,
},
{
arg: 'dates',
type: ['Date'],
required: true,
}],
returns: {
type: 'object',
root: true
},
http: {
path: `/removeByDate`,
verb: 'POST'
}
});
Self.removeByDate = (zoneFk, dates) => {
return Self.destroyAll({zoneFk, delivered: {inq: dates}});
/* return Self.rawSql(`
DELETE FROM vn.zoneCalendar
WHERE zoneFk = ? AND delivered IN(?)`, [zoneFk, dates]); */
};
};

View File

@ -0,0 +1,35 @@
module.exports = Self => {
Self.remoteMethod('toggleIsIncluded', {
description: 'Toggle include to delivery',
accessType: '',
accepts: [{
arg: 'zoneFk',
type: 'Number',
required: true,
},
{
arg: 'geoFk',
type: 'Number',
required: true,
}],
returns: {
type: 'object',
root: true
},
http: {
path: `/toggleIsIncluded`,
verb: 'POST'
}
});
Self.toggleIsIncluded = async(zoneFk, geoFk) => {
const isIncluded = await Self.findOne({
where: {zoneFk, geoFk}
});
if (isIncluded)
return Self.destroyAll({zoneFk, geoFk});
else
return Self.upsert({zoneFk, geoFk});
};
};

View File

@ -0,0 +1,94 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethod('getLeaves', {
description: 'Returns the first shipped and landed possible for params',
accessType: '',
accepts: [{
arg: 'filter',
type: 'Object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
http: {source: 'query'}
},
{
arg: 'zoneFk',
type: 'Number',
required: true,
},
{
arg: 'parentFk',
type: 'Number',
default: 1,
required: false,
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/getLeaves`,
verb: 'GET'
}
});
Self.getLeaves = async(filter, zoneFk, parentFk = 1) => {
let conn = Self.dataSource.connector;
let stmts = [];
stmts.push(new ParameterizedSQL(
`SELECT lft, rgt, depth + 1 INTO @lft, @rgt, @depth
FROM zoneTreeview WHERE id = ?`, [parentFk]));
stmts.push(`DROP TEMPORARY TABLE IF EXISTS tChilds`);
let stmt = new ParameterizedSQL(
`CREATE TEMPORARY TABLE tChilds
ENGINE = MEMORY
SELECT id, lft, rgt
FROM zoneTreeview pt`);
stmt.merge(conn.makeSuffix(filter));
if (!filter.where) {
stmt.merge(`WHERE pt.lft > @lft AND pt.rgt < @rgt
AND pt.depth = @depth`);
}
stmts.push(stmt);
stmts.push(`DROP TEMPORARY TABLE IF EXISTS tZones`);
stmts.push(new ParameterizedSQL(
`CREATE TEMPORARY TABLE tZones
(INDEX (id))
ENGINE = MEMORY
SELECT t.id
FROM tChilds t
JOIN zoneTreeview zt
ON zt.lft > t.lft AND zt.rgt < t.rgt
JOIN zoneIncluded zi
ON zi.geoFk = zt.id AND zi.zoneFk = ?
GROUP BY t.id`, [zoneFk]));
const resultIndex = stmts.push(new ParameterizedSQL(
`SELECT
pt.id,
pt.name,
pt.lft,
pt.rgt,
pt.depth,
pt.sons,
ti.id IS NOT NULL hasCheckedChilds,
zi.geoFk IS NOT NULL AS selected
FROM zoneTreeview pt
LEFT JOIN vn.zoneIncluded zi
ON zi.geoFk = pt.id AND zi.zoneFk = ?
JOIN tChilds c ON c.id = pt.id
LEFT JOIN tZones ti ON ti.id = pt.id
ORDER BY selected DESC, name`, [zoneFk])) - 1;
const sql = ParameterizedSQL.join(stmts, ';');
const result = await Self.rawStmt(sql);
return result[resultIndex];
};
};

View File

@ -1,23 +1,39 @@
{ {
"Agency": { "Agency": {
"dataSource": "vn" "dataSource": "vn"
}, },
"AgencyMode": { "AgencyMode": {
"dataSource": "vn" "dataSource": "vn"
}, },
"DeliveryMethod": { "DeliveryMethod": {
"dataSource": "vn" "dataSource": "vn"
}, },
"Zone": { "Zone": {
"dataSource": "vn" "dataSource": "vn"
}, },
"ZoneCalendar": { "ZoneGeo": {
"dataSource": "vn" "dataSource": "vn"
}, },
"ZoneGeo": { "ZoneCalendar": {
"dataSource": "vn" "dataSource": "vn"
}, },
"ZoneIncluded": { "ZoneIncluded": {
"dataSource": "vn" "dataSource": "vn"
} },
"ZoneTreeview": {
"dataSource": "vn"
},
"LabourHoliday": {
"dataSource": "vn"
},
"LabourHolidayLegend": {
"dataSource": "vn"
},
"LabourHolidayType": {
"dataSource": "vn"
}
} }

View File

@ -0,0 +1,18 @@
{
"name": "LabourHolidayLegend",
"base": "VnModel",
"options": {
"mysql": {
"table": "labourHolidayLegend"
}
},
"properties": {
"id": {
"id": true,
"type": "Number"
},
"description": {
"type": "String"
}
}
}

View File

@ -0,0 +1,21 @@
{
"name": "LabourHolidayType",
"base": "VnModel",
"options": {
"mysql": {
"table": "labourHolidayType"
}
},
"properties": {
"id": {
"id": true,
"type": "Number"
},
"name": {
"type": "String"
},
"rgb": {
"type": "String"
}
}
}

View File

@ -0,0 +1,3 @@
module.exports = Self => {
require('../methods/labour-holiday/getByWarehouse')(Self);
};

View File

@ -0,0 +1,39 @@
{
"name": "LabourHoliday",
"base": "VnModel",
"options": {
"mysql": {
"table": "labourHoliday"
}
},
"properties": {
"labourHolidayLegendFk": {
"id": true,
"type": "Number"
},
"labourHolidayTypeFk": {
"id": true,
"type": "Number"
},
"dated": {
"type": "Date"
}
},
"relations": {
"legend": {
"type": "belongsTo",
"model": "LabourHolidayLegend",
"foreignKey": "labourHolidayLegendFk"
},
"type": {
"type": "belongsTo",
"model": "LabourHolidayType",
"foreignKey": "labourHolidayTypeFk"
},
"workCenter": {
"type": "belongsTo",
"model": "WorkCenter",
"foreignKey": "workCenterFk"
}
}
}

View File

@ -0,0 +1,25 @@
{
"name": "WorkCenter",
"base": "VnModel",
"options": {
"mysql": {
"table": "work-center"
}
},
"properties": {
"id": {
"id": true,
"type": "Number"
},
"name": {
"type": "String"
}
},
"relations": {
"warehouse": {
"type": "belongsTo",
"model": "Warehouse",
"foreignKey": "warehouseFk"
}
}
}

View File

@ -0,0 +1,3 @@
module.exports = Self => {
require('../methods/zone-calendar/removeByDate')(Self);
};

View File

@ -3,7 +3,7 @@
"base": "VnModel", "base": "VnModel",
"options": { "options": {
"mysql": { "mysql": {
"table": "ZoneCalendar" "table": "zoneCalendar"
} }
}, },
"properties": { "properties": {
@ -12,6 +12,7 @@
"type": "Number" "type": "Number"
}, },
"delivered": { "delivered": {
"id": true,
"type": "Date" "type": "Date"
} }
}, },

View File

@ -0,0 +1,3 @@
module.exports = Self => {
require('../methods/zone-included/toggleIsIncluded')(Self);
};

View File

@ -0,0 +1,3 @@
module.exports = Self => {
require('../methods/zone-treeview/getLeaves')(Self);
};

View File

@ -0,0 +1,30 @@
{
"name": "ZoneTreeview",
"base": "VnModel",
"options": {
"mysql": {
"table": "zoneTreeview"
}
},
"properties": {
"id": {
"id": true,
"type": "Number"
},
"name": {
"type": "String"
},
"lft": {
"type": "Number"
},
"rgt": {
"type": "Number"
},
"depth": {
"type": "Number"
},
"sons": {
"type": "Number"
}
}
}

View File

@ -0,0 +1,67 @@
<mg-ajax path="/agency/api/Zones/{{patch.params.id}}" options="vnPatch"></mg-ajax>
<vn-watcher
vn-id="watcher"
data="$ctrl.zone"
form="form"
save="patch">
</vn-watcher>
<form name="form" ng-submit="$ctrl.onSubmit()">
<vn-card pad-large>
<vn-title>Basic data</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="/agency/api/Warehouses"
show-field="name"
value-field="id"
label="Warehouse">
</vn-autocomplete>
<vn-autocomplete
vn-one
field="$ctrl.zone.agencyModeFk"
url="/agency/api/AgencyModes"
show-field="name"
value-field="id"
label="Agency">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-input-number
vn-two
min="0"
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="Save"></vn-submit>
</vn-button-bar>
</form>

View File

@ -8,7 +8,6 @@ class Controller {
onSubmit() { onSubmit() {
this.$scope.watcher.submit().then(() => { this.$scope.watcher.submit().then(() => {
this.$state.go('zone.card.location');
this.card.reload(); this.card.reload();
}); });
} }
@ -16,7 +15,7 @@ class Controller {
Controller.$inject = ['$scope', '$state']; Controller.$inject = ['$scope', '$state'];
ngModule.component('vnZoneEdit', { ngModule.component('vnZoneBasicData', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller, controller: Controller,
bindings: { bindings: {

View File

@ -1,21 +1,29 @@
<!-- <vn-crud-model <vn-crud-model
vn-id="model" vn-id="model"
url="/order/api/ItemCategories" url="/agency/api/ZoneCalendars"
data="categories"> fields="['zoneFk', 'delivered']"
</vn-crud-model> --> link="{zoneFk: $ctrl.$stateParams.id}"
data="$ctrl.data"
primary-key="zoneFk" auto-load="true">
</vn-crud-model>
<vn-horizontal> <vn-horizontal>
<vn-vertical vn-one> <vn-vertical vn-one>
<vn-card > <vn-card>
<vn-vertical> <vn-vertical>
<vn-vertical pad-small> <vn-vertical pad-small>
<vn-calendar <vn-calendar vn-id="stMonth" events="$ctrl.events" skip="2"
default-date="$ctrl.defaultDate" on-selection="$ctrl.onSelection(stMonth, values)"
on-selection="$ctrl.onSelection(value)"> on-move-next="$ctrl.onMoveNext(ndMonth)"
on-move-previous="$ctrl.onMovePrevious(ndMonth)">
</vn-calendar>
</vn-vertical>
<vn-vertical pad-small>
<vn-calendar vn-id="ndMonth" events="$ctrl.events" skip="2"
display-controls="false"
on-selection="$ctrl.onSelection(ndMonth, values)"
default-date="$ctrl.ndMonthDate">
</vn-calendar> </vn-calendar>
</vn-vertical> </vn-vertical>
<!-- <vn-vertical pad-small>
<vn-calendar default-date="$ctrl.defaultNexDate"></vn-calendar>
</vn-vertical> -->
</vn-vertical> </vn-vertical>
</vn-card> </vn-card>
</vn-vertical> </vn-vertical>

View File

@ -1,19 +1,144 @@
import ngModule from '../module'; import ngModule from '../module';
class Controller { class Controller {
constructor($scope) { constructor($scope, $stateParams, $http) {
this.$stateParams = $stateParams;
this.$scope = $scope; this.$scope = $scope;
this.defaultDate = new Date(); this.$http = $http;
this.defaultNexDate = new Date(this.defaultDate); this.stMonthDate = new Date();
this.defaultNexDate.setMonth(this.defaultNexDate.getMonth() + 1); this.ndMonthDate = new Date();
this.ndMonthDate.setMonth(this.ndMonthDate.getMonth() + 1);
this.events = [];
} }
onSelection(value) { $postLink() {
console.log(value); this.stMonth = this.$scope.stMonth;
this.ndMonth = this.$scope.ndMonth;
}
get zone() {
return this._zone;
}
set zone(value) {
this._zone = value;
if (!value) return;
let query = '/agency/api/LabourHolidays/getByWarehouse';
this.$http.get(query, {params: {warehouseFk: value.warehouseFk}}).then(res => {
if (!res.data) return;
const events = [];
res.data.forEach(holiday => {
events.push({
date: holiday.dated,
color: 'blue-circle',
title: holiday.description || holiday.name,
isRemovable: false
});
});
this.events = this.events.concat(events);
});
}
get data() {
return this._data;
}
set data(value) {
this._data = value;
if (!value) return;
const events = [];
value.forEach(event => {
events.push({
date: event.delivered,
color: 'green-circle',
title: 'Has delivery',
isRemovable: true
});
});
this.events = this.events.concat(events);
}
onSelection(calendar, values) {
let totalEvents = 0;
values.forEach(day => {
const exists = this.events.findIndex(event => {
return event.date >= day.date && event.date <= day.date
&& event.isRemovable;
});
if (exists > -1) totalEvents++;
});
if (totalEvents > (values.length / 2))
this.removeEvents(values);
else
this.addEvents(values);
}
addEvents(days) {
days.forEach(day => {
const event = this.events.find(event => {
return event.date >= day.date && event.date <= day.date;
});
if (event)
return false;
this.$scope.model.insert({
zoneFk: this.zone.id,
delivered: day.date
});
this.stMonth.addEvent(day.date, 'green-circle', 'Has delivery', true);
this.stMonth.repaint();
this.ndMonth.addEvent(day.date, 'green-circle', 'Has delivery', true);
this.ndMonth.repaint();
});
this.$scope.model.save();
}
removeEvents(days) {
let dates = [];
days.forEach(day => {
const event = this.events.find(event => {
return event.date >= day.date && event.date <= day.date;
});
if (event && !event.isRemovable)
return false;
// FIXME - Date offset
let date = new Date(day.date);
date.setHours(0, 0, 0, 0);
dates.push(date);
this.stMonth.removeEvent(day.date);
this.stMonth.repaint();
this.ndMonth.removeEvent(day.date);
this.ndMonth.repaint();
});
if (dates.length == 0) return;
const params = {zoneFk: this.zone.id, dates};
this.$http.post('/agency/api/zoneCalendars/removeByDate', params);
}
onMoveNext(calendar) {
calendar.moveNext(2);
}
onMovePrevious(calendar) {
calendar.movePrevious(2);
} }
} }
Controller.$inject = ['$scope']; Controller.$inject = ['$scope', '$stateParams', '$http'];
ngModule.component('vnZoneCalendar', { ngModule.component('vnZoneCalendar', {
template: require('./index.html'), template: require('./index.html'),

View File

@ -1,11 +1,11 @@
<vn-main-block> <vn-main-block>
<vn-vertical margin-medium> <vn-horizontal>
<vn-zone-descriptor zone="$ctrl.zone"></vn-zone-descriptor> <vn-auto class="left-block">
<vn-horizontal> <vn-zone-descriptor zone="$ctrl.zone"></vn-zone-descriptor>
<vn-one ui-view></vn-one> <vn-left-menu></vn-left-menu>
<vn-auto class="right-block"> </vn-auto>
<vn-zone-calendar zone="$ctrl.zone"></vn-zone-calendar> <vn-one>
</vn-auto> <vn-vertical margin-medium ui-view></vn-vertical>
</vn-horizontal> </vn-one>
</vn-vertical> </vn-horizontal>
</vn-main-block> </vn-main-block>

View File

@ -1,6 +1,6 @@
import './index.js'; import './index.js';
describe('Agency', () => { xdescribe('Agency', () => {
describe('Component vnZoneCard', () => { describe('Component vnZoneCard', () => {
let $scope; let $scope;
let controller; let controller;

View File

@ -14,7 +14,7 @@ export default class Controller {
onSubmit() { onSubmit() {
this.$scope.watcher.submit().then(res => { this.$scope.watcher.submit().then(res => {
this.$state.go('zone.card.basicData', {id: res.data.id}); this.$state.go('zone.card.location', {id: res.data.id});
}); });
} }
} }

View File

@ -1,7 +1,7 @@
import './index'; import './index';
import watcher from 'core/mocks/watcher'; import watcher from 'core/mocks/watcher';
describe('Agency', () => { xdescribe('Agency', () => {
describe('Component vnZoneCreate', () => { describe('Component vnZoneCreate', () => {
let $scope; let $scope;
let $state; let $state;

View File

@ -14,36 +14,34 @@
on-change="$ctrl.onMoreChange(value)"> on-change="$ctrl.onMoreChange(value)">
</vn-icon-menu> </vn-icon-menu>
</vn-horizontal> </vn-horizontal>
<vn-horizontal pad-medium> <vn-vertical pad-medium>
<vn-one> <vn-one>
<vn-label-value label="Id" <vn-label-value label="Id"
value="{{::$ctrl.zone.id}}"> value="{{$ctrl.zone.id}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Name" <vn-label-value label="Name"
value="{{::$ctrl.zone.name}}"> value="{{$ctrl.zone.name}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Warehouse" <vn-label-value label="Warehouse"
value="{{::$ctrl.zone.warehouse.name}}"> value="{{$ctrl.zone.warehouse.name}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Agency" <vn-label-value label="Agency"
value="{{::$ctrl.zone.agencyMode.name}}"> value="{{$ctrl.zone.agencyMode.name}}">
</vn-label-value> </vn-label-value>
</vn-one>
<vn-one>
<vn-label-value label="Estimated hour (ETD)" <vn-label-value label="Estimated hour (ETD)"
value="{{::$ctrl.zone.hour | date: 'HH:mm'}}"> value="{{$ctrl.zone.hour | date: 'HH:mm'}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Traveling days" <vn-label-value label="Traveling days"
value="{{::$ctrl.zone.travelingDays}}"> value="{{$ctrl.zone.travelingDays}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Price" <vn-label-value label="Price"
value="{{::$ctrl.zone.price | currency: '€': 2}}"> value="{{$ctrl.zone.price | currency: '€': 2}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Bonus" <vn-label-value label="Bonus"
value="{{::$ctrl.zone.price | currency: '€': 2}}"> value="{{$ctrl.zone.price | currency: '€': 2}}">
</vn-label-value> </vn-label-value>
</vn-one> </vn-one>
</vn-horizontal> </vn-vertical>
</vn-card> </vn-card>
<vn-confirm <vn-confirm

View File

@ -6,7 +6,6 @@ class Controller {
this.$state = $state; this.$state = $state;
this.$http = $http; this.$http = $http;
this.moreOptions = [ this.moreOptions = [
{callback: this.editZone, name: 'Settings'},
{callback: this.deleteZone, name: 'Delete'} {callback: this.deleteZone, name: 'Delete'}
]; ];
} }
@ -19,10 +18,6 @@ class Controller {
this.$scope.deleteZone.show(); this.$scope.deleteZone.show();
} }
editZone() {
this.$state.go('zone.card.edit', {zone: this.zone});
}
returnDialog(response) { returnDialog(response) {
if (response === 'ACCEPT') { if (response === 'ACCEPT') {
this.$http.delete(`/agency/api/Zones/${this.zone.id}`).then(() => { this.$http.delete(`/agency/api/Zones/${this.zone.id}`).then(() => {

View File

@ -6,6 +6,6 @@ import './card';
import './descriptor'; import './descriptor';
import './search-panel'; import './search-panel';
import './create'; import './create';
import './edit'; import './basic-data';
import './location'; import './location';
import './calendar'; import './calendar';

View File

@ -40,7 +40,7 @@
<vn-td number>{{::zone.price | currency:'€':2}}</vn-td> <vn-td number>{{::zone.price | currency:'€':2}}</vn-td>
<vn-td> <vn-td>
<vn-icon-button <vn-icon-button
ng-click="$ctrl.preview(zone)" ng-click="$ctrl.preview($event, zone)"
vn-tooltip="Preview" vn-tooltip="Preview"
icon="desktop_windows"> icon="desktop_windows">
</vn-icon-button> </vn-icon-button>
@ -54,6 +54,13 @@
</vn-card> </vn-card>
<vn-pagination model="model"></vn-pagination> <vn-pagination model="model"></vn-pagination>
</div> </div>
<vn-dialog
vn-id="summary"
class="dialog-summary">
<tpl-body>
<vn-zone-summary zone="$ctrl.zoneSelected"></vn-zone-summary>
</tpl-body>
</vn-dialog>
<a ui-sref="zone.create" vn-tooltip="New zone" vn-bind="+" fixed-bottom-right> <a ui-sref="zone.create" vn-tooltip="New zone" vn-bind="+" fixed-bottom-right>
<vn-float-button icon="add"></vn-float-button> <vn-float-button icon="add"></vn-float-button>

View File

@ -26,8 +26,8 @@ export default class Controller {
preview(event, zone) { preview(event, zone) {
event.preventDefault(); event.preventDefault();
event.stopImmediatePropagation(); event.stopImmediatePropagation();
this.$scope.summary.zone = zone; this.zoneSelected = zone;
this.$scope.dialog.show(); this.$scope.summary.show();
} }
} }

View File

@ -1,6 +1,6 @@
import './index.js'; import './index.js';
describe('Agency', () => { xdescribe('Agency', () => {
describe('Component vnZoneIndex', () => { describe('Component vnZoneIndex', () => {
let $componentController; let $componentController;
let controller; let controller;

View File

@ -6,7 +6,7 @@ Price: Precio
Create: Crear Create: Crear
Delete: Eliminar Delete: Eliminar
Settings: Ajustes Settings: Ajustes
Delivery days: Días de envío Locations: Localizaciones
Enter a new search: Introduce una nueva búsqueda Enter a new search: Introduce una nueva búsqueda
Delete zone: Eliminar zona Delete zone: Eliminar zona
Are you sure you want to delete this zone?: ¿Estás seguro de querer eliminar esta zona? Are you sure you want to delete this zone?: ¿Estás seguro de querer eliminar esta zona?
@ -15,4 +15,4 @@ Zones: Zonas
List: Listado List: Listado
Summary: Vista previa Summary: Vista previa
New zone: Nueva zona New zone: Nueva zona
Edit zone: Editar zona Basic data: Datos básicos

View File

@ -1,18 +1,26 @@
<vn-crud-model <vn-crud-model
vn-id="model" vn-id="model"
url="/agency/api/ZoneGeos" url="/agency/api/ZoneTreeviews/getLeaves"
data="geos"> filter="::$ctrl.filter"
params="{zoneFk: $ctrl.$stateParams.id, parentFk: 1}">
</vn-crud-model> </vn-crud-model>
<vn-vertical vn-one> <vn-horizontal>
<vn-card pad-large> <vn-vertical vn-one>
<vn-title>Delivery days</vn-title> <vn-card pad-large>
<vn-searchbar <vn-title>Locations</vn-title>
panel="vn-calendar-search-panel" <vn-searchbar
model="model" model="model"
expr-builder="$ctrl.exprBuilder(param, value)" expr-builder="$ctrl.exprBuilder(param, value)"
vn-focus> on-search="$ctrl.onSearch()"
</vn-searchbar> vn-focus>
<vn-treeview model="model"></vn-treeview> </vn-searchbar>
</vn-card> <vn-treeview vn-id="treeview" model="model"
</vn-vertical> on-selection="$ctrl.onSelection(item)">
</vn-treeview>
</vn-card>
</vn-vertical>
<vn-auto class="right-block">
<vn-zone-calendar zone="::$ctrl.zone"></vn-zone-calendar>
</vn-auto>
</vn-horizontal>

View File

@ -1,12 +1,37 @@
import ngModule from '../module'; import ngModule from '../module';
class Controller { class Controller {
constructor($scope) { constructor($scope, $http, $stateParams) {
this.$stateParams = $stateParams;
this.$scope = $scope; this.$scope = $scope;
this.$http = $http;
this.searchValue = '';
this.filter = {};
}
onSearch() {
this.$scope.$$postDigest(() => {
this.$scope.treeview.refresh();
});
}
exprBuilder(param, value) {
switch (param) {
case 'search':
return {name: {like: `%${value}%`}};
}
}
onSelection(item) {
const path = '/agency/api/ZoneIncludeds/toggleIsIncluded';
const params = {geoFk: item.id, zoneFk: this.zone.id};
this.$http.post(path, params).then(() => {
this.$scope.treeview.repaintNode(item);
});
} }
} }
Controller.$inject = ['$scope']; Controller.$inject = ['$scope', '$http', '$stateParams'];
ngModule.component('vnZoneLocation', { ngModule.component('vnZoneLocation', {
template: require('./index.html'), template: require('./index.html'),

View File

@ -32,23 +32,26 @@
"description": "Detail" "description": "Detail"
}, },
{ {
"url": "/location", "url": "/location?q",
"state": "zone.card.location", "state": "zone.card.location",
"component": "vn-zone-location", "component": "vn-zone-location",
"description": "Location", "description": "Locations",
"params": { "params": {
"zone": "$ctrl.zone" "zone": "$ctrl.zone"
} }
}, },
{ {
"url": "/edit", "url": "/basic-data",
"state": "zone.card.edit", "state": "zone.card.basicData",
"component": "vn-zone-edit", "component": "vn-zone-basic-data",
"description": "Edit zone", "description": "Basic data",
"params": { "params": {
"zone": "$ctrl.zone" "zone": "$ctrl.zone"
} }
} }
], ],
"menu": [] "menu": [
{"state": "zone.card.basicData", "icon": "settings"},
{"state": "zone.card.location", "icon": "my_location"}
]
} }

View File

@ -1,30 +1,37 @@
<vn-card class="summary"> <vn-card class="summary">
<vn-vertical pad-medium> <vn-vertical pad-medium>
<vn-horizontal> <vn-auto>
<vn-one margin-medium> <h5 text-center pad-small-v class="title">{{$ctrl.summary.name}}</h5>
<vn-vertical name="basicData"> </vn-auto>
<h5 translate>Basic data</h5> <vn-horizontal pad-medium>
<vn-label-value label="Name" <vn-one>
value="{{$ctrl.zone.name}}"> <vn-label-value label="Id"
</vn-label-value> value="{{::$ctrl.summary.id}}">
<vn-label-value label="Warehouse" </vn-label-value>
value="{{$ctrl.zone.warehouse.name}}"> <vn-label-value label="Name"
</vn-label-value> value="{{::$ctrl.summary.name}}">
<vn-label-value label="Agency" </vn-label-value>
value="{{$ctrl.zone.agencyMode.name}}"> <vn-label-value label="Warehouse"
</vn-label-value> value="{{::$ctrl.summary.warehouse.name}}">
<vn-label-value label="Estimated hour (ETD)" </vn-label-value>
value="{{$ctrl.zone.hour | date: 'HH:mm'}}"> <vn-label-value label="Agency"
</vn-label-value> value="{{::$ctrl.summary.agencyMode.name}}">
<vn-label-value label="Price" </vn-label-value>
value="{{$ctrl.zone.price | currency: '€': 2}}"> </vn-one>
</vn-label-value> <vn-one>
<vn-label-value label="Bonus" <vn-label-value label="Estimated hour (ETD)"
value="{{$ctrl.zone.price | currency: '€': 2}}"> value="{{::$ctrl.summary.hour | date: 'HH:mm'}}">
</vn-label-value> </vn-label-value>
</vn-vertical> <vn-label-value label="Traveling days"
value="{{::$ctrl.summary.travelingDays}}">
</vn-label-value>
<vn-label-value label="Price"
value="{{::$ctrl.summary.price | currency: '€': 2}}">
</vn-label-value>
<vn-label-value label="Bonus"
value="{{::$ctrl.summary.price | currency: '€': 2}}">
</vn-label-value>
</vn-one> </vn-one>
<vn-one margin-medium></vn-one>
</vn-horizontal> </vn-horizontal>
</vn-vertical> </vn-vertical>
</vn-card> </vn-card>

View File

@ -18,8 +18,17 @@ class Controller {
} }
getSummary() { getSummary() {
this.$http.get(`/agency/api/Zones/${this.zone.id}`).then(response => { let filter = {
this.summary = response.data; include: [
{relation: 'warehouse', fields: ['name']},
{relation: 'agencyMode', fields: ['name']}
],
where: {id: this.zone.id}
};
filter = encodeURIComponent(JSON.stringify((filter)));
this.$http.get(`/agency/api/Zones/findOne?filter=${filter}`).then(res => {
if (res && res.data)
this.summary = res.data;
}); });
} }
} }

View File

@ -36,9 +36,9 @@ export default class Controller {
case 'search': case 'search':
return /^\d+$/.test(value) return /^\d+$/.test(value)
? {id: value} ? {id: value}
: {client: {regexp: value}}; : {client: {like: `%${value}%`}};
case 'client': case 'client':
return {[param]: {regexp: value}}; return {[param]: {like: `%${value}%`}};
case 'created': case 'created':
return {created: {between: [value, value]}}; return {created: {between: [value, value]}};
case 'id': case 'id':

View File

@ -23,7 +23,7 @@ export default class Controller {
case 'name': case 'name':
case 'socialName': case 'socialName':
case 'city': case 'city':
return {[param]: {regexp: `%${value}%`}}; return {[param]: {like: `%${value}%`}};
case 'id': case 'id':
case 'fi': case 'fi':
case 'postcode': case 'postcode':

View File

@ -26,6 +26,9 @@
}, },
"ref": { "ref": {
"type": "String" "type": "String"
},
"totalEntries": {
"type": "Number"
} }
}, },
"relations": { "relations": {

View File

@ -35,10 +35,15 @@ export default class Controller {
return {id: value}; return {id: value};
case 'ref': case 'ref':
return {[param]: {regexp: value}}; return {[param]: {regexp: value}};
case 'shipped':
return {shipped: {lte: value}};
case 'landed':
return {landed: {gte: value}};
case 'id': case 'id':
case 'agencyFk': case 'agencyFk':
case 'warehouseOutFk': case 'warehouseOutFk':
case 'warehouseInFk': case 'warehouseInFk':
case 'totalEntries':
return {[param]: value}; return {[param]: value};
} }
} }

View File

@ -14,6 +14,11 @@
label="Reference" label="Reference"
model="filter.ref"> model="filter.ref">
</vn-textfield> </vn-textfield>
<vn-textfield
vn-one
label="Total entries"
model="filter.totalEntries">
</vn-textfield>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-textfield <vn-textfield
@ -29,6 +34,18 @@
value-field="id"> value-field="id">
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
<vn-horizontal>
<vn-date-picker
vn-one
label="Shipped"
model="filter.shipped">
</vn-date-picker>
<vn-date-picker
vn-one
label="Landed"
model="filter.landed">
</vn-date-picker>
</vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-autocomplete vn-one <vn-autocomplete vn-one
label="Warehouse Out" label="Warehouse Out"