Добавлен расширенный отчет по реализации
Добавлен монитор активности
This commit is contained in:
miroman-afk
2023-08-03 11:05:15 +03:00
parent 19ad7d1c8a
commit c4dc6e02a0
93 changed files with 13328 additions and 1122 deletions

View File

@@ -0,0 +1,210 @@
(function () {
'use strict';
angular
.module('app', ['angular.drag.resize', 'ng-context-menu', 'ui.bootstrap', 'ui.utils'])
.controller('ActivityMonitorCtrl', ActivityMonitorCtrl);
ActivityMonitorCtrl.$inject = ['$scope', 'smartRequest', 'Notification'];
function ActivityMonitorCtrl($scope, smartRequest, Notification) {
Element.prototype.remove = function () {
this.parentElement.removeChild(this);
}
NodeList.prototype.remove = HTMLCollection.prototype.remove = function () {
for (var i = this.length - 1; i >= 0; i--) {
if (this[i] && this[i].parentElement) {
this[i].parentElement.removeChild(this[i]);
}
}
}
$scope.dataTablesOpt = {
language: {
url: "https://cdn.datatables.net/plug-ins/1.13.3/i18n/ru.json",
},
autoWidth: false,
searching: true,
paging: false,
info: false,
};
$scope.places = [];
$scope.tables = [];
$scope.newTables = [];
$scope.newTables2 = [];
$scope.roommap = [];
$scope.newElement = 0;
$scope.firstPlace = 1;
$('#create_table').hide();
$('#create_place').hide();
$('#places').hide();
$('#background').hide();
$('#background_1').hide();
$('#save_tables').hide();
$('#save_places').hide();
$('#back').hide();
document.getElementById('aside').remove();
document.getElementById("view").style.display = "flex";
document.getElementById("view").style.justifyContent = "center";
document.getElementById("view").style.alignItems = "center";
$scope.getRoomMap = function () {
smartRequest.get('v1/roommap?method=map&type=full', function (data) {
$('#back').show();
$scope.roommap = data.roommap;
});
};
$scope.back = function () {
location.reload();
};
$scope.getPlaces = function () {
smartRequest.get('v1/roommap?method=map&type=places', function (data) {
$scope.places = data.places;
console.log($scope.places);
});
smartRequest.get('v1/roommap?method=statistic&type=places', function (places_info) {
$scope.places_ooc = places_info.opened_orders_count;
$scope.places_oos = places_info.opened_orders_sum;
$scope.places_oocc = places_info.opened_orders_client_count;
$scope.places_coc = places_info.closed_orders_count;
$scope.places_cos = places_info.closed_orders_sum;
$scope.places_cocc = places_info.closed_orders_client_count;
});
};
$scope.getTables = function (place_id) {
$('#places').hide();
$('#background').show();
$('#background_1').show();
$('#create_table').show();
$('#back').show();
$scope.maxWidth = 1024;
$scope.windowHeight = 65;
$scope.screenHeight = screen.height;
$scope.windowWidth = window.innerWidth;
$scope.screenWidth = 80;
smartRequest.get('v1/roommap?method=map&type=place&id=' + place_id, function (data) {
$scope.place = data.place;
$scope.place_id = data.place_id;
$scope.left = 0;
$scope.top = 0;
$scope.tables = data.tables;
$scope.percentWidth = document.getElementById('tables').clientWidth / 1024;
$scope.percentHeight = document.getElementById('tables').clientHeight / 768;
});
smartRequest.get('v1/roommap?method=statistic&type=place&place_id=' + place_id, function (place_info) {
$scope.place_ooc = place_info.opened_orders_count;
$scope.place_oos = place_info.opened_orders_sum;
$scope.place_oocc = place_info.opened_orders_client_count;
$scope.place_coc = place_info.closed_orders_count;
$scope.place_cos = place_info.closed_orders_sum;
$scope.place_cocc = place_info.closed_orders_client_count;
});
};
$scope.getTables($scope.firstPlace);
$scope.getPlaces();
$scope.getTableInfo = function (place_id, table_id) {
smartRequest.get('v1/roommap?method=statistic&type=place&place_id=' + place_id + '&table_id=' + table_id, function (data) {
$scope.place_name = data.place_name;
$scope.place_id = place_id;
$scope.waited_count = data.waited_count;
$scope.waited_sum = data.waited_sum;
$scope.closed_count = data.closed_count;
$scope.closed_sum = data.closed_sum;
$scope.deleted_count = data.deleted_count;
$scope.deleted_sum = data.deleted_sum;
$scope.returned_count = data.returned_count;
$scope.returned_sum = data.returned_sum;
$scope.cancellations_count = data.cancellations_count;
$scope.cancellations_sum = data.cancellations_sum;
$scope.orders = data.orders;
$scope.orders.forEach(function(order) {
$scope.title = '';
if (order.is_printed_before_edit) {
$scope.title = $scope.title + ' Распечатан предчек до удаления позиции!<br>';
}
if (order.hasMove) {
$scope.title = $scope.title + ' Использовался перенос заказа!<br>';
}
if (order.hasMerge) {
$scope.title = $scope.title + ' Использовалось объединение заказов!<br>';
}
if (order.hasSlice) {
$scope.title = $scope.title + ' Использовалось разбиение заказа!<br>';
}
if (order.hasDelete) {
$scope.title = $scope.title + ' Присутствует удаление товаров!<br>';
}
order.title = $scope.title;
});
if ($scope.waited_count + $scope.closed_count + $scope.deleted_count + $scope.returned_count + $scope.cancellations_count > 0) {
$('#orders').modal();
$(function () {
$('[data-toggle="tooltip"]').tooltip({ html:true });
});
} else {
Notification.error('Заказы отсутствуют');
}
});
};
$scope.getOrderInfo = function (order_id, opened, closed) {
$scope.clients_modal = false;
$scope.orders_modal = true;
smartRequest.get('v1/orderhistory?order_id=' + order_id, function (actions) {
$scope.actions = actions;
});
smartRequest.get('v1/orderinfo?order_id=' + order_id + '&opened=' + opened + '&closed=' + closed, function (data) {
$scope.order = data.info;
$scope.cols = 5;
if ($scope.order.returned_count > 0) {
$scope.cols = $scope.cols + 1;
}
if ($scope.order.deleted_count > 0) {
$scope.cols = $scope.cols + 1;
}
$scope.backModal('orders', 'order');
});
};
$scope.closeModal = function (modalName) {
$scope.modalName = '#' + modalName;
$('.modal-body').scrollTop(0);
$($scope.modalName).modal('dispose');
return true;
};
$scope.backModal = function (prevModalName, targetModalName) {
$scope.prevModalName = '#' + prevModalName;
$scope.targetModalName = '#' + targetModalName;
$('.modal-body').scrollTop(0);
$($scope.prevModalName).modal('hide');
$($scope.targetModalName).modal('toggle');
return true;
};
$scope.borderStyle = function (sum, count) {
let style = '2px solid rgb(33, 150, 243)';
if (sum != 0 && count != 0) {
style = '2px solid rgb(255, 0, 0)';
}
if (sum == 0 && count != 0) {
style = '2px solid rgb(0, 255, 0)';
}
return style;
};
}
})();

View File

