<!DOCTYPE html>
<html>
<head>
<link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<script data-require="angular.js@*" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script data-require="jquery@*" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script data-require="bootstrap@*" data-semver="3.3.6" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script data-require="angular-route@*" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular-route.js"></script>
<link data-require="bootstrap-css@3.3.6" rel="stylesheet" href="https://cdn.rawgit.com/angular-ui/ui-select/v0.13.2/dist/select.min.css" />
<script data-require="jquery@*" src="https://cdn.rawgit.com/angular-ui/ui-select/v0.13.2/dist/select.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<style type="text/css">
.welCustom {
background: #dff0d8
}
</style>
<div data-ng-controller="OrdersController" data-ng-init="createNew()" class="container">
<form name="orderForm" data-ng-submit="create(orderForm.$valid)" role="form">
<div class="well" ng-class="{'welCustom': order.isCash === false}">
<div class="row">
<div class="col-md-6">
<div class="row">
<div class="col-md-6">
<div class="btn-group">
<label class="btn btn-success" ng-model="order.isCash" uib-btn-radio="true">Наличный </label>
<label class="btn btn-success" ng-model="order.isCash" uib-btn-radio="false">Без наличный</label>
</div>
</div>
<div class="col-md-6">
<select data-ng-model="order.client" class="form-control" ng-show="order.isCash === false" id="client" ng-options="client.title for client in clients track by client._id" tabindex="1" required="">
<option value="">Клиенты...</option>
</select>
</div>
</div>
<br />
<div class="row">
<div class="col-md-6">
<ui-select ng-model="order.direction.from" on-select="onSelectPlace($select, 'from')" tagging="" reset-search-input="false" tabindex="2">
<ui-select-match placeholder="Адрес назначение...">{{$select.selected.address}}</ui-select-match>
<ui-select-choices repeat="place in places | filter: {address: $select.search} track by $index | limitTo: 20">
<div ng-if="!place._id" ng-bind-html="place.address +' <small>(новый)</small>'| highlight: $select.search"></div>
<div ng-if="place._id" ng-bind-html="place.address | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
<div class="col-md-6">
<ui-select ng-model="order.direction.to" on-select="onSelectPlace($select, 'to')" tagging="" reset-search-input="false" tabindex="3">
<ui-select-match placeholder="Адрес подачи...">{{$select.selected.address}}</ui-select-match>
<ui-select-choices repeat="place in places | filter: {address: $select.search} track by $index | limitTo: 20">
<div ng-if="!place._id" ng-bind-html="place.address +' <small>(новый)</small>'| highlight: $select.search"></div>
<div ng-if="place._id" ng-bind-html="place.address | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
</div>
<br />
<div class="form-group">
<ui-select multiple="" tagging="contactTagTransform" ng-model="order.passengers" title="Choose a person" tabindex="4">
<ui-select-match placeholder="Добавить контакты пассажиров...">{{$item.name}} <{{$item.phone}}></ui-select-match>
<ui-select-choices repeat="contact in contacts | propsFilter: {name: $select.search, phone: $select.search}">
<div ng-if="contact.isTag" ng-bind-html="contact.name +' <small>(новый)</small>'| highlight: $select.search"></div>
<div ng-if="!contact.isTag" ng-bind-html="contact.name + contact.isTag| highlight: $select.search"></div>
<small>
имя: {{contact.name}}
тел: <span ng-bind-html="''+contact.phone | highlight: $select.search"></span>
</small>
</ui-select-choices>
</ui-select>
</div>
</div>
<div class="col-md-6">
<div class="checkbox">
<label>
<input type="checkbox" data-ng-model="order.preorder" tabindex="9" />
Предаварительный заказ
</label>
</div>
<table class="table table-bordered">
<tbody>
<tr>
<td>Дата пред. заказа:</td>
<td>
<input type="date" class="form-control input-md" data-ng-model="order.moment.advance" ng-disabled="!order.preorder" tabindex="10" />
</td>
</tr>
<tr>
<td>
Время подачи:
</td>
<td>
<input type="time" class="form-control" id="start" name="start" data-ng-model="order.moment.start" ng-disabled="!order.preorder" tabindex="11" />
</td>
</tr>
<tr>
<td>
Время оповещения:
</td>
<td>
<input type="time" class="form-control" id="notification" name="notification" data-ng-model="order.moment.notification" tabindex="11" />
</td>
</tr>
<tr>
<td>
Время встречи:
</td>
<td>
<input type="time" class="form-control" id="met" name="met" data-ng-model="order.moment.met" tabindex="11" />
</td>
</tr>
<tr>
<td>
Время завершения:
</td>
<td>
<input type="time" class="form-control" id="end" name="end" data-ng-model="order.moment.end" tabindex="11" />
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<table class="table table-bordered">
<tbody>
<tr>
<td>
Водитель:
</td>
<td>
<select class="form-control" id="driver" placeholder="driver" data-ng-model="order.driver" ng-options="driver as (driver.id +' - '+driver.name) for driver in drivers" tabindex="5">
<option value="">Водители...</option>
</select>
</td>
</tr>
<tr>
<td>Статус: </td>
<td>
<select class="form-control" id="status" placeholder="status" data-ng-model="order.status" ng-options="status as status.name for status in statuses" tabindex="6" required="">
<option value="">Статусы...</option>
</select>
</td>
</tr>
<tr>
<td>Километраж:</td>
<td>
<input type="number" placeholder="Ведите километраж..." class="form-control input-md" data-ng-model="order.km" tabindex="7" />
</td>
</tr>
<tr>
<td>Коментарий к заказу: </td>
<td>
<input type="textarea" name="comment" data-ng-model="order.comment" tabindex="7" />
</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-6">
<ul class="list">
<li>Сумма клиента по адресу подачи {{ order.fromAdressSum }}</li>
<li>Сумма клиента по адресу назначеия {{ order.toAdressSum }}</li>
<li>Время ожидания {{ order.waitingTime }}</li>
<li>Время ожидания округл {{ order.waitingTimeRounded }}</li>
<li>Время поездки {{ order.tripTime }}</li>
<li>Время поездки округл {{ order.tripTimeRounded }}</li>
<li>Сумма клиента за время ожидания {{ order.waitingTimeRounded * 30}}</li>
<li>Сумма клиента за время поездки {{ order.tripTimeRounded * 30}}</li>
<li>Сумма по км {{ order['kmSum'] }}</li>
<li>км/час {{ order['kmhour'] }}</li>
<li>Сумма после условия {{ order['byIfKmLowerFifteen'] }}</li>
<li>Сумма по трафиной зоне {{ order['tarifMaxSum']}}</li>
<li>Итоговая сумма {{ order['total'] }}</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-6">
<button mean-token="'create-submit'" type="submit" class="btn btn-danger" tabindex="8">Добавить новый заказ</button>
</div>
</div>
</form>
</div>
</body>
</html>
'use strict';
/*global angular */
angular.module('mean.barsManager').controller('OrdersController',
['$scope', '$stateParams', '$location', '$http', 'Global', 'Orders','Clients', 'Places','PaymentTypes','Contacts', 'Statuses','Drivers', 'MeanUser', 'Circles',
function($scope, $stateParams, $location, $http, Global, Orders, Clients, Places, PaymentTypes, Contacts, Statuses, Drivers, MeanUser, Circles) {
$scope.global = Global;
$scope.showClosed = false;
$scope.preorder = false;
$scope.showByStatus = function (status) {
if(status === 'Закрыть'){
return $scope.showClosed;
}else{
return true;
}
};
$scope.hideContacts = function (scope) {
scope.hideContact = false;
};
$scope.hasAuthorization = function(order) {
if (!order || !order.user) return false;
return MeanUser.isAdmin || order.user._id === MeanUser.user._id;
};
$scope.initCircles = function () {
Circles.mine(function(acl) {
$scope.availableCircles = acl.allowed;
$scope.allDescendants = acl.descendants;
});
}
// форматирует новый контакт
$scope.contactTagTransform = function (newTag) {
var val = newTag.split(':');
var item = {
name: val[0],
phone: val[1]
};
return item;
};
// форматирует новый адрес
$scope.addressTagTransform = function (newAddress) {
return {
address: newAddress,
isTag: true
};
};
// Сохраняет новый адрес
$scope.onSelectPlace = function (select, direction){
var order = $scope.order;
if(select.search.length > 3){
console.log('onSelectPlace.search ', select.search);
if(! select.selected || select.selected.address != select.search){
var result = $.grep($scope.places, function (p) {
return p.address === select.search;
});
console.log('onSelectPlace.select.selected ', select.selected, result);
if (result.length == 0) {
// not found
console.log('newItem', select.search);
var p = new Places({
address: select.search,
user: MeanUser.user
});
p.$save(function (response) {
$scope.places.push(response);
order.direction[direction] = response;
});
}
}
}
updateDirectionSum(direction, order, order.isCash, 'onSelectPlace');
};
// Сохраняет новый контакт
$scope.onSelectPassenger = function (select){
console.log('onSelectPassenger.select.selected', select.selected);
if(select.selected){
var selected = select.selected;
for (var i in selected) {
if(selected[i].isTag && selected[i].isTag === true){
console.log('founded new contact ', selected[i]);
var c = new Contacts({
name: selected[i].name,
phone: selected[i].phone
});
c.permissions = $scope.availableCircles.slice(2);
c.created = new Date();
c.$save(function (response) {
if(response){
console.log('saved new contact ', response);
$scope.order.passengers.push(response);
$scope.order.passengers[i] = response;
$scope.$broadcast('SetPassengersFocus')
}
});
}
}
}
};
// Загружает справочники
$scope.loadResources = function (state){
if(state === 'create'){
$scope.order = { };
}
$scope.initCircles();
$scope.clients = [];
Clients.query(function(value) {
$scope.clients = value;
console.log('clients loaded ', $scope.clients);
});
$scope.places = [];
Places.query(function(value) {
$scope.places = value;
});
$scope.paymentTypes = [];
PaymentTypes.query(function(value) {
$scope.paymentTypes = value;
});
$scope.passengers = [];
$scope.contacts = [];
Contacts.query(function(value) {
$scope.contacts = value;
});
$scope.statuses = [];
Statuses.query(function (value) {
$scope.statuses = value;
if(state === 'create'){
$scope.order.status = value[0];
}
});
$scope.drivers = [];
Drivers.query(function (value) {
$scope.drivers = value;
});
};
// Возвращает bootstrap класс по названию статуса
$scope.status = function(name) {
if(name === 'Принят'){
return 'btn-primary';
}
if(name === 'Назначен'){
return 'btn-success';
}
if(name === 'На месте'){
return 'btn-danger';
}
if(name === 'Оповещен'){
return 'btn-warning';
}
if(name === 'Встретил в пути'){
return 'btn-info';
}if(name === 'Принят'){
return 'btn-primary';
}
if(name === 'Закрыть' || name === 'Отменен'){
return 'btn-default';
}
};
// обработчик $watch для обнолвения суммы по выбранным данным
function updateDirectionSum(name, order, isCash, funcName) {
console.log(funcName);
if(order.direction){
if(order.direction[name]){
if(isCash === false){
console.log('isCash = false', order.client);
if(typeof(order.client) !== 'undefined' && order.client['places'].length > 0){
var places = order.client['places'] || [];
var tarif = places.filter(function(v){
return v.place._id === order.direction[name]._id;
});
if(tarif.length > 0){
order[name+'AdressSum'] = tarif[0].sum;
}
console.log('isCash = false && client && tarif', tarif);
}
}else if(isCash === true || typeof(order.direction[name].sum) != 'undefined'){
console.log('isCash = true', order.direction[name]);
order[name+'AdressSum'] = order.direction[name].sum;
}else{
console.log('Default');
order[name+'AdressSum'] = 0;
}
}
}
order['tarifMaxSum'] = Math.max(order.fromAdressSum, order.toAdressSum);
}
// Новая версия формы создания заказа TODO: Переименовать
$scope.createNew = function (isValid) {
$scope.loadResources('create');
$scope.order.moment = {};
$scope.order.isCash = true;
$scope.$watch('order.client', function(isCash, oldVal){
var order = $scope.order;
updateDirectionSum('from', order, order.isCash, '$watch.client');
updateDirectionSum('to', order, order.isCash, '$watch.client');
});
/*global moment, _*/
$scope.$watch('order.isCash', function(isCash, oldVal){
var order = $scope.order;
updateDirectionSum('from', order, isCash, '$watch.client');
updateDirectionSum('to', order, isCash, '$watch.client');
});
$scope.$watch('order.moment', function(newVal, oldVal){
var order = newVal;
if(order.moment){
var ready = _.every([
($scope.preorder === true ? order.moment['start'] : true),
order.moment['notification'],
order.moment['met'],
order.moment['end']
], function(v){
return typeof(v) != 'undefined';
});
if(ready === true){
var start = moment(order.moment.start);
var notification = moment(order.moment.notification);
var met= moment(order.moment.met);
var end = moment(order.moment.end);
var waitingTime = 0;
var tripTime = 0;
if($scope.order.preorder === true){
console.log('$scope.preorder ' , $scope.preorder);
waitingTime = moment.duration(met.diff(start));
}else{
console.log('$scope.preorder ' , $scope.preorder);
waitingTime = moment.duration(met.diff(notification));
}
tripTime = moment.duration(end.diff(met));
order['waitingTime'] = waitingTime.asMinutes() < 10 ? 0 : waitingTime.asMinutes();
order['waitingTimeRounded'] = 5 * Math.round(order['waitingTime'] / 5);
//order['waitingTimeRounded'] = Math.ceil(order['waitingTimeRounded']);
order['tripTime'] = tripTime.asMinutes();
order['tripTimeRounded'] = 15 * Math.round(order['tripTime'] / 15);
order['tripTimeRounded'] = order.tripTimeRounded < 30 ? 30 : Math.ceil(order['tripTimeRounded']);
order.km = order.km || 0;
order['kmSum'] = order.km * 100;
order['byIfKmLowerFifteen'] = order.km > 15 ? order['kmSum'] : (order.tripTimeRounded * 30);
order['kmhour'] = order.km / (order.tripTime * 60);
order['total'] = order['byIfKmLowerFifteen'] + order['tarifMaxSum'] + (order.waitingTimeRounded * 30);
}
}
}, true);
};
// Дулирует существующий заказ
$scope.duplicate = function (order) {
$scope.order = {
};
};
// Инициализация заказов. Подгружает список заказов и установка обработчиков
$scope.find = function() {
$scope.initCircles();
Orders.query(function(orders) {
console.log('orders ', orders);
$scope.orders = orders;
$scope.statuses = [];
Statuses.query(function (value) {
$scope.statuses = value;
});
});
};
// Обновляет статус с страницы заказов
$scope.updateStatus = function (status, order) {
order.status = status;
$scope.order = order;
$scope.update(true);
};
// Находит один заказ и устанавливает обработчики
$scope.findOne = function() {
$scope.initCircles();
$scope.loadResources();
Orders.get({
orderId: $stateParams.orderId
}, function(order) {
order.moment.met = typeof(order.moment.met) !== 'undefined' ? new Date(order.moment.met) : '';
order.moment.advance = typeof(order.moment.advance) !== 'undefined' ? new Date(order.moment.advance) : '';
order.moment.end = typeof(order.moment.end) !== 'undefined' ? new Date(order.moment.end) : '';
$scope.order = order;
console.log('findOne Order ', order);
});
};
// Создание заказа
$scope.create = function(isValid) {
if (isValid) {
var order = new Orders($scope.order);
order.permissions = $scope.availableCircles.slice(2);
order.created = new Date();
order.$save(function(response) {
$location.path('orders');
});
$scope.order = {};
} else {
$scope.submitted = true;
}
};
// Обновление заказа
$scope.update = function(isValid) {
console.log(isValid);
if (isValid) {
var order = $scope.order;
if (!order.updated) {
order.updated = [];
}
order.permissions = $scope.availableCircles.slice(2);
order.updated.push(new Date().getTime());
order.$update(function() {
$location.path('orders');
});
} else {
$scope.submitted = true;
}
};
// Удаление заказа
$scope.remove = function(order) {
if (order) {
order.$remove(function(response) {
for (var i in $scope.orders) {
if ($scope.orders[i] === order) {
$scope.orders.splice(i, 1);
}
}
$location.path('orders');
});
} else {
$scope.order.$remove(function(response) {
$location.path('orders');
});
}
};
}
]);
/* Styles go here */