@@ -318,11 +318,30 @@
});
};
$scope.getItems = function (order_id, opened, closed) {
smartRequest.get('v1/clientorderinfo?order_id=' + order_id + '&opened=' + opened + '&closed=' + closed, function (data) {
$scope.order = data.info;
$('#order').modal('toggle');
$scope.getOrderInfo = function (order_id, opened, closed) {
$scope.clients_modal = true;
$scope.orders_modal = false;
smartRequest.get('v1/orderhistory?order_id=' + order_id + '&opened=' + opened + '&closed=' + closed, function (actions) {
$scope.actions = actions;
});
smartRequest.get('v1/orderinfo?order_id=' + order_id + '&opened=' + opened + '&closed=' + closed, function (data) {
$scope.order = data.info;
$scope.cols = 5;
if ($scope.order.returned_count > 0) {
$scope.cols = $scope.cols + 1;
}
if ($scope.order.deleted_count > 0) {
$scope.cols = $scope.cols + 1;
}
$('#order').modal();
});
};
$scope.closeModal = function (modalName) {
$scope.modalName = '#' + modalName;
$('.modal-body').scrollTop(0);
$($scope.modalName).modal('dispose');
return true;
};
var mergeFiles = function (statuses) {

View File

@@ -9,10 +9,8 @@
if (typeof input == 'string') {
input = parseFloat(input.replace(/,/g, '.'));
}
var outputValue = input;
if (typeof outputValue !== 'undefined') {
if (typeof outputValue !== 'undefined' && outputValue !== null) {
return outputValue.toFixed(2);
} else {
return 0.00;
@@ -72,7 +70,7 @@
//Отображение текущего времени
$scope.currentDate = new Date();
var timer = $interval(function() {
var timer = $interval(function () {
$scope.currentDate = new Date();
}, 1000);
@@ -85,10 +83,10 @@
//Автоматическое обновление данных
$scope.timerEnabled = false;
$scope.timeRemaining = new Date(0, 0, 0, 0, 2, 0);
$scope.timeRemaining = new Date(0, 0, 0, 0, 1, 0);
var updateTimer = null;
$scope.toggleTimer = function() {
$scope.toggleTimer = function () {
if ($scope.timerEnabled) {
startTimer();
} else {
@@ -98,12 +96,12 @@
function startTimer() {
if (updateTimer === null) {
updateTimer = $interval(function() {
updateTimer = $interval(function () {
$scope.timeRemaining.setSeconds($scope.timeRemaining.getSeconds() - 1);
console.log($scope.timeRemaining.getSeconds());
//console.log($scope.timeRemaining.getSeconds());
if ($scope.timeRemaining.getMinutes() === 0 && $scope.timeRemaining.getSeconds() === 0) {
stopTimer();
$scope.timeRemaining = new Date(0, 0, 0, 0, 2, 0);
$scope.timeRemaining = new Date(0, 0, 0, 0, 1, 0);
console.log('Данные обновлены');
smartRequest.get('v1/clearcache?folder=dashboard', function (data) {
});
@@ -122,11 +120,43 @@
}
//Остановка таймеров
$scope.$on('$destroy', function() {
$scope.$on('$destroy', function () {
$interval.cancel(timer);
$interval.cancel(updateTimer);
});
$scope.dataTablesOpt = {
language: {
url: "https://cdn.datatables.net/plug-ins/1.13.3/i18n/ru.json",
},
autoWidth: false,
searching: true,
paging: false,
info: false,
};
/* $scope.dtoptions = {
/!*dom: "lfBrtip",*!/
language: {
url: "https://cdn.datatables.net/plug-ins/1.13.3/i18n/ru.json",
},
autoWidth: true,
searching: true,
paging: false,
info: false,
aoColumns: [
{title: "#"},
{title: "Гость", visible: false},
{title: "Статус", className: "text-right"},
{title: "Открыт", className: "text-right"},
{title: "Закрыт", className: "text-right"},
{title: "Сумма, BYN", className: "text-right"}
]
/!*buttons: [
{text: 'Экспорт в PDF', className: 'md-btn md-raised m-b-sm blue', extend: 'pdf'},
]*!/
};*/
$scope.orders_closed = {
percent: 0,
total: 0,
@@ -137,6 +167,11 @@
total: 0,
sum: 0
};
$scope.orders_cancellations = {
percent: 0,
total: 0,
sum: 0
};
$scope.orders_deleted = {
percent: 0,
total: 0,
@@ -334,231 +369,12 @@
});
};
$scope.updateData = function () {
smartRequest.get('dashboard/online/updatetime', function (data) {
$scope.update_time = data.updated;
});
smartRequest.get('v1/dashboard?method=info', function (data) {
$scope.shiftInfo = data;
});
smartRequest.get('dashboard/online/payments', function (data) {
$scope.payments.labels = data.payments.map(payment => payment.name);
$scope.payments.data = data.payments.map(payment => payment.value);
});
smartRequest.get('dashboard/online/orders', function (data) {
var total = data.wait_count + data.closed_count + data.deleted_count + data.returned_count;
$scope.orders_closed.percent = $scope.calcPercentageForGroupOrders(total, data.closed_count);
$scope.orders_closed.total = data.closed_count;
$scope.orders_closed.sum = data.closed_sum;
$scope.orders_waited.percent = $scope.calcPercentageForGroupOrders(total, data.wait_count);
$scope.orders_waited.total = data.wait_count;
$scope.orders_waited.sum = data.wait_sum;
$scope.orders_deleted.percent = $scope.calcPercentageForGroupOrders(total, data.deleted_count);
$scope.orders_deleted.total = data.deleted_count;
$scope.orders_deleted.sum = data.deleted_sum;
$scope.orders_returned.percent = $scope.calcPercentageForGroupOrders(total, data.returned_count);
$scope.orders_returned.total = data.returned_count;
$scope.orders_returned.sum = data.returned_sum;
});
smartRequest.get('dashboard/online/middle', function (data) {
$scope.middle = data.middle_check;
});
smartRequest.get('dashboard/online/total', function (data) {
$scope.total = data.total;
});
smartRequest.get('v1/onlinestaff?method=dashboard', function (data) {
$scope.personals = data.staff;
});
smartRequest.get('v1/topdishes', function (data) {
$scope.dishes = data.dishes;
$scope.terminalId = data.terminal;
if ($scope.terminalId > 0) {
smartRequest.post('settings/update/force', {
task: 'online',
terminal: $scope.terminalId,
}, function (data) {
$('#preload-modal').modal();
setTimeout(function () {
Notification.success('Данные синхронизируются. Обновите страницу через 5 минут.');
$('#preload-modal').modal('toggle');
}, 5000);
});
}
});
smartRequest.get('dashboard/online/folders', function (data) {
$scope.folders.labels = data.folders.map(folder => folder.name);
$scope.folders.data = data.folders.map(folder => Math.roundClearNG(folder.count));
});
smartRequest.get('dashboard/online/printers', function (data) {
$scope.printers.labels = [];
$scope.printers.data = [];
for (var i = 0; i < data.printers.length; i++) {
$scope.printers.labels.push(data.printers[i].name);
$scope.printers.data.push(Math.roundClearNG(data.printers[i].count, -2));
}
});
smartRequest.get('dashboard/online/tables', function (data) {
$scope.tables = data.tables;
});
smartRequest.get('dashboard/online/menu', function (data) {
$scope.menus.labels = [];
$scope.menus.data = [];
for (var i = 0; i < data.menus.length; i++) {
$scope.menus.labels.push(data.menus[i].menu_name);
$scope.menus.data.push(Math.roundClearNG(data.menus[i].count, -2));
}
});
smartRequest.get('dashboard/online/profit', function (data) {
$scope.profit = data.profit;
});
smartRequest.get('v1/dashboard?method=guests', function (data) {
$scope.guests = data.guestsCount;
$scope.namedGuests = data.namedGuests;
$scope.sumNamedGuests = data.totalSum;
});
smartRequest.get('v1/dashboard?method=deleted', function (data) {
$scope.deleted = Math.roundNG(data.count, -2);
$scope.deleted_sum = Math.roundNG(data.sum, -2);
});
smartRequest.get('v1/onlinediscount', function (data) {
$scope.discounts = Math.roundNG(data.count, -2);
$scope.discounts_sum = Math.roundNG(data.sum, -2);
$scope.tot_disc_sum = Math.roundNG(data.total_sum, -2);
});
smartRequest.get('v1/dashboard?method=guests&type=median', function (data) {
$scope.medianGuests.labels = [];
$scope.medianGuests.data = [[]];
var tempData = [];
var tempTime = [];
for (var i = 0; i < data.data.length; i++) {
var newDate = $scope.getMomentDate(data.data[i].time);
tempData.push(parseInt(data.data[i].count));
tempTime.push(newDate);
var indexTime = $scope.getIntervals(tempTime[i], $scope.medianGuests.labels);
if (indexTime == -1) {
$scope.medianGuests.labels.push(tempTime[i]);
$scope.medianGuests.data[0].push(tempData[i]);
} else {
$scope.medianGuests.data[0][indexTime] += tempData[i];
}
}
});
smartRequest.get('dashboard/online/finance/median', function (data) {
$scope.medianFinance.labels = [];
$scope.medianFinance.data = [[], [], []];
var tempSum = [];
var tempTotalCost = [];
var tempProffit = [];
var tempTime = [];
for (var i = 0; i < data.data.length; i++) {
var newDate = $scope.getMomentDate(data.data[i].time);
tempSum.push(data.data[i].sum);
tempTotalCost.push(data.data[i].totalCost);
var proffit = parseFloat((tempSum[i] - tempTotalCost[i]).toFixed(2));
tempProffit.push(proffit);
tempTime.push(newDate);
var indexTime = $scope.getIntervals(tempTime[i], $scope.medianFinance.labels);
$scope.fillMedianFinance(indexTime, tempTime[i], tempSum[i], tempTotalCost[i], tempProffit[i]);
}
for (var i = 0; i < $scope.medianFinance.data.length; i++) {
for (var j = 0; j < $scope.medianFinance.data[i].length; j++) {
var data = $scope.medianFinance.data[i][j];
data = Math.round(data * 100) / 100;
$scope.medianFinance.data[i][j] = data;
}
}
});
$scope.checkUpdate();
};
$scope.update = function () {
smartRequest.get('dashboard/online/updatetime', function (data) {
$scope.update_time = data.updated;
});
smartRequest.get('v1/dashboard?method=info', function (data) {
$scope.shiftInfo = data;
});
smartRequest.get('dashboard/online/payments', function (data) {
$scope.payments.labels = data.payments.map(payment => payment.name);
$scope.payments.data = data.payments.map(payment => payment.value);
});
smartRequest.get('dashboard/online/orders', function (data) {
var total = data.wait_count + data.closed_count + data.deleted_count + data.returned_count;
$scope.orders_closed.percent = $scope.calcPercentageForGroupOrders(total, data.closed_count);
$scope.orders_closed.total = data.closed_count;
$scope.orders_closed.sum = data.closed_sum;
$scope.orders_waited.percent = $scope.calcPercentageForGroupOrders(total, data.wait_count);
$scope.orders_waited.total = data.wait_count;
$scope.orders_waited.sum = data.wait_sum;
$scope.orders_deleted.percent = $scope.calcPercentageForGroupOrders(total, data.deleted_count);
$scope.orders_deleted.total = data.deleted_count;
$scope.orders_deleted.sum = data.deleted_sum;
$scope.orders_returned.percent = $scope.calcPercentageForGroupOrders(total, data.returned_count);
$scope.orders_returned.total = data.returned_count;
$scope.orders_returned.sum = data.returned_sum;
});
smartRequest.get('dashboard/online/middle', function (data) {
$scope.middle = data.middle_check;
});
smartRequest.get('dashboard/online/total', function (data) {
$scope.total = data.total;
});
smartRequest.get('v1/onlinestaff?method=dashboard', function (data) {
$scope.personals = data.staff;
});
smartRequest.get('v1/topdishes', function (data) {
$scope.dishes = data.dishes;
});
smartRequest.get('dashboard/online/folders', function (data) {
$scope.folders.labels = data.folders.map(folder => folder.name);
$scope.folders.data = data.folders.map(folder => Math.roundClearNG(folder.count));
@@ -574,7 +390,7 @@
}
});
smartRequest.get('dashboard/online/tables', function (data) {
smartRequest.get('v1/dashboard?method=tables&type=online', function (data) {
$scope.tables = data.tables;
});
@@ -588,22 +404,59 @@
}
});
smartRequest.get('dashboard/online/profit', function (data) {
smartRequest.get('dashboard/online/payments', function (data) {
$scope.payments.labels = data.payments.map(payment => payment.name);
$scope.payments.data = data.payments.map(payment => payment.value);
});
smartRequest.get('v1/dashboard?method=info', function (data) {
$scope.shiftInfo = data;
});
smartRequest.get('v1/dashboard?method=total', function (data) {
$scope.total = data.total;
var total_closed = data.waited_count + data.closed_count + data.cancellations_count;
var total_dr = data.deleted_count + data.returned_count;
$scope.orders_closed.percent = $scope.calcPercentageForGroupOrders(total_closed, data.closed_count);
$scope.orders_closed.total = data.closed_count;
$scope.orders_closed.sum = data.closed_sum;
$scope.orders_waited.percent = $scope.calcPercentageForGroupOrders(total_closed, data.waited_count);
$scope.orders_waited.total = data.waited_count;
$scope.orders_waited.sum = data.waited_sum;
$scope.orders_cancellations.percent = $scope.calcPercentageForGroupOrders(total_closed, data.cancellations_count);
$scope.orders_cancellations.total = data.cancellations_count;
$scope.orders_cancellations.sum = data.cancellations_sum;
$scope.orders_deleted.percent = $scope.calcPercentageForGroupOrders(total_dr, data.deleted_count);
$scope.orders_deleted.total = data.deleted_count;
$scope.orders_deleted.sum = data.deleted_sum;
$scope.orders_returned.percent = $scope.calcPercentageForGroupOrders(total_dr, data.returned_count);
$scope.orders_returned.total = data.returned_count;
$scope.orders_returned.sum = data.returned_sum;
});
smartRequest.get('v1/dashboard?method=staff&type=online', function (data) {
$scope.personals = data.staff;
});
smartRequest.get('v1/topdishes', function (data) {
$scope.dishes = data.dishes;
});
smartRequest.get('v1/dashboard?method=profit', function (data) {
$scope.profit = data.profit;
$scope.middle = data.middle;
$scope.guests = data.guests;
});
smartRequest.get('v1/dashboard?method=guests', function (data) {
$scope.guests = data.guestsCount;
$scope.namedGuests = data.namedGuests;
$scope.sumNamedGuests = data.totalSum;
});
smartRequest.get('v1/dashboard?method=deleted', function (data) {
$scope.deleted = Math.roundNG(data.count, -2);
$scope.deleted_sum = Math.roundNG(data.sum, -2);
});
smartRequest.get('v1/onlinediscount', function (data) {
smartRequest.get('v1/dashboard?method=discounts&type=online', function (data) {
$scope.discounts = Math.roundNG(data.count, -2);
$scope.discounts_sum = Math.roundNG(data.sum, -2);
$scope.tot_disc_sum = Math.roundNG(data.total_sum, -2);
@@ -765,24 +618,261 @@
});
};
$scope.getMoreGuests = function (code) {
smartRequest.get('v1/dashboard?method=guests&type=more', function (data) {
$scope.moreData = data;
$('#get-more-guests').modal();
$scope.getOrderInfo = function (order_id, opened, closed) {
$scope.clients_modal = false;
$scope.orders_modal = true;
smartRequest.get('v1/orderhistory?order_id=' + order_id, function (actions) {
$scope.actions = actions;
});
smartRequest.get('v1/orderinfo?order_id=' + order_id + '&opened=' + opened + '&closed=' + closed, function (data) {
$scope.order = data.info;
$scope.cols = 5;
if ($scope.order.returned_count > 0) {
$scope.cols = $scope.cols + 1;
}
if ($scope.order.deleted_count > 0) {
$scope.cols = $scope.cols + 1;
}
$scope.backModal('orders', 'order');
});
};
$scope.closeModal = function (modalName) {
$scope.modalName = '#' + modalName;
$('.modal-body').scrollTop(0);
$($scope.modalName).modal('dispose');
return true;
};
$scope.backModal = function (prevModalName, targetModalName) {
$scope.prevModalName = '#' + prevModalName;
$scope.targetModalName = '#' + targetModalName;
$('.modal-body').scrollTop(0);
$($scope.prevModalName).modal('hide');
$($scope.targetModalName).modal('toggle');
return true;
};
$scope.getMoreTotal = function (type) {
$scope.type = type;
$scope.guests_info = false;
$scope.deleted_info = false;
$scope.discount_info = false;
smartRequest.get('v1/roommap?method=statistic&type=full', function (data) {
$scope.staff_name = false;
$scope.waited_count = data.waited_count;
$scope.waited_sum = data.waited_sum;
$scope.closed_count = data.closed_count;
$scope.closed_sum = data.closed_sum;
$scope.deleted_count = data.deleted_count;
$scope.deleted_sum = data.deleted_sum;
$scope.returned_count = data.returned_count;
$scope.returned_sum = data.returned_sum;
$scope.cancellations_count = data.cancellations_count;
$scope.cancellations_sum = data.cancellations_sum;
$scope.orders = data.orders;
$scope.orders.forEach(function (order) {
$scope.title = '';
if (order.is_printed_before_edit) {
$scope.title = $scope.title + ' Распечатан предчек до удаления позиции!<br>';
}
if (order.hasMove) {
$scope.title = $scope.title + ' Использовался перенос заказа!<br>';
}
if (order.hasMerge) {
$scope.title = $scope.title + ' Использовалось объединение заказов!<br>';
}
if (order.hasSlice) {
$scope.title = $scope.title + ' Использовалось разбиение заказа!<br>';
}
if (order.hasDelete) {
$scope.title = $scope.title + ' Присутствует удаление товаров!<br>';
}
order.title = $scope.title;
});
if ($scope.waited_count + $scope.closed_count + $scope.deleted_count + $scope.returned_count + $scope.cancellations_count > 0) {
$('#orders').modal('show');
} else {
Notification.error('Заказы отсутствуют');
}
});
};
$scope.getMoreGuests = function (type) {
$scope.guests_info = true;
$scope.type = type;
$scope.deleted_info = false;
$scope.discount_info = false;
smartRequest.get('v1/roommap?method=statistic&type=full&guests=true', function (data) {
$scope.staff_name = false;
$scope.waited_count = data.waited_count;
$scope.waited_sum = data.waited_sum;
$scope.closed_count = data.closed_count;
$scope.closed_sum = data.closed_sum;
$scope.deleted_count = data.deleted_count;
$scope.deleted_sum = data.deleted_sum;
$scope.returned_count = data.returned_count;
$scope.returned_sum = data.returned_sum;
$scope.cancellations_count = data.cancellations_count;
$scope.cancellations_sum = data.cancellations_sum;
$scope.orders = data.orders;
$scope.orders.forEach(function (order) {
$scope.title = '';
if (order.is_printed_before_edit) {
$scope.title = $scope.title + ' Распечатан предчек до удаления позиции!<br>';
}
if (order.hasMove) {
$scope.title = $scope.title + ' Использовался перенос заказа!<br>';
}
if (order.hasMerge) {
$scope.title = $scope.title + ' Использовалось объединение заказов!<br>';
}
if (order.hasSlice) {
$scope.title = $scope.title + ' Использовалось разбиение заказа!<br>';
}
if (order.hasDelete) {
$scope.title = $scope.title + ' Присутствует удаление товаров!<br>';
}
order.title = $scope.title;
});
if ($scope.waited_count + $scope.closed_count + $scope.deleted_count + $scope.returned_count + $scope.cancellations_count > 0) {
$('#orders').modal('show');
} else {
Notification.error('Заказы отсутствуют');
}
});
};
$scope.getMoreStaff = function (staff, type) {
$scope.type = type;
$scope.guests_info = false;
$scope.deleted_info = false;
$scope.discount_info = false;
smartRequest.get('v1/roommap?method=statistic&type=full&staff_id=' + staff.code, function (data) {
$scope.staff_name = staff.name;
$scope.waited_count = data.waited_count;
$scope.waited_sum = data.waited_sum;
$scope.closed_count = data.closed_count;
$scope.closed_sum = data.closed_sum;
$scope.deleted_count = data.deleted_count;
$scope.deleted_sum = data.deleted_sum;
$scope.returned_count = data.returned_count;
$scope.returned_sum = data.returned_sum;
$scope.cancellations_count = data.cancellations_count;
$scope.cancellations_sum = data.cancellations_sum;
$scope.orders = data.orders;
$scope.orders.forEach(function (order) {
$scope.title = '';
if (order.is_printed_before_edit) {
$scope.title = $scope.title + ' Распечатан предчек до удаления позиции!<br>';
}
if (order.hasMove) {
$scope.title = $scope.title + ' Использовался перенос заказа!<br>';
}
if (order.hasMerge) {
$scope.title = $scope.title + ' Использовалось объединение заказов!<br>';
}
if (order.hasSlice) {
$scope.title = $scope.title + ' Использовалось разбиение заказа!<br>';
}
if (order.hasDelete) {
$scope.title = $scope.title + ' Присутствует удаление товаров!<br>';
}
order.title = $scope.title;
});
if ($scope.waited_count + $scope.closed_count + $scope.deleted_count + $scope.returned_count + $scope.cancellations_count > 0) {
$('#orders').modal('show');
} else {
Notification.error('Заказы отсутствуют');
}
});
};
$scope.getMoreDeleted = function () {
smartRequest.get('v1/dashboard?method=deleted&more=true', function (data) {
$scope.moreData = data;
$('#get-more-deleted').modal();
$scope.guests_info = false;
$scope.deleted_info = true;
$scope.discount_info = false;
smartRequest.get('v1/roommap?method=statistic&type=full&deleted=true', function (data) {
$scope.waited_count = data.waited_count;
$scope.waited_sum = data.waited_sum;
$scope.closed_count = data.closed_count;
$scope.closed_sum = data.closed_sum;
$scope.deleted_count = data.deleted_count;
$scope.deleted_sum = data.deleted_sum;
$scope.returned_count = data.returned_count;
$scope.returned_sum = data.returned_sum;
$scope.cancellations_count = data.cancellations_count;
$scope.cancellations_sum = data.cancellations_sum;
$scope.orders = data.orders;
$scope.orders.forEach(function (order) {
$scope.title = '';
if (order.is_printed_before_edit) {
$scope.title = $scope.title + ' Распечатан предчек до удаления позиции!<br>';
}
if (order.hasMove) {
$scope.title = $scope.title + ' Использовался перенос заказа!<br>';
}
if (order.hasMerge) {
$scope.title = $scope.title + ' Использовалось объединение заказов!<br>';
}
if (order.hasSlice) {
$scope.title = $scope.title + ' Использовалось разбиение заказа!<br>';
}
if (order.hasDelete) {
$scope.title = $scope.title + ' Присутствует удаление товаров!<br>';
}
order.title = $scope.title;
});
if ($scope.waited_count + $scope.closed_count + $scope.deleted_count + $scope.returned_count + $scope.cancellations_count > 0) {
$('#orders').modal('show');
} else {
Notification.error('Заказы отсутствуют');
}
});
};
$scope.getMoreDiscount = function () {
smartRequest.get('v1/morediscount/', function (data) {
$scope.moreData = data;
$('#get-more-discount').modal();
$scope.guests_info = false;
$scope.deleted_info = false;
$scope.discount_info = true;
smartRequest.get('v1/roommap?method=statistic&type=full&discounts=true', function (data) {
$scope.waited_count = data.waited_count;
$scope.waited_sum = data.waited_sum;
$scope.closed_count = data.closed_count;
$scope.closed_sum = data.closed_sum;
$scope.deleted_count = data.deleted_count;
$scope.deleted_sum = data.deleted_sum;
$scope.returned_count = data.returned_count;
$scope.returned_sum = data.returned_sum;
$scope.cancellations_count = data.cancellations_count;
$scope.cancellations_sum = data.cancellations_sum;
$scope.orders = data.orders;
$scope.orders.forEach(function (order) {
$scope.title = '';
if (order.is_printed_before_edit) {
$scope.title = $scope.title + ' Распечатан предчек до удаления позиции!<br>';
}
if (order.hasMove) {
$scope.title = $scope.title + ' Использовался перенос заказа!<br>';
}
if (order.hasMerge) {
$scope.title = $scope.title + ' Использовалось объединение заказов!<br>';
}
if (order.hasSlice) {
$scope.title = $scope.title + ' Использовалось разбиение заказа!<br>';
}
if (order.hasDelete) {
$scope.title = $scope.title + ' Присутствует удаление товаров!<br>';
}
order.title = $scope.title;
});
if ($scope.waited_count + $scope.closed_count + $scope.deleted_count + $scope.returned_count + $scope.cancellations_count > 0) {
$('#orders').modal('show');
} else {
Notification.error('Заказы отсутствуют');
}
});
};
@@ -794,54 +884,6 @@
});
};
$scope.getItemsDeleted = function (order) {
$('#get-more-deleted').modal('toggle');
smartRequest.get('v1/dashboard?method=deleted&items=true&order_id=' + order.number, function (data) {
$scope.order = data;
$('#items-deleted').modal('toggle');
});
};
$scope.getItemsStaff = function (order) {
$('#get-more-staff').modal('toggle');
smartRequest.get('v1/onlinestaff?method=items&order=' + order.number, function (data) {
$scope.order = data;
$('#items-staff').modal('toggle');
});
};
$scope.getItemsDiscount = function (order) {
$('#get-more-discount').modal('toggle');
smartRequest.get('v1/discountitems?order=' + order.number, function (data) {
$scope.order = data;
$('#items-discount').modal('toggle');
});
};
$scope.returnModal = function (name) {
$('#items-' + name).on('hidden.bs.modal', function (event) {
$('#get-more-' + name).modal('show');
});
};
$scope.getTotalItems = function (order) {
$('#get-more-total').modal('toggle');
smartRequest.get('dashboard/total/items?order=' + order.number, function (data) {
$scope.order = data;
smartRequest.get('v1/orderhistory?order_id=' + order.number, function (actions) {
$scope.actions = actions;
});
$('#items-total').modal('toggle');
});
};
$scope.getStaffMore = function (staff) {
smartRequest.get('dashboard/more/staff?code=' + staff.code, function (data) {
$scope.staff = data;
$('#get-more-staff').modal('toggle');
});
};
$scope.getTableMore = function (table) {
smartRequest.get('dashboard/more/table?place=' + table.place_name + '&table=' + table.table_name, function (data) {
$scope.table_ord = data;
@@ -876,7 +918,7 @@
};
$scope.GetCountNamedGuests = declOfNum(['именованный гость', 'именованных гостя', 'именованных гостей']);
$scope.GetCountDeletedPositions = declOfNum(['позиций', 'позиции', 'позиций']);
$scope.GetCountDeletedPositions = declOfNum(['товаров', 'товара', 'товаров']);
$scope.GetCountTotalOrders = declOfNum(['заказ', 'заказа', 'заказов']);
}

View File

@@ -143,22 +143,478 @@
$scope.totalSum = data.totalSum;
$scope.totalCount = data.totalCount;
$('#preload-modal').modal('hide');
$('#report-delete').modal();
if ($scope.totalCount > 0) {
$('#report-delete').modal();
} else {
Notification.error(data.message);
}
$scope.update();
});
};
$scope.reportRealisation = function () {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Ожидайте.');
smartRequest.get('v1/datareport?type=realisation&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.update();
$scope.report_realisation = data.printers;
$scope.return_printers = data.ret_prints;
$scope.report_realisation.total_count = data.total_count;
$scope.report_realisation.total_sum = data.total_sum;
$('#preload-modal').modal('hide');
$('#report-realisation').modal();
});
};
$scope.drawTable = function (data) {
var collapsedGroups = [];
var groupParent = [];
var counter = 1;
$.fn.dataTable.moment('YYYY-MM-DD HH:mm:ss');
$scope.table = $('#table_orders').DataTable({
data: data,
destroy: true,
columns: [
{data: 'shift_id', title: 'Смена'},//hide
{data: 'work_place', title: 'Раб.место'},//hide
{data: 'place_name', title: 'Зал'},//hide
{data: 'table_name', title: 'Стол'},//hide
{
data: 'staff_name',
title: 'Смена/Зал/Стол/Заказ/Персонал',
searchBuilderTitle: 'Персонал',
class: 'order_id'
},
{data: 'client_name', title: 'Клиент', class: 'order_id'},
{data: 'item_name', title: 'Товар'},
{data: 'order_code', title: 'Заказ'},//hide
{data: 'item_time', title: 'Время'},
{
data: 'printer_name',
title: 'МП',
searchBuilderTitle: 'Место приготовления',
class: 'order_id'
},
{
data: 'item_count',
title: 'Кол-во',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 3, '', '').display(data);
}
},
{data: 'item_real_price', title: 'Цена',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{data: 'item_sale_price', title: 'Сумма',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{data: 'item_special_price', title: 'Себест.', searchBuilderTitle: 'Себестоимость'},
{
data: 'item_cash',
title: 'Нал.', searchBuilderTitle: 'Оплата наличными',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{
data: 'item_credit',
title: 'Кред.карта', searchBuilderTitle: 'Оплата кредитной картой',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{
data: 'item_presale',
title: 'Аванс', searchBuilderTitle: 'Зачет аванса',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{data: 'item_clearing', title: 'Б/н', searchBuilderTitle: 'Оплата безналичными',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{data: 'item_discount_sum', title: 'Скидка, BYN', searchBuilderTitle: 'Сумма скидки',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{data: 'item_discount_value', title: 'Скидка, %', searchBuilderTitle: '% скидки'},
{
data: 'order_opened',
title: 'Время открытия заказа',
searchBuilderTitle: 'Время открытия заказа'
},//hide
{
data: 'order_closed',
title: 'Время закрытия заказа',
searchBuilderTitle: 'Время закрытия заказа'
},//hide
{data: 'order_check_number', searchBuilderTitle: 'Номер чека'},//hide
{
data: 'shift_opened',
title: 'Время открытия смены',
searchBuilderTitle: 'Время открытия смены'
},//hide
{
data: 'shift_closed',
title: 'Время закрытия смены',
searchBuilderTitle: 'Время закрытия смены'
},//hide
],
order: [[0, 'asc'], [1, 'asc'], [2, 'asc'], [3, 'asc'], [7, 'asc']],
columnDefs: [{
targets: [0, 1, 2, 3, 7, 20, 21, 22, 23, 24],
visible: false
}],
stripeClasses: [],
fixedHeader: true,
scrollCollapse: false,
paging: false,
searching: true,
responsive: false,
dom: 'QBfrtip',
searchBuilder: {
columns: [0, 2, 3, 4, 5, 6, 7, 8, 9, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
},
buttons: [{
text: 'Excel',
action: function (e, dt, node, conf) {
$scope.exportTableToExcel('table_orders', 'extend-realisation');
}
}],
language: {
url: "https://cdn.datatables.net/plug-ins/1.13.3/i18n/ru.json",
},
rowGroup: {
dataSrc: ['shift_id', 'place_name', 'table_name', 'order_code'],
startRender: function (rows, group, level) {
groupParent[level] = group;
var groupAll = '';
var name = '';
var check_text = '';
$scope.opened = '';
$scope.closed = '';
$scope.check_number = null;
for (var i = 0; i < level; i++) {
groupAll += groupParent[i];
if (collapsedGroups[groupAll]) {
return;
}
}
groupAll += group;
if ((typeof (collapsedGroups[groupAll]) == 'undefined') || (collapsedGroups[groupAll] === null)) {
if (level === 3) {
collapsedGroups[groupAll] = true;
} else {
collapsedGroups[groupAll] = false;
}
} //True = Start collapsed. False = Start expanded.
var collapsed = collapsedGroups[groupAll];
rows.nodes().each(function (r) {
r.style.display = (collapsed ? 'none' : '');
});
if (level === 0) {
name = 'Смена №';
$scope.opened = '';
$scope.closed = '';
$scope.total_item_count = 0;
$scope.total_item_real_price = 0;
$scope.total_item_sale_price = 0;
$scope.total_item_special_price = 0;
$scope.total_item_cash = 0;
$scope.total_item_credit = 0;
$scope.total_item_clearing = 0;
$scope.total_item_presale = 0;
$scope.total_item_discount_sum = 0;
rows.rows().data().filter(function (value, index) {
if (parseInt(value['shift_id']) === parseInt(groupAll)) {
$scope.opened = value['shift_opened'];
$scope.closed = value['shift_closed'];
if (rows.rows(index, {page: 'current'}).data()[0]) {
$scope.total_item_count += value['item_count'];
$scope.total_item_real_price += value['item_real_price'];
$scope.total_item_sale_price += value['item_sale_price'];
$scope.total_item_special_price += value['item_special_price'];
$scope.total_item_cash += value['item_cash'];
$scope.total_item_credit += value['item_credit'];
$scope.total_item_clearing += value['item_clearing'];
$scope.total_item_presale += value['item_presale'];
$scope.total_item_discount_sum += value['item_discount_sum'];
}
}
});
return $('<tr/>')
.append('<td colspan="5">' + name + group + ' ' + '<small>(Открыта: ' + $scope.opened + ' Закрыта: ' + $scope.closed + ')</small></td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 3, '', '').display($scope.total_item_count) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_real_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_sale_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_special_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_cash) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_credit) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_presale) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_clearing) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_discount_sum) + '</td>')
.append('<td colspan="1"/>')
.attr('data-name', groupAll)
.toggleClass('collapsed', collapsed);
}
if (level === 1) {
$scope.total_item_count = 0;
$scope.total_item_real_price = 0;
$scope.total_item_sale_price = 0;
$scope.total_item_special_price = 0;
$scope.total_item_cash = 0;
$scope.total_item_credit = 0;
$scope.total_item_clearing = 0;
$scope.total_item_presale = 0;
$scope.total_item_discount_sum = 0;
rows.rows().data().filter(function (value, index) {
if (value['shift_id'] + value['place_name'] === groupAll) {
if (rows.rows(index, {page: 'current'}).data()[0]) {
$scope.total_item_count += value['item_count'];
$scope.total_item_real_price += value['item_real_price'];
$scope.total_item_sale_price += value['item_sale_price'];
$scope.total_item_special_price += value['item_special_price'];
$scope.total_item_cash += value['item_cash'];
$scope.total_item_credit += value['item_credit'];
$scope.total_item_clearing += value['item_clearing'];
$scope.total_item_presale += value['item_presale'];
$scope.total_item_discount_sum += value['item_discount_sum'];
}
}
});
return $('<tr/>')
.append('<td colspan="5">' + name + group + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 3, '', '').display($scope.total_item_count) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_real_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_sale_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_special_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_cash) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_credit) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_presale) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_clearing) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_discount_sum) + '</td>')
.append('<td colspan="1"/>')
.attr('data-name', groupAll)
.toggleClass('collapsed', collapsed);
}
if (level === 2) {
name = 'Стол №';
$scope.total_item_count = 0;
$scope.total_item_real_price = 0;
$scope.total_item_sale_price = 0;
$scope.total_item_special_price = 0;
$scope.total_item_cash = 0;
$scope.total_item_credit = 0;
$scope.total_item_clearing = 0;
$scope.total_item_presale = 0;
$scope.total_item_discount_sum = 0;
rows.rows().data().filter(function (value, index) {
if (value['shift_id'] + value['place_name'] + value['table_name'] === groupAll) {
if (rows.rows(index, {page: 'current'}).data()[0]) {
$scope.total_item_count += value['item_count'];
$scope.total_item_real_price += value['item_real_price'];
$scope.total_item_sale_price += value['item_sale_price'];
$scope.total_item_special_price += value['item_special_price'];
$scope.total_item_cash += value['item_cash'];
$scope.total_item_credit += value['item_credit'];
$scope.total_item_clearing += value['item_clearing'];
$scope.total_item_presale += value['item_presale'];
$scope.total_item_discount_sum += value['item_discount_sum'];
}
}
});
return $('<tr/>')
.append('<td colspan="5">' + name + group + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 3, '', '').display($scope.total_item_count) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_real_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_sale_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_special_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_cash) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_credit) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_presale) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_clearing) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_discount_sum) + '</td>')
.append('<td colspan="1"/>')
.attr('data-name', groupAll)
.toggleClass('collapsed', collapsed);
}
if (level === 3) {
name = 'Заказ №';
check_text = ' Чек №'
$scope.total_item_count = 0;
$scope.total_item_real_price = 0;
$scope.total_item_sale_price = 0;
$scope.total_item_special_price = 0;
$scope.total_item_cash = 0;
$scope.total_item_credit = 0;
$scope.total_item_clearing = 0;
$scope.total_item_presale = 0;
$scope.total_item_discount_sum = 0;
rows.rows().data().filter(function (value, index) {
if (value['shift_id'] + value['place_name'] + value['table_name'] + value['order_code'] === groupAll) {
$scope.opened = value['order_opened'];
$scope.closed = value['order_closed'];
$scope.check_number = value['order_check_number'];
if (rows.rows(index, {page: 'current'}).data()[0]) {
$scope.total_item_count += value['item_count'];
$scope.total_item_real_price += value['item_real_price'];
$scope.total_item_sale_price += value['item_sale_price'];
$scope.total_item_special_price += value['item_special_price'];
$scope.total_item_cash += value['item_cash'];
$scope.total_item_credit += value['item_credit'];
$scope.total_item_clearing += value['item_clearing'];
$scope.total_item_presale += value['item_presale'];
$scope.total_item_discount_sum += value['item_discount_sum'];
}
}
});
return $('<tr/>')
.append('<td colspan="5">' + name + group + ' ' + '<small>(Открыт: ' + $scope.opened + ' Закрыт: ' + $scope.closed + ($scope.check_number === 0 ? '' : check_text + $scope.check_number) + ')</small></td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 3, '', '').display($scope.total_item_count) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_real_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_sale_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_special_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_cash) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_credit) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_presale) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_clearing) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_discount_sum) + '</td>')
.append('<td colspan="1"/>')
.attr('data-name', groupAll)
.toggleClass('collapsed', collapsed);
}
},
initComplete: function () {
counter = 1;
}
}
}).on('draw', function () {
$('#preload-modal').modal('hide');
counter = 1;
});
$('#table_orders tbody').on('click', 'tr.dtrg-start', function () {
var name = $(this).data('name');
collapsedGroups[name] = !collapsedGroups[name];
$scope.table.draw(false);
});
};
$scope.reportRealisationConstruct = function () {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=report_construct&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.construct_data = data.data;
$scope.drawTable($scope.construct_data);
$scope.update();
Notification.success('Отчет сформирован, ожидайте загрузки!');
$('#report-construct').modal();
});
};
function getEndingDigit(inputString) {
const regex = /\d+$/;
if (regex.test(inputString)) {
const match = inputString.match(regex);
return match[0].replace(/\D/g, '');
}
return null;
}
function autofitColumns(worksheet) {
let objectMaxLength = [];
const letters = [];
const [startLetter, endLetter] = worksheet['!ref']?.replace(/\d/, '').split(':');
const startCode = startLetter.charCodeAt(0);
const endCode = endLetter.charCodeAt(0) + 1;
for (let code = startCode; code < endCode; code++) {
const letter = String.fromCharCode(code);
letters.push(letter);
}
letters.forEach((c) => {
const cellHeader = c;
const maxCellLengthForWholeColumn = Array.from(
{length: getEndingDigit(worksheet['!ref'])},
(_, i) => i
).reduce((acc, i) => {
const cell = worksheet[`${cellHeader}${i + 1}`];
if (!cell) return acc;
const charLength = cell.v.length + 1;
return acc > charLength ? acc : charLength;
}, 0);
objectMaxLength.push({width: maxCellLengthForWholeColumn + 2});
});
worksheet['!cols'] = objectMaxLength;
return worksheet;
}
$scope.exportTableToExcel = function (tableID, filename = 'table') {
const table = document.getElementById(tableID);
const wb = XLSX.utils.table_to_book(table, {raw: true, sheet: 'SheetJS'});
let ws = wb.Sheets['SheetJS'];
ws = autofitColumns(ws);
console.log(ws);
// Set date and time format for the 4th column (index 3)
const dateFormat = 'yyyy-mm-dd hh:mm:ss';
const range = XLSX.utils.decode_range(ws['!ref']);
for (let row = range.s.r; row <= range.e.r; row++) {
const cellRef = XLSX.utils.encode_cell({r: row, c: 3}); // 4th column (index 3)
const cell = ws[cellRef];
if (cell && cell.t === 'n' && isExcelDate(cell.v)) {
cell.z = dateFormat;
}
}
const firstRowRange = {s: {r: 0, c: range.s.c}, e: {r: 0, c: range.e.c}};
for (let rowNum = firstRowRange.s.r; rowNum <= firstRowRange.e.r; rowNum++) {
for (let colNum = firstRowRange.s.c; colNum <= firstRowRange.e.c; colNum++) {
const cellAddress = XLSX.utils.encode_cell({r: rowNum, c: colNum});
const cell = ws[cellAddress];
if (cell && cell.s) {
cell.s.fill = {
fgColor: {rgb: "FFFF00"}
};
}
}
}
const wbout = XLSX.write(wb, {bookType: 'xlsx', type: 'array', cellStyles: true});
const blob = new Blob([wbout], {type: 'application/octet-stream'});
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = `${filename}.xlsx`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
function isExcelDate(value) {
return value >= 0 && value < 2958466.99999999;
}
$scope.reportStatistic = function () {
smartRequest.get('v1/datareport?type=statistic&start_date=' + encodeURIComponent($scope.start_date) + '&end_date=' + encodeURIComponent($scope.end_date), function (data) {
$scope.fiscal = data.fiscal;
@@ -206,6 +662,9 @@
case 'realisation':
$scope.reportRealisation();
break;
case 'reportRealisationConstruct':
$scope.reportRealisationConstruct();
break;
case 'statistics':
$scope.reportStatistic();
break;

View File

@@ -23,7 +23,7 @@
$scope.getRoomMap = function () {
smartRequest.get('v1/roommap?type=full', function (data) {
smartRequest.get('v1/roommap?method=map&type=full', function (data) {
$('#back').hide();
$('#save_tables').hide();
$('#save_places').hide();
@@ -94,7 +94,7 @@
$scope.windowWidth = window.innerWidth;
$scope.screenWidth = 69;
smartRequest.get('v1/roommap?type=place&id=' + place_id, function (data) {
smartRequest.get('v1/roommap?method=map&type=place&id=' + place_id, function (data) {
$scope.place = data.place;
$scope.place_id = data.place_id;
$scope.left = document.getElementById('tables').getBoundingClientRect().left;

View File

@@ -20,14 +20,14 @@
ShiftsCtrl.$inject = ['$scope', '$filter', 'smartRequest', 'Notification'];
function ShiftsCtrl($scope, $filter, smartRequest, Notification) {
Number.prototype.toDivide = function() {
Number.prototype.toDivide = function () {
var float = String(this.toFixed(2));
if(float.length <= 6) return float;
if (float.length <= 6) return float;
var space = 0;
var number = '';
for(var i = float.length - 1; i >= 0; i--) {
if(space == 3) {
for (var i = float.length - 1; i >= 0; i--) {
if (space == 3) {
number = ' ' + number;
space = 0;
}
@@ -154,6 +154,8 @@
};
$scope.reportDiscounts = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=discounts&shift_id=' + shift.id, function (data) {
$scope.orders_info = data.orders_info;
$scope.orders_count = data.orders_count;
@@ -162,45 +164,60 @@
$scope.orders_order_sum = data.orders_order_sum;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#report-discounts').modal();
$('#preload-modal').modal('hide');
$scope.update();
$('#report-discounts').modal();
});
};
$scope.reportMerged = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=merge&shift_id=' + shift.id, function (data) {
$scope.report_merge = data.data;
$scope.report_merge.count = data.count;
$scope.report_merge.shift_id = data.shift_id;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#preload-modal').modal('hide');
$scope.update();
$('#report-merge').modal();
});
};
$scope.reportMoved = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=move&shift_id=' + shift.id, function (data) {
$scope.report_move = data.data;
$scope.report_move.count = data.count;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#preload-modal').modal('hide');
$scope.update();
$('#report-move').modal();
});
};
$scope.reportSliced = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=slice&shift_id=' + shift.id, function (data) {
$scope.report_slice = data.data;
$scope.report_slice.count = data.count;
$scope.report_slice.shift_id = data.shift_id;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#preload-modal').modal('hide');
$scope.update();
$('#report-slice').modal();
});
};
$scope.reportDelete = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=deleted&shift_id=' + shift.id, function (data) {
if (data.totalCount > 0) {
$scope.report_delete = data.orders;
@@ -209,7 +226,7 @@
$scope.shift_id = shift.id;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#preload-modal').modal('hide');
$scope.update();
$('#shift-delete').modal();
@@ -221,6 +238,8 @@
};
$scope.reportRealisation = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=realisation&shift_id=' + shift.id, function (data) {
$scope.report_realisation = data.printers;
$scope.return_printers = data.ret_prints;
@@ -229,13 +248,424 @@
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#preload-modal').modal('hide');
$scope.update();
$('#report-realisation').modal();
});
};
$scope.draw_counter = 0;
$scope.drawTable = function (data) {
var collapsedGroups = [];
var groupParent = [];
var counter = 1;
$.fn.dataTable.moment('YYYY-MM-DD HH:mm:ss');
$scope.table = $('#table_orders').DataTable({
data: data,
destroy: true,
columns: [
{data: 'shift_id', title: 'Смена'},//hide
{data: 'work_place', title: 'Раб.место'},//hide
{data: 'place_name', title: 'Зал'},//hide
{data: 'table_name', title: 'Стол'},//hide
{
data: 'staff_name',
title: 'Смена/Зал/Стол/Заказ/Персонал',
searchBuilderTitle: 'Персонал',
class: 'order_id'
},
{data: 'client_name', title: 'Клиент', class: 'order_id'},
{data: 'item_name', title: 'Товар'},
{data: 'order_code', title: 'Заказ'},//hide
{data: 'item_time', title: 'Время'},
{
data: 'printer_name',
title: 'МП',
searchBuilderTitle: 'Место приготовления',
class: 'order_id'
},
{
data: 'item_count',
title: 'Кол-во',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 3, '', '').display(data);
}
},
{data: 'item_real_price', title: 'Цена',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{data: 'item_sale_price', title: 'Сумма',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{data: 'item_special_price', title: 'Себест.', searchBuilderTitle: 'Себестоимость'},
{
data: 'item_cash',
title: 'Нал.', searchBuilderTitle: 'Оплата наличными',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{
data: 'item_credit',
title: 'Кред.карта', searchBuilderTitle: 'Оплата кредитной картой',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{
data: 'item_presale',
title: 'Аванс', searchBuilderTitle: 'Зачет аванса',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{data: 'item_clearing', title: 'Б/н', searchBuilderTitle: 'Оплата безналичными',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{data: 'item_discount_sum', title: 'Скидка, BYN', searchBuilderTitle: 'Сумма скидки',
render: function (data, type, row) {
return DataTable.render.number(' ', '.', 2, '', '').display(data);
}
},
{data: 'item_discount_value', title: 'Скидка, %', searchBuilderTitle: '% скидки'},
{data: 'order_opened', title: 'Время открытия заказа', searchBuilderTitle: 'Время открытия заказа'},//hide
{data: 'order_closed', title: 'Время закрытия заказа', searchBuilderTitle: 'Время закрытия заказа'},//hide
{data: 'order_check_number', searchBuilderTitle: 'Номер чека'},//hide
{data: 'shift_opened', title: 'Время открытия смены', searchBuilderTitle: 'Время открытия смены'},//hide
{data: 'shift_closed', title: 'Время закрытия смены', searchBuilderTitle: 'Время закрытия смены'},//hide
],
order: [[0, 'asc'], [1, 'asc'], [2, 'asc'], [3, 'asc'], [7, 'asc']],
columnDefs: [{
targets: [0, 1, 2, 3, 7, 20, 21, 22, 23, 24],
visible: false
}],
stripeClasses: [],
fixedHeader: true,
scrollCollapse: false,
paging: false,
searching: true,
responsive: false,
processing: true,
dom: 'QBfrtip',
searchBuilder: {
columns: [0, 2, 3, 4, 5, 6, 7, 8, 9, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
},
buttons: [{
text: 'Excel',
action: function (e, dt, node, conf) {
$scope.exportTableToExcel('table_orders', 'extend-realisation');
}
}],
language: {
url: "https://cdn.datatables.net/plug-ins/1.13.3/i18n/ru.json",
},
rowGroup: {
dataSrc: ['shift_id', 'place_name', 'table_name', 'order_code'],
startRender: function (rows, group, level) {
groupParent[level] = group;
var groupAll = '';
var name = '';
var check_text = '';
$scope.opened = '';
$scope.closed = '';
$scope.check_number = null;
$scope.total_item_count = 0;
$scope.total_item_real_price = 0;
$scope.total_item_sale_price = 0;
$scope.total_item_special_price = 0;
$scope.total_item_cash = 0;
$scope.total_item_credit = 0;
$scope.total_item_clearing = 0;
$scope.total_item_presale = 0;
$scope.total_item_discount_sum = 0;
for (var i = 0; i < level; i++) {
groupAll += groupParent[i];
if (collapsedGroups[groupAll]) {
return;
}
}
groupAll += group;
if ((typeof (collapsedGroups[groupAll]) == 'undefined') || (collapsedGroups[groupAll] === null)) {
if (level === 3) {
collapsedGroups[groupAll] = true;
} else {
collapsedGroups[groupAll] = false;
}
} //True = Start collapsed. False = Start expanded.
var collapsed = collapsedGroups[groupAll];
rows.nodes().each(function (r) {
r.style.display = (collapsed ? 'none' : '');
});
if (level === 0) {
name = 'Смена №';
rows.rows().data().filter(function (value, index) {
if (parseInt(value['shift_id']) === parseInt(groupAll)) {
$scope.opened = $scope.start_date;
$scope.closed = $scope.end_date;
if (rows.rows(index, {page: 'current'}).data()[0]) {
$scope.total_item_count += value['item_count'];
$scope.total_item_real_price += value['item_real_price'];
$scope.total_item_sale_price += value['item_sale_price'];
$scope.total_item_special_price += value['item_special_price'];
$scope.total_item_cash += value['item_cash'];
$scope.total_item_credit += value['item_credit'];
$scope.total_item_clearing += value['item_clearing'];
$scope.total_item_presale += value['item_presale'];
$scope.total_item_discount_sum += value['item_discount_sum'];
}
}
});
return $('<tr/>')
.append('<td colspan="5">' + name + group + ' ' + '<small>(Открыта: ' + $scope.opened + ' Закрыта: ' + $scope.closed + ')</small></td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 3, '', '').display($scope.total_item_count) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_real_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_sale_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_special_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_cash) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_credit) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_presale) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_clearing) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_discount_sum) + '</td>')
.append('<td colspan="1"/>')
.attr('data-name', groupAll)
.toggleClass('collapsed', collapsed);
}
if (level === 1) {
rows.rows().data().filter(function (value, index) {
if (value['shift_id'] + value['place_name'] === groupAll) {
if (rows.rows(index, {page: 'current'}).data()[0]) {
$scope.total_item_count += value['item_count'];
$scope.total_item_real_price += value['item_real_price'];
$scope.total_item_sale_price += value['item_sale_price'];
$scope.total_item_special_price += value['item_special_price'];
$scope.total_item_cash += value['item_cash'];
$scope.total_item_credit += value['item_credit'];
$scope.total_item_clearing += value['item_clearing'];
$scope.total_item_presale += value['item_presale'];
$scope.total_item_discount_sum += value['item_discount_sum'];
}
}
})
return $('<tr/>')
.append('<td colspan="5">' + name + group + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 3, '', '').display($scope.total_item_count) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_real_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_sale_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_special_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_cash) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_credit) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_presale) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_clearing) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_discount_sum) + '</td>')
.append('<td colspan="1"/>')
.attr('data-name', groupAll)
.toggleClass('collapsed', collapsed);
}
if (level === 2) {
name = 'Стол №';
rows.rows().data().filter(function (value, index) {
if (value['shift_id'] + value['place_name'] + value['table_name'] === groupAll) {
if (rows.rows(index, {page: 'current'}).data()[0]) {
$scope.total_item_count += value['item_count'];
$scope.total_item_real_price += value['item_real_price'];
$scope.total_item_sale_price += value['item_sale_price'];
$scope.total_item_special_price += value['item_special_price'];
$scope.total_item_cash += value['item_cash'];
$scope.total_item_credit += value['item_credit'];
$scope.total_item_clearing += value['item_clearing'];
$scope.total_item_presale += value['item_presale'];
$scope.total_item_discount_sum += value['item_discount_sum'];
}
}
});
return $('<tr/>')
.append('<td colspan="5">' + name + group + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 3, '', '').display($scope.total_item_count) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_real_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_sale_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_special_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_cash) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_credit) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_presale) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_clearing) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_discount_sum) + '</td>')
.append('<td colspan="1"/>')
.attr('data-name', groupAll)
.toggleClass('collapsed', collapsed);
}
if (level === 3) {
name = 'Заказ №';
check_text = ' Чек №'
rows.rows().data().filter(function (value, index) {
if (value['shift_id'] + value['place_name'] + value['table_name'] + value['order_code'] === groupAll) {
if (rows.rows(index, {page: 'current'}).data()[0]) {
$scope.opened = value['order_opened'];
$scope.closed = value['order_closed'];
$scope.check_number = value['order_check_number'];
$scope.total_item_count += value['item_count'];
$scope.total_item_real_price += value['item_real_price'];
$scope.total_item_sale_price += value['item_sale_price'];
$scope.total_item_special_price += value['item_special_price'];
$scope.total_item_cash += value['item_cash'];
$scope.total_item_credit += value['item_credit'];
$scope.total_item_clearing += value['item_clearing'];
$scope.total_item_presale += value['item_presale'];
$scope.total_item_discount_sum += value['item_discount_sum'];
}
}
});
return $('<tr/>')
.append('<td colspan="5">' + name + group + ' ' + '<small>(Открыт: ' + $scope.opened + ' Закрыт: ' + $scope.closed + ($scope.check_number === 0 ? '' : check_text + $scope.check_number) + ')</small></td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 3, '', '').display($scope.total_item_count) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_real_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_sale_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_special_price) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_cash) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_credit) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_presale) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_clearing) + '</td>')
.append('<td colspan="1">' + DataTable.render.number(' ', '.', 2, '', '').display($scope.total_item_discount_sum) + '</td>')
.append('<td colspan="1"/>')
.attr('data-name', groupAll)
.toggleClass('collapsed', collapsed);
}
},
initComplete: function () {
counter = 1;
}
}
}).on('draw', function () {
$('#preload-modal').modal('hide');
counter = 1;
});
$('#table_orders tbody').on('click', 'tr.dtrg-start', function () {
var name = $(this).data('name');
collapsedGroups[name] = !collapsedGroups[name];
$scope.table.draw(false);
});
};
$scope.reportRealisationConstruct = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=report_construct&shift_id=' + shift.id, function (data) {
$scope.construct_data = data.data;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$scope.drawTable($scope.construct_data);
$scope.update();
$('#report-construct').modal();
});
};
function getEndingDigit(inputString) {
const regex = /\d+$/;
if (regex.test(inputString)) {
const match = inputString.match(regex);
return match[0].replace(/\D/g, '');
}
return null;
}
function autofitColumns(worksheet) {
let objectMaxLength = [];
const letters = [];
const [startLetter, endLetter] = worksheet['!ref']?.replace(/\d/, '').split(':');
const startCode = startLetter.charCodeAt(0);
const endCode = endLetter.charCodeAt(0) + 1;
for (let code = startCode; code < endCode; code++) {
const letter = String.fromCharCode(code);
letters.push(letter);
}
letters.forEach((c) => {
const cellHeader = c;
const maxCellLengthForWholeColumn = Array.from(
{length: getEndingDigit(worksheet['!ref'])},
(_, i) => i
).reduce((acc, i) => {
const cell = worksheet[`${cellHeader}${i + 1}`];
if (!cell) return acc;
const charLength = cell.v.length + 1;
return acc > charLength ? acc : charLength;
}, 0);
objectMaxLength.push({width: maxCellLengthForWholeColumn + 2});
});
worksheet['!cols'] = objectMaxLength;
return worksheet;
}
$scope.exportTableToExcel = function (tableID, filename = 'table') {
const table = document.getElementById(tableID);
const wb = XLSX.utils.table_to_book(table, {raw: true, sheet: 'SheetJS'});
let ws = wb.Sheets['SheetJS'];
ws = autofitColumns(ws);
console.log(ws);
// Set date and time format for the 4th column (index 3)
const dateFormat = 'yyyy-mm-dd hh:mm:ss';
const range = XLSX.utils.decode_range(ws['!ref']);
for (let row = range.s.r; row <= range.e.r; row++) {
const cellRef = XLSX.utils.encode_cell({r: row, c: 3}); // 4th column (index 3)
const cell = ws[cellRef];
if (cell && cell.t === 'n' && isExcelDate(cell.v)) {
cell.z = dateFormat;
}
}
const firstRowRange = {s: {r: 0, c: range.s.c}, e: {r: 0, c: range.e.c}};
for (let rowNum = firstRowRange.s.r; rowNum <= firstRowRange.e.r; rowNum++) {
for (let colNum = firstRowRange.s.c; colNum <= firstRowRange.e.c; colNum++) {
const cellAddress = XLSX.utils.encode_cell({r: rowNum, c: colNum});
const cell = ws[cellAddress];
if (cell && cell.s) {
cell.s.fill = {
fgColor: {rgb: "FFFF00"}
};
}
}
}
const wbout = XLSX.write(wb, {bookType: 'xlsx', type: 'array', cellStyles: true});
const blob = new Blob([wbout], {type: 'application/octet-stream'});
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = `${filename}.xlsx`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
function isExcelDate(value) {
return value >= 0 && value < 2958466.99999999;
}
$scope.reportStatistic = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=statistic&shift_id=' + shift.id, function (data) {
$scope.fiscal = data.fiscal;
$scope.realisation = data.realisation;
@@ -246,43 +676,51 @@
$scope.payments = data.payments;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#preload-modal').modal('hide');
$scope.update();
$('#report-statistic').modal();
});
};
$scope.reportStaff = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=staff&shift_id=' + shift.id, function (data) {
$scope.staffs = data.staffs;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#preload-modal').modal('hide');
$scope.update();
$('#report-staff').modal();
});
};
$scope.reportPay = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/datareport?type=payment&shift_id=' + shift.id, function (data) {
$scope.printers = data.items;
$scope.start_date = shift.opened;
$scope.end_date = shift.closed;
$('#preload-modal').modal('hide');
$scope.update();
$('#report-payment').modal();
});
};
$scope.reportOut = function (shift) {
$('#preload-modal').modal();
Notification.primary('Отчет формируется. Пожалуйста, дождитесь загрузки!');
smartRequest.get('v1/outorders?shift_id=' + shift.id, function (data) {
$scope.response = data.message;
if (data.message == 'false') {
Notification.error('Внешние заказы не найдены');
$('#preload-modal').modal('hide');
} else {
$scope.orders = data.orders;
$scope.shift = data.shift;
$scope.total = data.total;
$('#preload-modal').modal('hide');
$scope.update();
$('#report-out').modal();
}
@@ -305,6 +743,7 @@
}
if ($scope.status == 'error') {
Notification.error(data.message);
$('#preload-modal').modal('hide');
}
});
};

View File

@@ -1,183 +1,202 @@
(function () {
'use strict';
angular
.module('app')
.controller('TerminalsCtrl', TerminalsCtrl);
'use strict';
angular
.module('app')
.controller('TerminalsCtrl', TerminalsCtrl);
TerminalsCtrl.$inject = ['$scope', 'smartRequest', 'Notification'];
function TerminalsCtrl($scope, smartRequest, Notification) {
$scope.terminals = [];
$scope.tasks = [];
$scope.printers = [];
TerminalsCtrl.$inject = ['$scope', 'smartRequest', 'Notification'];
$scope.settings = {
sizes: [56, 80],
speeds: [4800, 9600, 19200, 38400, 57600, 115200],
types: ['COM', 'LAN', 'Windows'],
com_ports: ['COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'COM10']
};
function TerminalsCtrl($scope, smartRequest, Notification) {
$scope.terminals = [];
$scope.tasks = [];
$scope.printers = [];
$scope.terminal_id = 0;
$scope.active_tasks = [];
$scope.settings = {
sizes: [56, 80],
speeds: [4800, 9600, 19200, 38400, 57600, 115200],
types: ['COM', 'LAN', 'Windows'],
com_ports: ['COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'COM10']
};
$scope.terminalLogs = [];
$scope.terminal_id = 0;
$scope.active_tasks = [];
$scope.update = function () {
smartRequest.get('v1/settings?method=terminals', function (data) {
$scope.terminals = data.terminals;
});
};
$scope.terminalLogs = [];
$scope.update();
$scope.update = function () {
smartRequest.get('v1/settings?method=terminals', function (data) {
$scope.terminals = data.terminals;
});
};
$scope.onLicence = function (key, active) {
if (active === false) {
smartRequest.post('licence/reject', {
'key': key
},
function () {
$scope.update();
},
function () {
$scope.update();
});
}
else {
smartRequest.post('licence/apply', {
'key': key
},
function () {
$scope.update();
},
function () {
$scope.update();
});
}
$scope.update();
};
$scope.onLicence = function (key, active) {
if (active === false) {
smartRequest.post('licence/reject', {
'key': key
},
function () {
$scope.update();
},
function () {
$scope.update();
});
} else {
smartRequest.post('licence/apply', {
'key': key
},
function () {
$scope.update();
},
function () {
$scope.update();
});
}
$scope.isTaskActive = function (task) {
for (var i = 0; i < $scope.active_tasks.length; i++) {
if (task.code == $scope.active_tasks[i].code) {
return false;
}
}
};
return true;
};
$scope.isTaskActive = function (task) {
for (var i = 0; i < $scope.active_tasks.length; i++) {
if (task.code == $scope.active_tasks[i].code) {
return false;
}
}
$scope.editTerminal = function (id) {
$scope.terminal_id = id;
return true;
};
smartRequest.get('settings/update/list', function (data) {
for (var i = 0; i < data.update_list.length; i++) {
data.update_list[i].active = false;
data.update_list[i].period = parseInt(data.update_list[i].default);
}
$scope.editTerminal = function (id) {
$scope.terminal_id = id;
$scope.all_tasks = data.update_list;
});
smartRequest.get('settings/update/list', function (data) {
for (var i = 0; i < data.update_list.length; i++) {
data.update_list[i].active = false;
data.update_list[i].period = parseInt(data.update_list[i].default);
}
smartRequest.get('settings/update/active?terminal=' + id, function (data) {
for (var i = 0; i < data.update_list.length; i++) {
data.update_list[i].active = true;
data.update_list[i].period = parseInt(data.update_list[i].period);
}
$scope.all_tasks = data.update_list;
});
$scope.active_tasks = data.update_list;
$('#edit-terminal').modal();
});
};
smartRequest.get('settings/update/active?terminal=' + id, function (data) {
for (var i = 0; i < data.update_list.length; i++) {
data.update_list[i].active = true;
data.update_list[i].period = parseInt(data.update_list[i].period);
}
$scope.getEquipment = function (id) {
smartRequest.get('v1/equipment?terminal=' + id, function (data) {
$scope.printers = data.printers;
$scope.groups = data.printer_groups;
$scope.terminal_id = id;
});
$('#equipment').modal();
};
$scope.active_tasks = data.update_list;
$('#edit-terminal').modal();
});
};
$scope.updateEquipment = function (printer) {
smartRequest.post('v1/printers', {
terminal: $scope.terminal_id,
id: printer.id,
name: printer.name,
ip_address: printer.ip,
com_port: printer.com_port,
type: printer.type,
speed: printer.speed,
group: printer.printer_group,
template: printer.template,
size: printer.size,
driver: printer.driver,
more: printer.more
}, function(data) {
Notification.success('Данные принтера сохранены');
});
};
$scope.updateFiscal = function (fiscal) {
smartRequest.post('v1/fiscals', {
terminal: $scope.terminal_id,
pass: fiscal.password,
ip: fiscal.ip
}, function(data) {
Notification.success('Данные ФР изменены');
});
};
$scope.getEquipment = function (id) {
smartRequest.get('v1/equipment?terminal=' + id, function (data) {
$scope.printers = data.printers;
$scope.groups = data.printer_groups;
$scope.terminal_id = id;
});
$('#equipment').modal();
};
$scope.addTask = function () {
smartRequest.get('settings/equipment/task?terminal=' + $scope.terminal_id, function (data) {
Notification.success('Задача запушена');
});
};
$scope.updateEquipment = function (printer) {
smartRequest.post('v1/printers', {
terminal: $scope.terminal_id,
id: printer.id,
name: printer.name,
ip_address: printer.ip,
com_port: printer.com_port,
type: printer.type,
speed: printer.speed,
group: printer.printer_group,
template: printer.template,
size: printer.size,
driver: printer.driver,
more: printer.more
$scope.objectHasProperty = function (object, name) {
return object.hasOwnProperty(name);
};
}, function (data) {
Notification.success('Данные принтера сохранены');
});
};
$scope.changeTask = function (task) {
if (task.active) {
smartRequest.post('settings/update/enable', {
terminal: $scope.terminal_id,
task: task.code,
period: task.period
});
}
else {
smartRequest.post('settings/update/disable', {
terminal: $scope.terminal_id,
task: task.code
});
}
};
$scope.updateFiscal = function (fiscal) {
smartRequest.post('v1/fiscals', {
terminal: $scope.terminal_id,
pass: fiscal.password,
ip: fiscal.ip
}, function (data) {
Notification.success('Данные ФР изменены');
});
};
$scope.changePeriod = function (task) {
if (task.active) {
smartRequest.post('settings/update/enable', {
terminal: $scope.terminal_id,
task: task.code,
period: task.period
});
}
};
$scope.addTask = function () {
smartRequest.get('settings/equipment/task?terminal=' + $scope.terminal_id, function (data) {
Notification.success('Задача запушена');
});
};
$scope.runTask = function (task) {
smartRequest.post('settings/update/force', {
terminal: $scope.terminal_id,
task: task.code
}, function (data) {
Notification.success('Задача запущена');
});
};
$scope.objectHasProperty = function (object, name) {
return object.hasOwnProperty(name);
};
$scope.showLogs = function (terminal_key) {
smartRequest.get('settings/terminal/logs?terminal=' + terminal_key, function (data) {
$scope.terminalLogs = data.logs;
$('#logs').modal();
});
};
}
$scope.changeTask = function (task) {
if (task.active) {
smartRequest.post('settings/update/enable', {
terminal: $scope.terminal_id,
task: task.code,
period: task.period
});
} else {
smartRequest.post('settings/update/disable', {
terminal: $scope.terminal_id,
task: task.code
});
}
};
$scope.changePeriod = function (task) {
if (task.active) {
smartRequest.post('settings/update/enable', {
terminal: $scope.terminal_id,
task: task.code,
period: task.period
});
}
};
$scope.runTask = function (task) {
smartRequest.post('settings/update/force', {
terminal: $scope.terminal_id,
task: task.code
}, function (data) {
Notification.success('Задача запущена');
});
};
$scope.updateTerminal = function (terminal) {
var info = JSON.stringify({
id: terminal.id,
name: terminal.newName,
work_code: terminal.work_code,
work_group: terminal.work_group,
soft: terminal.soft,
is_active: terminal.is_active,
key: terminal.key,
last_activity: terminal.last_activity
});
smartRequest.post('v1/terminals', {
method: 'update',
data: btoa(info)
}, function (data) {
Notification.success('Наименование рабочей группы изменено');
$scope.update();
});
};
$scope.showLogs = function (terminal_key) {
smartRequest.get('settings/terminal/logs?terminal=' + terminal_key, function (data) {
$scope.terminalLogs = data.logs;
$('#logs').modal();
});
};
}
})();

View File

@@ -20,6 +20,13 @@ item: [
icon: 'dashboard',
order: 0
},
{
name: 'Монитор активности',
acl: 'activitymonitor',
url: 'app.activitymonitor',
icon: 'desktop_windows',
order: 0
},
{
name: 'Loyalty (dev)',
acl: 'loyalty',

View File

@@ -22,13 +22,21 @@
controller: 'OrdersCtrl',
resolve: ['scripts/controllers/orders.js']
},
{
code: 'app.activitymonitor',
url: '/v1/activitymonitor',
templateUrl: '../views/activitymonitor/index.html',
data: { title : 'Монитор активности' },
controller: 'ActivityMonitorCtrl',
resolve: ['scripts/controllers/activitymonitor.js']
},
{
code: 'app.roommap',
url: '/v1/roommap',
url: '/v1/roommap',
templateUrl: '../views/roommap/index.html',
data: { title : 'RoomMap' },
controller: 'RoommapCtrl',
resolve: ['scripts/controllers/roommap.js']
resolve: ['scripts/controllers/roommap.js']
},
{
code: 'app.loyalty',

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,102 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="backModal('order', 'orders')">
<i class="material-icons md-24">arrow_back</i>
</button>
<p style="margin-bottom: -0.1rem;">Номер заказа: <strong>#{{order.order_id}}</strong><br></p>
<p style="margin-bottom: -0.1rem;">Заказ размещен в зале "<strong>{{order.place}}</strong>" на столе №<strong>{{order.table}}</strong><br></p>
<p style="margin-bottom: -0.1rem;">Время открытия: <strong>{{order.opened}}</strong><br></p>
<p style="margin-bottom: -0.1rem;" ng-if="order.closed">Время закрытия: <strong>{{order.closed}}</strong><br></p>
<p style="margin-bottom: -0.1rem;">Заказ открыт пользователем: <strong>{{order.who_open}}</strong><br></p>
<p style="margin-bottom: -0.1rem;" ng-if="order.who_close">Заказ закрыт пользователем: <strong>{{order.who_close}}</strong><br></p>
<p style="margin-bottom: -0.1rem;">Статус заказа: <span class="label success">{{order.order_status}}</span><br></p>
</div>
<div class="modal-body p-lg">
<div class="table-responsive">
<table class="table table-striped white b-a">
<thead>
<tr>
<th>ID</th>
<th>Блюдо</th>
<th style="width: 80px">Кол-во</th>
<th style="width: 80px" ng-if="order.returned_count > 0">Кол-во возвр.</th>
<th style="width: 80px" ng-if="order.deleted_count > 0">Кол-во удал.</th>
<th style="width: 140px">Стоимость</th>
<th style="width: 180px">Итог</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in order.items">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.count * item.cof}}</td>
<td ng-if="order.returned_count > 0">{{item.returned_count * item.cof}}</td>
<td ng-if="order.deleted_count > 0">{{item.deleted_count * item.cof}}</td>
<td>{{item.price | curr}} BYN</td>
<td>{{item.amount | curr}} BYN <p ng-if="item.discount > 0">
<span>(Скидка: {{item.discount}}%)</span></p></td>
</tr>
<tr>
<td colspan="{{cols - 1}}" class="text-right">
<strong ng-if="order.returned_count > 0">Сумма</strong>
<strong ng-if="order.returned_count == 0">Итого</strong>
</td>
<td>{{order.amount | curr}} BYN</td>
</tr>
<tr>
<td colspan="{{cols - 1}}" class="text-right no-border" ng-if="order.full_price - order.amount > 0">
<strong>Сумма скидки</strong></td>
<td ng-if="order.full_price - order.amount > 0">{{order.full_price - order.amount | curr}} BYN
</td>
</tr>
<tr ng-if="order.cash > 0 || order.credit > 0 || order.clearing > 0 || order.presale > 0 || order.self > 0 || order.online > 0">
<td colspan="{{cols - 1}}" class="text-right no-border"><strong>Оплачено:</strong></td>
</tr>
<tr ng-if="order.cash > 0">
<td colspan="{{cols}}" class="text-right no-border">Наличные: <strong>{{order.cash
| curr}} BYN</strong></td>
</tr>
<tr ng-if="order.credit > 0">
<td colspan="{{cols}}" class="text-right no-border">Кред. карта: <strong>{{order.credit | curr}}
BYN</strong></td>
</tr>
<tr ng-if="order.clearing > 0">
<td colspan="{{cols}}" class="text-right no-border">Питание штата: <strong>{{order.clearing | curr}}
BYN</strong>
</tr>
<tr ng-if="order.presale > 0">
<td colspan="{{cols}}" class="text-right no-border">Зачтен аванс: <strong>{{order.presale | curr}}
BYN</strong></td>
</tr>
<tr ng-if="order.self > 0">
<td colspan="{{cols}}" class="text-right no-border">Безнал: <strong>{{order.self | curr}} BYN</strong>
</td>
</tr>
<tr ng-if="order.online > 0">
<td colspan="{{cols}}" class="text-right no-border">Онлайн: <strong>{{order.online | curr}} BYN</strong>
</td>
</tr>
<tr ng-if="order.returned_count > 0">
<td colspan="{{cols - 1}}" class="text-right"><strong>Возвращено:</strong></td>
</tr>
<tr ng-if="order.returned_method.cash > 0">
<td colspan="{{cols}}" class="text-right no-border">Наличные: <strong>{{order.returned_method.cash
| curr}} BYN</strong></td>
</tr>
<tr ng-if="order.returned_method.credit > 0">
<td colspan="{{cols}}" class="text-right no-border">Кред. карта: <strong>{{order.returned_method.credit | curr}}
BYN</strong></td>
</tr>
<tr ng-if="order.returned_count > 0">
<td colspan="{{cols - 1}}" class="text-right"><strong>Итого</strong></td>
<td>{{order.amount - order.returned_sum | curr}} BYN</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,232 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button ng-if="orders_modal" type="button" class="close" ng-click="backModal('order', 'orders')">
<i class="material-icons md-24">arrow_back</i>
</button>
<button ng-if="clients_modal" type="button" class="close" data-dismiss="modal">&times;</button>
<p style="margin-bottom: -0.1rem;">Номер заказа: <strong>#{{order.order_id}}</strong><br></p>
<p style="margin-bottom: -0.1rem;">Заказ размещен в зале "<strong>{{order.place}}</strong>" на столе
<strong>{{order.table}}</strong><br></p>
<p style="margin-bottom: -0.1rem;">Время открытия: <strong>{{order.opened}}</strong><br></p>
<p style="margin-bottom: -0.1rem;" ng-if="order.closed">Время закрытия:
<strong>{{order.closed}}</strong><br></p>
<p style="margin-bottom: -0.1rem;">Заказ открыт пользователем: <strong>{{order.who_open}}</strong><br></p>
<p style="margin-bottom: -0.1rem;" ng-if="order.who_close">Заказ закрыт пользователем: <strong>{{order.who_close}}</strong><br>
</p>
<p style="margin-bottom: -0.1rem;">Статус заказа: <span
class="label success">{{order.order_status}}</span><br></p>
</div>
<div class="modal-body p-lg">
<div>
<div class="b-b nav-active-bg">
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" href="" data-toggle="tab" data-target="#tab1"
aria-expanded="true">Заказ</a>
</li>
<li class="nav-item">
<a class="nav-link" href="" data-toggle="tab" data-target="#tab2" aria-expanded="false">Журнал
заказа</a>
</li>
<li class="nav-item" ng-if="actions.slice_trigger == 1">
<a class="nav-link" href="" data-toggle="tab" data-target="#tab3" aria-expanded="false">История
разбиения</a>
</li>
<li class="nav-item" ng-if="actions.merge_trigger == 1">
<a class="nav-link" href="" data-toggle="tab" data-target="#tab4" aria-expanded="false">История
объединения</a>
</li>
<li class="nav-item" ng-if="actions.move_trigger == 1">
<a class="nav-link" href="" data-toggle="tab" data-target="#tab5" aria-expanded="false">История
переноса</a>
</li>
</ul>
</div>
<div class="tab-content p-a m-b-md">
<div class="tab-pane animated fadeIn text-muted active" id="tab1" aria-expanded="true">
<!-- Заказ -->
<div class="table-responsive">
<table class="table table-striped white b-a">
<thead>
<tr>
<th>ID</th>
<th>Блюдо</th>
<th style="width: 80px">Кол-во</th>
<th style="width: 80px" ng-if="order.returned_count > 0">Кол-во возвр.</th>
<th style="width: 80px" ng-if="order.deleted_count > 0">Кол-во удал.</th>
<th style="width: 140px">Стоимость</th>
<th style="width: 180px">Итог</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in order.items">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.count * item.cof}}</td>
<td ng-if="order.returned_count > 0">{{item.returned_count * item.cof}}</td>
<td ng-if="order.deleted_count > 0">{{item.deleted_count * item.cof}}</td>
<td>{{item.price | curr}} BYN</td>
<td>{{item.amount | curr}} BYN <p ng-if="item.discount > 0">
<span>(Скидка: {{item.discount}}%)</span></p></td>
</tr>
<tr>
<td colspan="{{cols - 1}}" class="text-right">
<strong ng-if="order.returned_count > 0">Сумма</strong>
<strong ng-if="order.returned_count == 0">Итого</strong>
</td>
<td>{{order.amount | curr}} BYN</td>
</tr>
<tr>
<td colspan="{{cols - 1}}" class="text-right no-border"
ng-if="order.full_price - order.amount > 0">
<strong>Сумма скидки</strong></td>
<td ng-if="order.full_price - order.amount > 0">{{order.full_price - order.amount |
curr}} BYN
</td>
</tr>
<tr ng-if="order.cash > 0 || order.credit > 0 || order.clearing > 0 || order.presale > 0 || order.self > 0 || order.online > 0">
<td colspan="{{cols - 1}}" class="text-right no-border"><strong>Оплачено:</strong>
</td>
</tr>
<tr ng-if="order.cash > 0">
<td colspan="{{cols}}" class="text-right no-border">Наличные: <strong>{{order.cash
| curr}} BYN</strong></td>
</tr>
<tr ng-if="order.credit > 0">
<td colspan="{{cols}}" class="text-right no-border">Кред. карта: <strong>{{order.credit
| curr}}
BYN</strong></td>
</tr>
<tr ng-if="order.clearing > 0">
<td colspan="{{cols}}" class="text-right no-border">Питание штата: <strong>{{order.clearing
| curr}}
BYN</strong>
</tr>
<tr ng-if="order.presale > 0">
<td colspan="{{cols}}" class="text-right no-border">Зачтен аванс: <strong>{{order.presale
| curr}}
BYN</strong></td>
</tr>
<tr ng-if="order.self > 0">
<td colspan="{{cols}}" class="text-right no-border">Безнал: <strong>{{order.self |
curr}} BYN</strong>
</td>
</tr>
<tr ng-if="order.online > 0">
<td colspan="{{cols}}" class="text-right no-border">Онлайн: <strong>{{order.online |
curr}} BYN</strong>
</td>
</tr>
<tr ng-if="order.returned_count > 0">
<td colspan="{{cols - 1}}" class="text-right"><strong>Возвращено:</strong></td>
</tr>
<tr ng-if="order.returned_method.cash > 0">
<td colspan="{{cols}}" class="text-right no-border">Наличные: <strong>{{order.returned_method.cash
| curr}} BYN</strong></td>
</tr>
<tr ng-if="order.returned_method.credit > 0">
<td colspan="{{cols}}" class="text-right no-border">Кред. карта: <strong>{{order.returned_method.credit
| curr}}
BYN</strong></td>
</tr>
<tr ng-if="order.returned_count > 0">
<td colspan="{{cols - 1}}" class="text-right"><strong>Итого</strong></td>
<td>{{order.amount - order.returned_sum | curr}} BYN</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Журнал заказа -->
<div class="tab-pane animated fadeIn text-muted" id="tab2" aria-expanded="false">
<div class="table-responsive">
<table class="table m-a-0">
<thead>
<tr>
<th>Действие</th>
<th>Персонал</th>
<th>Время</th>
<th>Группа</th>
<th>Место</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="action in actions.actions">
<td>{{ action.action }}</td>
<td>{{ action.who }}</td>
<td>{{ action.time }}</td>
<td>{{ action.workgroup }}</td>
<td>{{ action.workcode }}</td>
</tr>
</tbody>
</table>
</div>
</div>
<!--Разбиение заказа-->
<div ng-if="actions.slice_trigger == 1" class="tab-pane animated fadeIn text-muted" id="tab3" aria-expanded="false">
<div ng-repeat="sliced_order_item in actions.sliced_order_items">
<p class="text-muted m-b-0">Время разбиения: <span class="m-b-0">{{ sliced_order_item.time }}</span></p>
<p class="text-muted m-b-0">Пользователь: <span class="m-b-0">{{ sliced_order_item.staff }}</span></p>
<p class="text-muted m-b-0">Товары перенесенные в заказ №<span class="m-b-0">{{ sliced_order_item.order }}</span></p>
<div class="table-responsive">
<table class="table m-a-0">
<thead>
<tr>
<th>Наименование</th>
<th>Количество</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in sliced_order_item.items">
<td>{{ item.name }}</td>
<td>{{ item.count }}</td>
</tr>
</tbody>
</table>
</div>
<hr>
</div>
</div>
<!--Объединение заказа-->
<div ng-if="actions.merge_trigger == 1" class="tab-pane animated fadeIn text-muted" id="tab4" aria-expanded="false">
<div ng-repeat="merged_order_item in actions.merged_order_items">
<p class="text-muted m-b-0">Время объединения: <span class="m-b-0">{{ merged_order_item.time }}</span></p>
<p class="text-muted m-b-0">Пользователь: <span class="m-b-0">{{ merged_order_item.staff }}</span></p>
<p class="text-muted m-b-0">Товары перенесенные из заказа №<span class="m-b-0">{{ merged_order_item.order }}</span></p>
<div class="table-responsive">
<table class="table m-a-0">
<thead>
<tr>
<th>Наименование</th>
<th>Количество</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in merged_order_item.items">
<td>{{ item.name }}</td>
<td>{{ item.count }}</td>
</tr>
</tbody>
</table>
</div>
<hr>
</div>
</div>
<!--Перенос заказа-->
<div ng-if="actions.move_trigger == 1" class="tab-pane animated fadeIn text-muted" id="tab5" aria-expanded="false">
<div ng-repeat="moved_order in actions.moved_order_data">
<p class="m-b-0">Время переноса: <span class="m-b-0">{{ moved_order.time }}</span></p>
<p class="m-b-0">Пользователь: <span class="m-b-0">{{ moved_order.staff_name }}</span></p>
<p class="m-b-0">{{ moved_order.data }}</span></p>
<hr>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,77 @@
<div class="modal-dialog modal-lg">
<div class="modal-content" id="ordersInfo">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" ng-click="closeModal('ordersInfo')">&times;
</button>
<h6 class="modal-title" ng-if="place_id">{{place_name}} стол №{{place_id}}</h6>
<h6 class="modal-title" ng-if="deleted_info">Подробнее об удаленных</h6>
<h6 class="modal-title" ng-if="discount_info">Подробнее о заказах со скидками</h6>
<h6 class="modal-title" ng-if="!place_id && !guests_info && !deleted_info && !discount_info">Подробнее о выручке <span ng-if="staff_name"> {{staff_name}}</span>
</h6>
<h6 class="modal-title" ng-if="!place_id && !deleted_info && !discount_info && guests_info">Подробнее о заказах гостей</h6>
<p class="modal-title">Отложено заказов: {{waited_count}} на сумму {{waited_sum | curr}} BYN</p>
<p class="modal-title">Закрыто заказов: {{closed_count}} на сумму {{closed_sum | curr}} BYN</p>
<p class="modal-title">Аннулировано заказов: {{cancellations_count}} на сумму {{cancellations_sum |
curr}}BYN</p>
<p class="modal-title">Удалено товаров: {{deleted_count}} на сумму {{deleted_sum | curr}} BYN</p>
<p class="modal-title">Возвращено товаров: {{returned_count}} на сумму {{returned_sum | curr}} BYN</p>
</div>
<div class="modal-body p-lg"
ng-if="(waited_count + closed_count + deleted_count + returned_count + cancellations_count) > 0">
<table id="{{ 'tableOrders_' + type }}" class="table table-bordered table-striped table-hover datatable"
ui-jq="dataTable" ui-options="dataTablesOpt" ng-style="{'width': 'inherit'}">
<thead>
<tr>
<th ng-style="{'width':'70px', 'text-align':'right'}">#</th>
<th ng-style="{ 'display' : (guests_info) ? 'revert' : 'none', 'width':'118px', 'text-align':'right'}">
Гость
</th>
<th ng-style="{'width':'198px', 'text-align':'right'}">Статус</th>
<th ng-style="{'width':'210px', 'text-align':'right'}">Открыт</th>
<th ng-style="{'width':'210px', 'text-align':'right'}">Закрыт</th>
<th ng-style="{'display' : (discount_info) ? 'revert' : 'none', 'width':'140px', 'text-align':'right'}">Сумма, BYN</th>
<th ng-style="{'display' : (discount_info) ? 'revert' : 'none', 'width':'140px', 'text-align':'right'}">Скидка, BYN</th>
<th ng-style="{'display' : (!deleted_info) ? 'revert' : 'none', 'width':'140px', 'text-align':'right'}">Итого, BYN</th>
<th ng-style="{'display' : (deleted_info) ? 'revert' : 'none', 'width':'140px', 'text-align':'right'}">Сумма удалений, BYN</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="order in orders" sglclick="getOrderInfo(order.id, order.opened, order.closed)">
<td>{{ order.id }}</td>
<td style="text-align: right" ng-style="{ 'display' : (guests_info) ? 'revert' : 'none' }">{{
order.client_name }}
</td>
<td style="text-align: right">
<p style="margin-bottom: 0;">{{ order.status }}
<button
type="button"
class="btn btn-outline-danger btn-sm"
data-toggle="popover"
data-placement="right"
data-html="true"
data-content={{order.title}}
ng-if="order.is_printed_before_edit || order.hasMove || order.hasMerge || order.hasSlice || order.hasDelete"
onmouseenter="$(this).popover('show')"
onmouseleave="$(this).popover('hide')">
‼️
</button>
<br>
<small>Предчеков: {{order.preCheck_count}}</small>
</p>
</td>
<td style="text-align: right">{{ order.opened }} {{ order.who_open }}</td>
<td style="text-align: right" ng-if="order.closed">{{ order.closed }} {{ order.who_close }}</td>
<td style="text-align: right" ng-if="!order.closed">-</td>
<td style="text-align: right" ng-style="{ 'display' : (discount_info) ? 'revert' : 'none' }">{{ order.full_sum | curr}}</td>
<td style="text-align: right" ng-style="{ 'display' : (discount_info) ? 'revert' : 'none' }">{{ order.sale_sum | curr}}</td>
<td style="text-align: right" ng-style="{ 'display' : (!deleted_info) ? 'revert' : 'none' }">{{ order.sum | curr}}</td>
<td style="text-align: right" ng-style="{ 'display' : (deleted_info) ? 'revert' : 'none' }">{{ order.deleted_items_sum | curr}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

View File

@@ -211,7 +211,7 @@
<div class="row align-items-center" style="margin-right: 0px;">
<div class="sl-content">
<div class="col-lg-12 col-sm-6">
<a ng-click="getItems(order.code, order.opened, order.closed)">
<a ng-click="getOrderInfo(order.code, order.opened, order.closed)">
<div class="sl-date text-muted">Заказ открыт:
{{order.opened}}
</div>
@@ -488,5 +488,5 @@
</div>
<div class="modal fade" id="order" data-backdrop="true">
<div ui-include="'../views/clients/order.html'"></div>
<div ui-include="'../views/activitymonitor/items/order.html'"></div>
</div>

View File

@@ -1,71 +0,0 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<p>
Номер заказа: <strong>#{{order.order_id}}</strong><br>
Время закрытия: <strong>{{order.closed}}</strong><br>
Персонал: <strong>{{order.who_close}}</strong><br>
Статус заказа: <span class="label success">{{order.order_status}}</span><br>
</p>
</div>
<div class="modal-body p-lg">
<div class="table-responsive">
<table class="table table-striped white b-a">
<thead>
<tr>
<th>ID</th>
<th>Блюдо</th>
<th style="width: 80px">Кол-во</th>
<th style="width: 140px">Стоимость</th>
<th style="width: 180px">Итог</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in order.items">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.count * item.cof}}</td>
<td>{{item.price | curr}} BYN</td>
<td>{{item.amount | curr}} BYN <p ng-if="item.discount > 0">
<span>(Скидка: {{item.discount}}%)</span></p></td>
</tr>
<tr>
<td colspan="4" class="text-right"><strong>Итого</strong></td>
<td>{{order.amount | curr}} BYN</td>
</tr>
<tr>
<td colspan="4" class="text-right no-border" ng-if="order.full_price - order.amount > 0">
<strong>Сумма скидки</strong></td>
<td ng-if="order.full_price - order.amount > 0">{{order.full_price - order.amount | curr}} BYN
</td>
</tr>
<tr>
<td colspan="4" class="text-right no-border"><strong>Оплачено:</strong></td>
</tr>
<tr ng-if="order.cash > 0">
<td colspan="5" class="text-right no-border">Наличные: <strong>{{order.cash
| curr}} BYN</strong></td>
</tr>
<tr ng-if="order.credit > 0">
<td colspan="5" class="text-right no-border">Кред. карта: <strong>{{order.credit | curr}}
BYN</strong></td>
</tr>
<tr ng-if="order.clearing > 0">
<td colspan="5" class="text-right no-border">Питание штата: <strong>{{order.clearing | curr}}
BYN</strong>
</tr>
<tr ng-if="order.presale > 0">
<td colspan="5" class="text-right no-border">Зачтен аванс: <strong>{{order.presale | curr}}
BYN</strong></td>
</tr>
<tr ng-if="order.self > 0">
<td colspan="5" class="text-right no-border">Безнал: <strong>{{order.self | curr}} BYN</strong>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,618 @@
<div id="container-floating">
<div class="nd1 nds" data-toggle="tooltip" data-placement="left" title="Обновить" ng-click="updateData()" style="background-color: #d3a411"
onmouseenter="$(this).tooltip('show')">
<i class="material-icons">&#xE5D5;</i>
</div>
<div id="floating-button" data-toggle="tooltip" data-placement="left" title="Действия" onmouseenter="$(this).tooltip('show')">
<p class="plus">
<i class="material-icons">&#xE5D2;</i>
</p>
<p class="edit">
<i class="material-icons">&#xE5CD;</i>
</p>
</div>
</div>
<div class="padding">
<div class="margin">
<div class="row">
<div class="col-sm-9">
<h5 id="currentTime" class="m-b-0 _300">{{ currentDate | date:'dd.MM.yyyy HH:mm:ss' }}
</h5>
<small class="text-muted">Данные по филиалу
<strong>{{globals.currentUser.organization.name}}</strong>
</small>
</div>
<div class="col-sm-3">
<label class="md-switch">
<input id="timerCheckbox" type="checkbox" ng-model="timerEnabled" ng-change="toggleTimer()">
<i class="blue"></i>
<span ng-show="timerEnabled">
Автоматическое обновление через: {{ timeRemaining | date:'mm:ss' }}
</span>
<span ng-show="!timerEnabled">
Обновление данных отключено!
</span>
</label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-3">
<div class="box" style="height: 198px;">
<div class="box-header warn">
<h3>Смена № {{shiftInfo.z_number}}</h3>
</div>
<div class="box-body">
<div ng-if="!shiftInfo.exists">Информация о смене будет доступна позже</div>
<div ng-if="shiftInfo.exists">
<span>Открыл: {{shiftInfo.open}} в {{shiftInfo.opened | date:'H:mm d.MM'}}</span>
<div ng-if="shiftInfo.closed">
<span>Закрыл: {{shiftInfo.close}} в {{shiftInfo.closed | date:'H:mm d.MM'}}</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-12 col-md-9">
<div class="row">
<div class="col-sm-6 col-md-4 one-height" >
<div class="box p-a" style="max-height: 75px;">
<div class="pull-left m-r">
<span class="w-40 {{app.setting.theme.primary}} text-center rounded">
<i class="material-icons">&#xE227;</i>
</span>
</div>
<div class="clear">
<h4 class="m-a-0 text-md">
<a>{{total | curr}}</a>
</h4>
<small class="text-muted">выручка</small>
</div>
<div class="box-tool">
<ul class="nav">
<li class="nav-item">
<a ng-click="getMore('total')">
<i class="fa fa-eye"></i>
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 one-height">
<div class="box-color p-a {{app.setting.theme.primary}}" style="max-height: 75px;">
<div class="pull-left m-r">
<span class="w-40 dker text-center rounded">
<i class="material-icons">&#xE84F;</i>
</span>
</div>
<div class="clear">
<h4 class="m-a-0 text-md">
<a>{{profit | curr}}</a>
</h4>
<small class="text-muted">валовый доход</small>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 one-height">
<div class="box-color p-a {{app.setting.theme.accent}}" style="max-height: 75px;">
<div class="pull-left m-r">
<span class="w-40 dker text-center rounded">
<i class="material-icons">&#xE8A1;</i>
</span>
</div>
<div class="clear">
<h4 class="m-a-0 text-md">
<a>{{middle | curr}}</a>
</h4>
<small class="text-muted">средний чек</small>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6 col-md-4 one-height">
<div class="box">
<div class="box-header danger">
<h3>Удаления: {{deleted}}</h3>
</div>
<div class="box-tool box-tool-white">
<ul class="nav">
<li class="nav-item">
<a ng-click="getMoreDeleted()">
<i class="fa fa-eye"></i>
</a>
</li>
</ul>
</div>
<div class="box-body b-t">
<h4 class="m-a-0 text-md" ng-if="deleted > 0">
<a>
<span class="text-sm lead"><strong>Сумма: {{deleted_sum | curr}} BYN</strong></span>
</a>
</h4>
<span class="text-muted" ng-if="deleted == 0">Удаленных позиций нет</span>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 one-height">
<div class="box">
<div class="box-header primary">
<h3>
Заказы со скидками: {{discounts}}
</h3>
</div>
<div class="box-tool box-tool-white">
<ul class="nav">
<li class="nav-item">
<a ng-click="getMoreDiscount()">
<i class="fa fa-eye"></i>
</a>
</li>
</ul>
</div>
<div class="box-body b-t">
<h4 class="m-a-0 text-md" ng-if="discounts > 0">
<a>
<span class="text-sm lead"><strong>Сумма: {{tot_disc_sum | curr}} BYN</strong></span>
</a>
</h4>
<span class="text-muted" ng-if="discounts == 0">Заказов со скидками нет</span>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4 one-height">
<div class="box">
<div class="box-header blue">
<h3>
Гостей: {{guests}}
</h3>
</div>
<div class="box-tool box-tool-white">
<ul class="nav">
<li class="nav-item">
<a ng-click="getMoreGuests()">
<i class="fa fa-eye"></i>
</a>
</li>
</ul>
</div>
<div class="box-body b-t">
<h4 class="m-a-0 text-md" ng-if="namedGuests > 0">
<a>
<span class="text-sm lead"><strong>Сумма заказов: {{sumNamedGuests | curr}} BYN</strong></span>
</a>
</h4>
<span class="text-muted" ng-if="namedGuests == 0">Именованных гостей нет</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-xl-4">
<div class="box">
<div class="box-header">
<h3>Текущие заказы</h3>
</div>
<div class="text-center b-t" style="height: 230px">
<div class="row-col">
<div class="row-cell p-a">
<div class="inline m-b">
<div ui-jp="easyPieChart" class="easyPieChart" ui-refresh="app.setting.color" data-redraw='true' data-percent="{{ orders_closed.percent }}"
ui-options="{
lineWidth: 8,
trackColor: 'rgba(0,0,0,0.05)',
barColor: '{{ app.setting.color.primary }}',
scaleColor: 'transparent',
size: 100,
scaleLength: 0,
animate:{
duration: 1500,
enabled:true
}
}">
<div>
<h5>{{ orders_closed.percent }}%</h5>
</div>
</div>
</div>
<div>
Закрытые
<small class="block m-b">
<strong>{{ orders_closed.total }}</strong> на сумму
<strong>{{ orders_closed.sum | curr}}</strong>
</small>
</div>
</div>
<div class="row-cell p-a dker" style="height: 230px">
<div class="inline m-b">
<div ui-jp="easyPieChart" class="easyPieChart" ui-refresh="app.setting.color" data-redraw='true' data-percent="{{ orders_waited.percent }}"
ui-options="{
lineWidth: 8,
trackColor: 'rgba(0,0,0,0.05)',
barColor: '{{ app.setting.color.warn }}',
scaleColor: 'transparent',
size: 100,
scaleLength: 0,
animate:{
duration: 1500,
enabled:true
}
}">
<div>
<h5>{{ orders_waited.percent }}%</h5>
</div>
</div>
</div>
<div>
Отложенные
<small class="block m-b">
<strong>{{ orders_waited.total }}</strong> на сумму
<strong>{{ orders_waited.sum | curr}}</strong>
</small>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 col-xl-4">
<div class="box">
<div class="box-header">
<h3>Текущие заказы</h3>
</div>
<div class="text-center b-t" style="height: 230px">
<div class="row-col">
<div class="row-cell p-a">
<div class="inline m-b">
<div ui-jp="easyPieChart" class="easyPieChart" ui-refresh="app.setting.color" data-redraw='true' data-percent="{{ orders_deleted.percent }}"
ui-options="{
lineWidth: 8,
trackColor: 'rgba(0,0,0,0.05)',
barColor: '#f44455',
scaleColor: 'transparent',
size: 100,
scaleLength: 0,
animate:{
duration: 1500,
enabled:true
}
}">
<div>
<h5>{{ orders_deleted.percent }}%</h5>
</div>
</div>
</div>
<div>
Удаленные
<small class="block m-b">
<strong>{{ orders_deleted.total }}</strong> на сумму
<strong>{{ orders_deleted.sum | curr}}</strong>
</small>
</div>
</div>
<div class="row-cell p-a dker" style="height: 230px">
<div class="inline m-b">
<div ui-jp="easyPieChart" class="easyPieChart" ui-refresh="app.setting.color" data-redraw='true' data-percent="{{ orders_returned.percent }}"
ui-options="{
lineWidth: 8,
trackColor: 'rgba(0,0,0,0.05)',
barColor: '{{ app.setting.color.accent }}',
scaleColor: 'transparent',
size: 100,
scaleLength: 0,
animate:{
duration: 1500,
enabled:true
}
}">
<div>
<h5>{{ orders_returned.percent }}%</h5>
</div>
</div>
</div>
<div>
Возвраты
<small class="block m-b">
<strong>{{ orders_returned.total }}</strong> на сумму
<strong>{{ orders_returned.sum | curr}}</strong>
</small>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-12 col-xl-4">
<div class="box">
<div class="box-header">
<h3>Персонал</h3>
</div>
<div class="box-tool">
<ul class="nav">
<li class="nav-item">
<span bs-tooltip="" title="Кликните по персоналу для просмотра подробной информации" class="text-muted inline p-a-xs m-r-sm">
<i class="fa fa-question"></i>
</span>
</li>
</ul>
</div>
<div class="scrollable" style="height: 230px">
<table class="table table-striped table-hover">
<thead>
<tr>
<td>ФИО</td>
<td class="text-right">Количество заказов</td>
<td class="text-right">Сумма, BYN</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="personal in personals" ng-click="getStaffMore(personal)">
<td class="text-left">
<strong>{{ personal.name }}</strong>
</td>
<td class="text-right">{{ personal.orders_count }}</td>
<td class="text-right">{{ personal.orders_sum | curr}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 col-xl-6">
<div class="box">
<div class="box-header">
<h3>Гости</h3>
</div>
<div class="box-body">
<canvas class="chart chart-bar" chart-data="medianGuests.data" chart-series="medianGuests.series" chart-labels="medianGuests.labels"
chart-options="medianGuests.options" chart-colors="colors"></canvas>
</div>
</div>
</div>
<div class="col-md-12 col-xl-6">
<div class="box">
<div class="box-header">
<h3>Финансы</h3>
</div>
<div class="box-body">
<canvas class="chart chart-bar" chart-data="medianFinance.data" chart-labels="medianFinance.labels" chart-series="medianFinance.series"
chart-options="medianFinance.options" chart-colors="colors"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 col-xl-8" style="max-height: 620px; "><!--overflow-y: hidden;-->
<div class="box">
<div class="box-header">
<h3>Топ продаваемых товаров</h3>
</div>
<div class="box-tool">
<ul class="nav">
<li class="nav-item">
<span bs-tooltip="" title="< 25%-сверхприбыль 25-35%-прибыль 35-50%-самоокупаемость > 50%-убыток" class="text-muted inline p-a-xs m-r-sm">
<i class="fa fa-question"></i>
</span>
</li>
</ul>
</div>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th></th>
<th class="text-center">Кол-во</th>
<th class="text-center">Сумма,
<br> BYN</th>
<th class="text-center">Total cost,
<br> BYN</th>
<th class="text-center">Total cost /
<br>Сумма</th>
<th class="text-center">Прибыль,
<br> BYN</th>
</tr>
</thead>
<tbody>
<tr class="text-right" ng-repeat="dish in dishes">
<td>
<strong>{{ dish.name }}</strong>
</td>
<td>{{ dish.count }}</td>
<td>{{ dish.sum | curr}}</td>
<td>{{ dish.totalCost | curr}}</td>
<td ng-class="getBackClass(dish.percentProffit)">{{ dish.percentProffit }} %</td>
<td>{{ dish.proffit | curr}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-md-12 col-xl-4">
<div class="box">
<div class="box-header">
<h3>Список занятых столов</h3>
</div>
<div class="box-tool">
<ul class="nav">
<li class="nav-item">
<span bs-tooltip="" title="Кликните по столу для просмотра подробной информации" class="text-muted inline p-a-xs m-r-sm">
<i class="fa fa-question"></i>
</span>
</li>
</ul>
</div>
<div class="box-body">
<p class="text-muted text-center" ng-if="tables.length == 0">Занятых столов нет</p>
<div class="table-responsive" ng-if="tables.length > 0" style="max-height: 510px;">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Зал</th>
<th>Номер стола</th>
<th>Количество заказов</th>
<th>Сумма, BYN</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="table in tables" ng-click="getTableMore(table)">
<td>
<strong>{{ table.place_name }}</strong>
</td>
<td>
<strong>{{ table.table_name }}</strong>
</td>
<td>{{ table.guests_count }}</td>
<td class="text-right">{{ table.sum | curr}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 col-xl-4">
<div class="box">
<div class="box-header">
<h3>Категории товаров</h3>
</div>
<div class="box-body">
<div class="box-body">
<canvas class="chart chart-pie" chart-data="folders.data" chart-labels="folders.labels" chart-options="folders.options"></canvas>
</div>
</div>
</div>
</div>
<div class="col-md-12 col-xl-4">
<div class="box">
<div class="box-header">
<h3>Места продаж</h3>
</div>
<div class="box-body">
<div class="box-body">
<canvas class="chart chart-pie" chart-data="printers.data" chart-labels="printers.labels" chart-options="printers.options"></canvas>
</div>
</div>
</div>
</div>
<div class="col-md-12 col-xl-4">
<div class="box">
<div class="box-header">
<h3>Типы оплат</h3>
</div>
<div class="box-body">
<div class="box-body">
<canvas class="chart chart-pie" chart-data="payments.data" chart-labels="payments.labels" chart-options="payments.options"></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="add-widget">
<div ui-include="'../views/dashboard/add.html'"></div>
</div>
<div class="modal fade" id="get-more-deleted">
<div ui-include="'../views/dashboard/items/more-deleted.html'"></div>
</div>
<!--<div class="modal my-modal fade" id="get-more-newyear">
<div ui-include="'../views/dashboard/items/more-newyear.html'"></div>
</div>-->
<div class="modal fade" id="get-more-guests">
<div ui-include="'../views/dashboard/items/more-guests.html'"></div>
</div>
<div class="modal fade" id="get-more-discount">
<div ui-include="'../views/dashboard/items/more-discount.html'"></div>
</div>
<div class="modal fade" id="get-more-total">
<div ui-include="'../views/dashboard/items/more-total.html'"></div>
</div>
<div class="modal fade" id="get-more-staff">
<div ui-include="'../views/dashboard/items/more-staff.html'"></div>
</div>
<div class="modal fade" id="get-more-table">
<div ui-include="'../views/dashboard/items/more-table.html'"></div>
</div>
<div class="modal fade" id="items-guests">
<div ui-include="'../views/dashboard/items/items-guests.html'"></div>
</div>
<div class="modal fade" id="items-discount">
<div ui-include="'../views/dashboard/items/items-discount.html'"></div>
</div>
<div class="modal fade" id="items-total">
<div ui-include="'../views/dashboard/items/items-total.html'"></div>
</div>
<div class="modal fade" id="items-staff">
<div ui-include="'../views/dashboard/items/items-staff.html'"></div>
</div>
<div class="modal fade" id="items-deleted">
<div ui-include="'../views/dashboard/items/items-deleted.html'"></div>
</div>
<div class="modal fade" id="preload-modal" data-backdrop="true">
<div ui-include="'../views/dashboard/preload.html'"></div>
</div>

View File

@@ -1,19 +1,3 @@
<div id="container-floating">
<div class="nd1 nds" data-toggle="tooltip" data-placement="left" title="Обновить" ng-click="updateData()" style="background-color: #d3a411"
onmouseenter="$(this).tooltip('show')">
<i class="material-icons">&#xE5D5;</i>
</div>
<div id="floating-button" data-toggle="tooltip" data-placement="left" title="Действия" onmouseenter="$(this).tooltip('show')">
<p class="plus">
<i class="material-icons">&#xE5D2;</i>
</p>
<p class="edit">
<i class="material-icons">&#xE5CD;</i>
</p>
</div>
</div>
<div class="padding">
<div class="margin">
<div class="row">
@@ -72,13 +56,13 @@
<h4 class="m-a-0 text-md">
<a>{{total | curr}}</a>
</h4>
<small class="text-muted">выручка</small>
<small class="text-muted">заказы</small>
</div>
<div class="box-tool">
<ul class="nav">
<li class="nav-item">
<a ng-click="getMore('total')">
<a sglclick="getMoreTotal('total')">
<i class="fa fa-eye"></i>
</a>
</li>
@@ -124,7 +108,7 @@
<div class="col-sm-6 col-md-4 one-height">
<div class="box">
<div class="box-header danger">
<h3>Удаления: {{deleted}}</h3>
<h3>Удалено товаров: {{orders_deleted.total}}</h3>
</div>
<div class="box-tool box-tool-white">
@@ -138,12 +122,12 @@
</div>
<div class="box-body b-t">
<h4 class="m-a-0 text-md" ng-if="deleted > 0">
<h4 class="m-a-0 text-md" ng-if="orders_deleted.total > 0">
<a>
<span class="text-sm lead"><strong>Сумма: {{deleted_sum | curr}} BYN</strong></span>
<span class="text-sm lead"><strong>Сумма: {{orders_deleted.sum | curr}} BYN</strong></span>
</a>
</h4>
<span class="text-muted" ng-if="deleted == 0">Удаленных позиций нет</span>
<span class="text-muted" ng-if="orders_deleted.total == 0">Удаленных товаров нет</span>
</div>
</div>
</div>
@@ -169,7 +153,7 @@
<div class="box-body b-t">
<h4 class="m-a-0 text-md" ng-if="discounts > 0">
<a>
<span class="text-sm lead"><strong>Сумма: {{tot_disc_sum | curr}} BYN</strong></span>
<span class="text-sm lead"><strong>Сумма: {{tot_disc_sum | curr}} BYN <small>(Сумма скидок: {{discounts_sum | curr}} BYN)</small></strong></span>
</a>
</h4>
<span class="text-muted" ng-if="discounts == 0">Заказов со скидками нет</span>
@@ -181,14 +165,14 @@
<div class="box">
<div class="box-header blue">
<h3>
Гостей: {{guests}}
Именованных гостей: {{namedGuests}}
</h3>
</div>
<div class="box-tool box-tool-white">
<ul class="nav">
<li class="nav-item">
<a ng-click="getMoreGuests()">
<a sglclick="getMoreGuests('guests')">
<i class="fa fa-eye"></i>
</a>
</li>
@@ -275,6 +259,34 @@
</small>
</div>
</div>
<div class="row-cell p-a">
<div class="inline m-b">
<div ui-jp="easyPieChart" class="easyPieChart" ui-refresh="app.setting.color" data-redraw='true' data-percent="{{ orders_cancellations.percent }}"
ui-options="{
lineWidth: 8,
trackColor: 'rgba(0,0,0,0.05)',
barColor: '{{ app.setting.color.primary }}',
scaleColor: 'transparent',
size: 100,
scaleLength: 0,
animate:{
duration: 1500,
enabled:true
}
}">
<div>
<h5>{{ orders_cancellations.percent }}%</h5>
</div>
</div>
</div>
<div>
Аннулированные
<small class="block m-b">
<strong>{{ orders_cancellations.total }}</strong> на сумму
<strong>{{ orders_cancellations.sum | curr}}</strong>
</small>
</div>
</div>
</div>
</div>
</div>
@@ -283,7 +295,7 @@
<div class="col-md-6 col-xl-4">
<div class="box">
<div class="box-header">
<h3>Текущие заказы</h3>
<h3>Информация о товарах</h3>
</div>
<div class="text-center b-t" style="height: 230px">
@@ -337,7 +349,7 @@
</div>
</div>
<div>
Возвраты
Возвращенные
<small class="block m-b">
<strong>{{ orders_returned.total }}</strong> на сумму
<strong>{{ orders_returned.sum | curr}}</strong>
@@ -375,7 +387,7 @@
</tr>
</thead>
<tbody>
<tr ng-repeat="personal in personals" ng-click="getStaffMore(personal)">
<tr ng-repeat="personal in personals" ng-click="getMoreStaff(personal, 'guests')" ng-if="personal.orders_count > 0">
<td class="text-left">
<strong>{{ personal.name }}</strong>
</td>
@@ -505,8 +517,8 @@
<td>
<strong>{{ table.table_name }}</strong>
</td>
<td>{{ table.guests_count }}</td>
<td class="text-right">{{ table.sum | curr}}</td>
<td>{{ table.orders_count }}</td>
<td class="text-right">{{ table.orders_sum | curr}}</td>
</tr>
</tbody>
</table>
@@ -565,54 +577,22 @@
<div ui-include="'../views/dashboard/add.html'"></div>
</div>
<div class="modal fade" id="get-more-deleted">
<div ui-include="'../views/dashboard/items/more-deleted.html'"></div>
</div>
<!--<div class="modal my-modal fade" id="get-more-newyear">
<div ui-include="'../views/dashboard/items/more-newyear.html'"></div>
</div>-->
<div class="modal fade" id="get-more-guests">
<div ui-include="'../views/dashboard/items/more-guests.html'"></div>
<div class="modal fade" id="order">
<div ui-include="'../views/activitymonitor/items/order.html'"></div>
</div>
<div class="modal fade" id="get-more-discount">
<div ui-include="'../views/dashboard/items/more-discount.html'"></div>
</div>
<div class="modal fade" id="get-more-total">
<div ui-include="'../views/dashboard/items/more-total.html'"></div>
</div>
<div class="modal fade" id="get-more-staff">
<div ui-include="'../views/dashboard/items/more-staff.html'"></div>
<div class="modal fade" id="orders">
<div ui-include="'../views/activitymonitor/items/orders.html'"></div>
</div>
<div class="modal fade" id="get-more-table">
<div ui-include="'../views/dashboard/items/more-table.html'"></div>
</div>
<div class="modal fade" id="items-guests">
<div ui-include="'../views/dashboard/items/items-guests.html'"></div>
</div>
<div class="modal fade" id="items-discount">
<div ui-include="'../views/dashboard/items/items-discount.html'"></div>
</div>
<div class="modal fade" id="items-total">
<div ui-include="'../views/dashboard/items/items-total.html'"></div>
</div>
<div class="modal fade" id="items-staff">
<div ui-include="'../views/dashboard/items/items-staff.html'"></div>
</div>
<div class="modal fade" id="items-deleted">
<div ui-include="'../views/dashboard/items/items-deleted.html'"></div>
</div>
<div class="modal fade" id="preload-modal" data-backdrop="true">
<div ui-include="'../views/dashboard/preload.html'"></div>
</div>

View File

@@ -1,7 +1,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-toggle="modal" data-target="#items-deleted" ng-click="returnModal('deleted')">
<button type="button" class="close" data-toggle="modal" ng-click="backModal('items-deleted', 'get-more-deleted')">
<i class="material-icons md-24">arrow_back</i>
</button>
<h5 class="modal-title">Подробнее об удалениях в заказе № {{ order.code }}</h5>

View File

@@ -1,7 +1,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-toggle="modal" data-target="#items-discount" ng-click="returnModal('discount')">
<button type="button" class="close" data-toggle="modal" ng-click="backModal('items-discount', 'get-more-discount')">
<i class="material-icons md-24">arrow_back</i>
</button>
<h5 class="modal-title">Подробнее о заказе № {{ order.title }}</h5>

View File

@@ -1,7 +1,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-toggle="modal" data-target="#items-guests" ng-click="returnModal('guests')">
<button type="button" class="close" data-toggle="modal" ng-click="backModal('items-guests', 'get-more-guests')">
<i class="material-icons md-24">arrow_back</i>
</button>
<h5 class="modal-title">{{ order.title }}</h5>

View File

@@ -1,7 +1,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-toggle="modal" data-target="#items-staff" ng-click="returnModal('staff')">
<button type="button" class="close" data-toggle="modal" ng-click="backModal('items-staff', 'get-more-staff')">
<i class="material-icons md-24">arrow_back</i>
</button>
<h5 class="modal-title">{{ order.title }}</h5>

View File

@@ -79,22 +79,22 @@
<div class="table-responsive">
<table class="table m-a-0">
<thead>
<tr>
<th>Действие</th>
<th>Персонал</th>
<th>Время</th>
<th>Группа</th>
<th>Место</th>
</tr>
<tr>
<th>Действие</th>
<th>Персонал</th>
<th>Время</th>
<th>Группа</th>
<th>Место</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="action in actions.actions">
<td>{{ action.action }}</td>
<td>{{ action.who }}</td>
<td>{{ action.time }}</td>
<td>{{ action.workgroup }}</td>
<td>{{ action.workcode }}</td>
</tr>
<tr ng-repeat="action in actions.actions">
<td>{{ action.action }}</td>
<td>{{ action.who }}</td>
<td>{{ action.time }}</td>
<td>{{ action.workgroup }}</td>
<td>{{ action.workcode }}</td>
</tr>
</tbody>
</table>
</div>
@@ -108,16 +108,16 @@
<div class="table-responsive">
<table class="table m-a-0">
<thead>
<tr>
<th>Наименование</th>
<th>Количество</th>
</tr>
<tr>
<th>Наименование</th>
<th>Количество</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in sliced_order_item.items">
<td>{{ item.name }}</td>
<td>{{ item.count }}</td>
</tr>
<tr ng-repeat="item in sliced_order_item.items">
<td>{{ item.name }}</td>
<td>{{ item.count }}</td>
</tr>
</tbody>
</table>
</div>
@@ -134,16 +134,16 @@
<div class="table-responsive">
<table class="table m-a-0">
<thead>
<tr>
<th>Наименование</th>
<th>Количество</th>
</tr>
<tr>
<th>Наименование</th>
<th>Количество</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in merged_order_item.items">
<td>{{ item.name }}</td>
<td>{{ item.count }}</td>
</tr>
<tr ng-repeat="item in merged_order_item.items">
<td>{{ item.name }}</td>
<td>{{ item.count }}</td>
</tr>
</tbody>
</table>
</div>

View File

@@ -33,7 +33,7 @@
</div>
<div ng-if="moreData.deleted_orders.length == 0">
<div class="text-muted">Удаленных позиций нет</div>
<div class="text-muted">Удаленных товаров нет</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,41 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h5 class="modal-title">{{ moreData.title }}</h5>
</div>
<div class="modal-body p-lg">
<div class="table-responsive" ng-if="moreData.orders.length > 0">
<table class="table table-hover">
<thead>
<tr>
<th>Заказ №</th>
<th>Открыт</th>
<th>Закрыт</th>
<th class="text-right">Итого, BYN</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="order in moreData.orders" ng-click="getTotalItems(order)">
<td>{{ order.number }}</td>
<td>{{ order.opened }}</td>
<td>{{ getClosedDate(order.closed) }}</td>
<td class="text-right">{{ order.sum | curr }}</td>
</tr>
</tbody>
<thead>
<tr>
<th class="text-left" colspan="3">Всего: {{ moreData.count }} {{ GetCountTotalOrders(moreData.count) }}</th>
<th class="text-right">Итого: {{ moreData.sum | curr }} BYN</th>
</tr>
</thead>
</table>
</div>
<div ng-if="moreData.orders.length == 0">
<div class="text-muted">Закрытых заказов нет</div>
</div>
</div>
</div>
</div>

View File

@@ -37,4 +37,5 @@
<div class="text-muted">Закрытых заказов нет</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -9,6 +9,7 @@
<optgroup label="Основные">
<option value="statistics">По статистике</option>
<option value="realisation">По реализации</option>
<option value="reportRealisationConstruct">Расширенный по реализации</option>
<option value="deleted">По удалениям</option>
<option value="pay">По отделам и видам оплат</option>
<option value="staff">По персоналу</option>
@@ -139,6 +140,10 @@
<div ui-include="'../views/reports/items/realisation.html'"></div>
</div>
<div class="modal fade" id="report-construct" data-backdrop="true">
<div ui-include="'../views/reports/items/construct.html'"></div>
</div>
<div class="modal fade" id="report-statistic" data-backdrop="true">
<div ui-include="'../views/reports/items/statistic.html'"></div>
</div>

View File

@@ -0,0 +1,66 @@
<div class="modal-dialog modal-lg" style="width: 98% !important;
height: 92% !important;
min-width: 98% !important;
min-height: 92% !important;
max-width: 98% !important;
max-height: 92% !important;
padding: 0 !important;">
<div class="modal-content" id="reportRealisationConstruct" style=" height: 99% !important;
min-height: 99% !important;
max-height: 99% !important;">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
ng-click="closeModal('reportRealisationConstruct')">&times;
</button>
<button class="btn btn-icon white" ng-click="printElem('#reportRealisationConstruct')">
<i class="fa fa-print"></i>
</button>
<h4 class="modal-title">{{globals.currentUser.organization.name}}</h4>
<h5 class="modal-title">Расширенный отчет</h5>
<span class="text-muted">{{start_date}} - {{end_date}}</span>
</div>
<div id="tableRealisation" class="modal-body p-lg">
<!-- <table cellspacing="5" cellpadding="5" border="0">
<tbody>
<span>Фильтр по времени добавления позиции</span>
<tr>
<td colspan="1">С:</td>
<td colspan="1"><input type="text" id="min" name="min" class="form-control"></td>
<td colspan="1">По:</td>
<td colspan="1"><input type="text" id="max" name="max" class="form-control"></td>
</tr>
</tbody>
</table>-->
<!--<table cellspacing="5" cellpadding="5" border="0">
<tbody>
<span>Фильтр по персоналу: </span>
<tr>
<td colspan="2">
<select id="staff_filter" class="form-control c-select">
<option value="">All</option>
</select>
</td>
</tr>
</tbody>
</table>
<table cellspacing="5" cellpadding="5" border="0">
<tbody>
<span>Фильтр по размеру скидки: </span>
<tr>
<td colspan="2">
<select id="discount_filter" class="form-control c-select">
<option value="">All</option>
</select>
</td>
</tr>
</tbody>
</table>-->
<table id="table_orders" class="display table table-striped b-t compact cell-border"
style="width:100%"></table>
<div ng-if="items.length == 0">
<p>Реализация отсутсвует</p>
</div>
</div>
</div>
</div>

View File

@@ -59,6 +59,7 @@
<a class="dropdown-item" ng-click="reportPay(shift)">По отделам</a>
<a class="dropdown-item" ng-click="reportDiscounts(shift)">По скидкам</a>
<!-- <a class="dropdown-item" ng-click="reportOrders(shift)">По заказам</a> -->
<a class="dropdown-item" ng-click="reportRealisationConstruct(shift)">Расширенный по реализации</a>
<a class="dropdown-item" ng-click="reportMerged(shift)">По объединениям</a>
<a class="dropdown-item" ng-click="reportSliced(shift)">По разбиениям</a>
<a class="dropdown-item" ng-click="reportMoved(shift)">По переносам</a>
@@ -104,6 +105,10 @@
<div ui-include="'../views/reports/items/realisation.html'"></div>
</div>
<div class="modal fade" id="report-construct" data-backdrop="true">
<div ui-include="'../views/reports/items/construct.html'"></div>
</div>
<div class="modal fade" id="report-statistic" data-backdrop="true">
<div ui-include="'../views/reports/items/statistic.html'"></div>
</div>

View File

@@ -16,7 +16,7 @@
<tbody>
<tr ng-repeat="task in active_tasks">
<td>{{ task.name }} <span class="label primary m-r-xs left5">{{ task.code }}</span></td>
<td>{{ task.name }} <span class="label primary m-r-xs left5">{{ task.code }}</span> <small>Next at: {{task.next_at}}</small></td>
<td><input type="number" class="form-control" ng-model="task.period" ng-change="changePeriod(task)" /></td>
<td>
<label class="ui-switch ui-switch-md m-t-xs">
@@ -30,7 +30,7 @@
</tr>
<tr ng-repeat="task in all_tasks" ng-if="isTaskActive(task)">
<td>{{ task.name }} <span class="label primary m-r-xs left5">{{ task.code }}</span></td>
<td>{{ task.name }} <span class="label primary m-r-xs left5">{{ task.code }}</span> <small>Next at: {{task.next_at}}</small></td>
<td><input type="number" class="form-control" ng-model="task.period" ng-change="changePeriod(task)" /></td>
<td>
<label class="ui-switch ui-switch-md m-t-xs">

View File

@@ -1,10 +1,12 @@
<div id="container-floating">
<div class="nd1 nds" data-toggle="tooltip" data-placement="left" title="Обновить" ng-click="update()" style="background-color: #d3a411"
onmouseenter="$(this).tooltip('show')">
<div class="nd1 nds" data-toggle="tooltip" data-placement="left" title="Обновить" ng-click="update()"
style="background-color: #d3a411"
onmouseenter="$(this).tooltip('show')">
<i class="material-icons">&#xE5D5;</i>
</div>
<div id="floating-button" data-toggle="tooltip" data-placement="left" title="Действия" onmouseenter="$(this).tooltip('show')">
<div id="floating-button" data-toggle="tooltip" data-placement="left" title="Действия"
onmouseenter="$(this).tooltip('show')">
<p class="plus">
<i class="material-icons">&#xE5D2;</i>
</p>
@@ -17,46 +19,58 @@
<div class="padding">
<div class="box">
<!-- <div class="table-responsive"> -->
<table class="table table-striped m-a-0">
<thead>
<tr>
<th>ID</th>
<th>Тип</th>
<th>Код рабочей группы</th>
<th>Код рабочего места</th>
<th>Статус</th>
<th>Последняя активность</th>
<th style="width: 70px"><i class="material-icons">&#xE3E7;</i></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="terminal in terminals">
<td><strong>{{ terminal.key }}</strong></td>
<td><strong>{{ terminal.soft }}</strong></td>
<td>{{ terminal.work_group }}</td>
<td>{{ terminal.work_code }}</td>
<td>
<label class="ui-switch ui-switch-md m-t-xs">
<input type="checkbox" ng-model="terminal.is_active" ng-change="onLicence(terminal.key, terminal.is_active)">
<i></i>
</label>
</td>
<td><span ng-if="terminal.last_activity != '0'">{{ terminal.last_activity }}</span></td>
<td>
<div class="dropdown inline">
<button class="btn btn-sm white dropdown-toggle" data-toggle="dropdown">
<i class="material-icons">&#xE5D2;</i>
</button>
<div class="dropdown-menu pull-right dropdown-menu-scale">
<a class="dropdown-item" ng-click="editTerminal(terminal.key)">Управление синхронизацией</a>
<a class="dropdown-item" ng-click="getEquipment(terminal.key)">Принтеры</a>
<a class="dropdown-item" ng-click="showLogs(terminal.key)">Журнал</a>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<table class="table table-striped m-a-0">
<thead>
<tr>
<th>ID</th>
<th>Тип</th>
<th>Имя рабочей группы</th>
<th>Код рабочей группы</th>
<th>Код рабочего места</th>
<th>Статус</th>
<th>Последняя активность</th>
<th style="width: 70px"><i class="material-icons">&#xE3E7;</i></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="terminal in terminals">
<td><strong>{{ terminal.key }}</strong></td>
<td><strong>{{ terminal.soft }}</strong></td>
<td ng-if="terminal.name" ios-dblclick="terminal.name = null">{{ terminal.name }}</td>
<td ng-if="!terminal.name">
<div class="input-group">
<input type="text" class="form-control" ng-model="terminal.newName">
<span class="input-group-btn">
<button class="btn white" type="button" ng-click="updateTerminal(terminal)" ng-if="terminal.newName"><i class="fa fa-check"></i></button>
</span>
</div>
</td>
<td>{{ terminal.work_group }}</td>
<td>{{ terminal.work_code }}</td>
<td>
<label class="ui-switch ui-switch-md m-t-xs">
<input type="checkbox" ng-model="terminal.is_active"
ng-change="onLicence(terminal.key, terminal.is_active)">
<i></i>
</label>
</td>
<td><span ng-if="terminal.last_activity != '0'">{{ terminal.last_activity }}</span></td>
<td>
<div class="dropdown inline">
<button class="btn btn-sm white dropdown-toggle" data-toggle="dropdown">
<i class="material-icons">&#xE5D2;</i>
</button>
<div class="dropdown-menu pull-right dropdown-menu-scale">
<a class="dropdown-item" ng-click="editTerminal(terminal.key)">Управление синхронизацией</a>
<a class="dropdown-item" ng-click="getEquipment(terminal.key)">Принтеры</a>
<a class="dropdown-item" ng-click="showLogs(terminal.key)">Журнал</a>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<!-- </div> -->
</div>
</div>