parent
8c1736f4fd
commit
5b10141217
|
@ -8,6 +8,7 @@ namespace mirzaev\ebala\controllers;
|
||||||
use mirzaev\ebala\controllers\core,
|
use mirzaev\ebala\controllers\core,
|
||||||
mirzaev\ebala\controllers\traits\errors,
|
mirzaev\ebala\controllers\traits\errors,
|
||||||
mirzaev\ebala\models\account as model,
|
mirzaev\ebala\models\account as model,
|
||||||
|
mirzaev\ebala\models\task,
|
||||||
mirzaev\ebala\models\registry,
|
mirzaev\ebala\models\registry,
|
||||||
mirzaev\ebala\models\core as _core;
|
mirzaev\ebala\models\core as _core;
|
||||||
|
|
||||||
|
@ -27,6 +28,37 @@ final class account extends core
|
||||||
{
|
{
|
||||||
use errors;
|
use errors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Страница аккаунта
|
||||||
|
*
|
||||||
|
* @param array $parameters Параметры запроса
|
||||||
|
*/
|
||||||
|
public function index(array $parameters = []): ?string
|
||||||
|
{
|
||||||
|
if ($this->account->status()) {
|
||||||
|
// Авторизован аккаунт
|
||||||
|
|
||||||
|
// Инициализация истории заявок
|
||||||
|
$this->view->history = task::list(before: 'FILTER task.worker == "' . model::worker($this->account->getId())?->id . '"');
|
||||||
|
|
||||||
|
// Инициализация баланса счёта
|
||||||
|
// В будущем сделать перебор по всем связанным с аккаунтам сотрудникам и магазинам (сейчас только 1 сотрудник может быть)
|
||||||
|
$this->view->balance = 0;
|
||||||
|
foreach (task::list(before: 'FILTER task.worker == "' . model::worker($this->account->getId())?->id . '" && task.result.processed == false') as $task) $this->view->balance += $task->task['result']['hours'] * $task->task['result']['hour'] + $task->task['result']['penalty'] + $task->task['result']['bonus'];
|
||||||
|
|
||||||
|
// Генерация представления
|
||||||
|
$main = $this->view->render(DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'account.html');
|
||||||
|
} else $main = $this->authorization();
|
||||||
|
|
||||||
|
// Возврат (успех)
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') return $this->view->render(DIRECTORY_SEPARATOR . 'index.html', ['main' => $main]);
|
||||||
|
else if ($_SERVER['REQUEST_METHOD'] === 'POST') return $main;
|
||||||
|
|
||||||
|
// Возврат (провал)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Прочитать данные
|
* Прочитать данные
|
||||||
*
|
*
|
||||||
|
|
|
@ -388,6 +388,166 @@ final class market extends core
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Заблокировать сотрудника в магазине
|
||||||
|
*
|
||||||
|
* @param array $parameters Параметры запроса
|
||||||
|
*/
|
||||||
|
public function ban(array $parameters = []): ?string
|
||||||
|
{
|
||||||
|
if ($this->account->status() && $this->account->type === 'market') {
|
||||||
|
// Авторизован аккаунт магазина
|
||||||
|
|
||||||
|
// Инициализация данных магазина
|
||||||
|
$market = account::market($this->account->getId());
|
||||||
|
|
||||||
|
if ($market instanceof _document) {
|
||||||
|
// Найден магазин
|
||||||
|
|
||||||
|
// Блокировка сотрудника
|
||||||
|
if (!in_array($parameters['worker'], $market->bans ??= [], true)) $market->bans = $market->bans + [$parameters['worker']];
|
||||||
|
|
||||||
|
if (_core::update($market)) {
|
||||||
|
// Записаны данные магазина
|
||||||
|
|
||||||
|
// Запись в глобальную переменную шаблонизатора обрабатываемой страницы (отключение)
|
||||||
|
$this->view->page = null;
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
header('Content-Encoding: none');
|
||||||
|
header('X-Accel-Buffering: no');
|
||||||
|
|
||||||
|
// Инициализация буфера вывода
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
// Инициализация буфера ответа
|
||||||
|
$return = [
|
||||||
|
'banned' => true,
|
||||||
|
'errors' => self::parse_only_text($this->errors)
|
||||||
|
];
|
||||||
|
|
||||||
|
// Генерация ответа
|
||||||
|
echo json_encode($return);
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Length: ' . ob_get_length());
|
||||||
|
|
||||||
|
// Отправка и деинициализация буфера вывода
|
||||||
|
ob_end_flush();
|
||||||
|
flush();
|
||||||
|
} else throw new exception('Не удалось записать изменения в базу данных');
|
||||||
|
} else throw new exception('Не удалось найти магазин');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Возврат (провал)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Разблокировать сотрудника в магазине
|
||||||
|
*
|
||||||
|
* @param array $parameters Параметры запроса
|
||||||
|
*/
|
||||||
|
public function unban(array $parameters = []): ?string
|
||||||
|
{
|
||||||
|
if ($this->account->status() && $this->account->type === 'market') {
|
||||||
|
// Авторизован аккаунт магазина
|
||||||
|
|
||||||
|
// Инициализация данных магазина
|
||||||
|
$market = account::market($this->account->getId());
|
||||||
|
|
||||||
|
if ($market instanceof _document) {
|
||||||
|
// Найден магазин
|
||||||
|
|
||||||
|
// Разблокировка сотрудника
|
||||||
|
if (in_array($parameters['worker'], $market->bans ??= [], true)) $market->bans = array_diff($market->bans ??= [], [$parameters['worker']]);
|
||||||
|
|
||||||
|
if (_core::update($market)) {
|
||||||
|
// Записаны данные магазина
|
||||||
|
|
||||||
|
// Запись в глобальную переменную шаблонизатора обрабатываемой страницы (отключение)
|
||||||
|
$this->view->page = null;
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
header('Content-Encoding: none');
|
||||||
|
header('X-Accel-Buffering: no');
|
||||||
|
|
||||||
|
// Инициализация буфера вывода
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
// Инициализация буфера ответа
|
||||||
|
$return = [
|
||||||
|
'unbanned' => true,
|
||||||
|
'errors' => self::parse_only_text($this->errors)
|
||||||
|
];
|
||||||
|
|
||||||
|
// Генерация ответа
|
||||||
|
echo json_encode($return);
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Length: ' . ob_get_length());
|
||||||
|
|
||||||
|
// Отправка и деинициализация буфера вывода
|
||||||
|
ob_end_flush();
|
||||||
|
flush();
|
||||||
|
} else throw new exception('Не удалось записать изменения в базу данных');
|
||||||
|
} else throw new exception('Не удалось найти магазин');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Возврат (провал)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверить наличие сотрудника в реестре заблокированных
|
||||||
|
*
|
||||||
|
* @param array $parameters Параметры запроса
|
||||||
|
*/
|
||||||
|
public function banned(array $parameters = []): ?string
|
||||||
|
{
|
||||||
|
if ($this->account->status() && $this->account->type === 'market') {
|
||||||
|
// Авторизован аккаунт магазина
|
||||||
|
|
||||||
|
// Инициализация данных магазина
|
||||||
|
$market = account::market($this->account->getId());
|
||||||
|
|
||||||
|
if ($market instanceof _document) {
|
||||||
|
// Найден магазин
|
||||||
|
|
||||||
|
// Запись в глобальную переменную шаблонизатора обрабатываемой страницы (отключение)
|
||||||
|
$this->view->page = null;
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
header('Content-Encoding: none');
|
||||||
|
header('X-Accel-Buffering: no');
|
||||||
|
|
||||||
|
// Инициализация буфера вывода
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
// Инициализация буфера ответа
|
||||||
|
$return = [
|
||||||
|
'banned' => in_array($parameters['worker'], $market->bans ?? [], true),
|
||||||
|
'errors' => self::parse_only_text($this->errors)
|
||||||
|
];
|
||||||
|
|
||||||
|
// Генерация ответа
|
||||||
|
echo json_encode($return);
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Length: ' . ob_get_length());
|
||||||
|
|
||||||
|
// Отправка и деинициализация буфера вывода
|
||||||
|
ob_end_flush();
|
||||||
|
flush();
|
||||||
|
} else throw new exception('Не удалось найти магазин');
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Обновить данные
|
* Обновить данные
|
||||||
*
|
*
|
||||||
|
@ -416,6 +576,7 @@ final class market extends core
|
||||||
if ($parameters['city'] !== $market->city) $market->city = $parameters['city'];
|
if ($parameters['city'] !== $market->city) $market->city = $parameters['city'];
|
||||||
if ($parameters['district'] !== $market->district) $market->district = $parameters['district'];
|
if ($parameters['district'] !== $market->district) $market->district = $parameters['district'];
|
||||||
if ($parameters['address'] !== $market->address) $market->address = $parameters['address'];
|
if ($parameters['address'] !== $market->address) $market->address = $parameters['address'];
|
||||||
|
if (!in_array($parameters['ban'], $market->bans, true)) $market->bans[] = $parameters['ban'];
|
||||||
|
|
||||||
if (_core::update($market)) {
|
if (_core::update($market)) {
|
||||||
// Записаны данные магазина
|
// Записаны данные магазина
|
||||||
|
|
|
@ -76,7 +76,7 @@ final class payments extends core
|
||||||
} else throw new exception('Вы не авторизованы');
|
} else throw new exception('Вы не авторизованы');
|
||||||
} catch (exception $e) {
|
} catch (exception $e) {
|
||||||
// Запись в реестр ошибок
|
// Запись в реестр ошибок
|
||||||
$this->errors[] = [
|
$this->errors['export'][] = [
|
||||||
'text' => $e->getMessage(),
|
'text' => $e->getMessage(),
|
||||||
'file' => $e->getFile(),
|
'file' => $e->getFile(),
|
||||||
'line' => $e->getLine(),
|
'line' => $e->getLine(),
|
||||||
|
@ -110,7 +110,7 @@ final class payments extends core
|
||||||
/**
|
/**
|
||||||
* Магазины
|
* Магазины
|
||||||
*
|
*
|
||||||
* Расчитать ... (сверку?) за выбранный период и сгенерировать excel-документ
|
* Расчитать прибыль с магазинов за выбранный период и сгенерировать excel-документ
|
||||||
*
|
*
|
||||||
* @param array $parameters Параметры запроса
|
* @param array $parameters Параметры запроса
|
||||||
*
|
*
|
||||||
|
@ -161,7 +161,7 @@ final class payments extends core
|
||||||
} else throw new exception('Вы не авторизованы');
|
} else throw new exception('Вы не авторизованы');
|
||||||
} catch (exception $e) {
|
} catch (exception $e) {
|
||||||
// Запись в реестр ошибок
|
// Запись в реестр ошибок
|
||||||
$this->errors[] = [
|
$this->errors['export'][] = [
|
||||||
'text' => $e->getMessage(),
|
'text' => $e->getMessage(),
|
||||||
'file' => $e->getFile(),
|
'file' => $e->getFile(),
|
||||||
'line' => $e->getLine(),
|
'line' => $e->getLine(),
|
||||||
|
@ -192,4 +192,74 @@ final class payments extends core
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Подтвердить
|
||||||
|
*
|
||||||
|
* Подтвердить выполнение операций с документом (магазины или сотрудники)
|
||||||
|
*
|
||||||
|
* @param array $parameters Параметры запроса
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function confirm(array $parameters = []): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator')) {
|
||||||
|
// Авторизован аккаунт администратора или оператора
|
||||||
|
|
||||||
|
// Инициализация буфера ошибок
|
||||||
|
$this->errors['confirm'] ??= [];
|
||||||
|
|
||||||
|
if (!empty($from = (int) ($_COOKIE["tasks_filter_from"] ?? @$this->session->buffer[$_SERVER['INTERFACE']]['tasks']['filters']['from']))) {
|
||||||
|
// Инициализирован параметр: from
|
||||||
|
|
||||||
|
if (!empty($to = (int) ($_COOKIE["tasks_filter_to"] ?? @$this->session->buffer[$_SERVER['INTERFACE']]['tasks']['filters']['to']))) {
|
||||||
|
// Инициализирован параметр: to
|
||||||
|
|
||||||
|
// Запуск процедуры подтверждения
|
||||||
|
model::confirm(
|
||||||
|
$from,
|
||||||
|
$to,
|
||||||
|
match ($parameters['type']) {
|
||||||
|
'workers' => 'workers',
|
||||||
|
'markets' => 'markets',
|
||||||
|
default => throw new exception('Для подтверждения обработки документа необходимо передать его тип: workers, markets')
|
||||||
|
},
|
||||||
|
$this->errors['confirm']
|
||||||
|
);
|
||||||
|
} else throw new exception('Не инициализирован параметр: to');
|
||||||
|
} else throw new exception('Не инициализирован параметр: from');
|
||||||
|
} else throw new exception('Вы не авторизованы');
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Запись в реестр ошибок
|
||||||
|
$this->errors['confirm'][] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
header('Content-Encoding: none');
|
||||||
|
header('X-Accel-Buffering: no');
|
||||||
|
|
||||||
|
// Инициализация буфера вывода
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
// Генерация ответа
|
||||||
|
echo json_encode(
|
||||||
|
[
|
||||||
|
'errors' => self::parse_only_text($this->errors)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Length: ' . ob_get_length());
|
||||||
|
|
||||||
|
// Отправка и деинициализация буфера вывода
|
||||||
|
ob_end_flush();
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -558,15 +558,15 @@ final class task extends core
|
||||||
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
||||||
|
|
||||||
// Заявка уже начата?
|
// Заявка уже начата?
|
||||||
if (time() - $start > 0)
|
if (time() - $start > 0 && time() - $end < 0)
|
||||||
throw new exception('Запрещено редактировать начатую заявку');
|
throw new exception('Запрещено редактировать начатую заявку');
|
||||||
|
|
||||||
// Заявка уже прошла?
|
// Заявка уже прошла?
|
||||||
if (time() - $end > 0)
|
else if (time() - $end > 0 && $task->completed !== true)
|
||||||
throw new exception('Запрещено редактировать прошедшую заявку');
|
throw new exception('Запрещено редактировать прошедшую заявку');
|
||||||
|
|
||||||
// Заявка уже завершена?
|
// Заявка уже завершена?
|
||||||
if ($task->completed === true)
|
else if ($task->completed === true)
|
||||||
throw new exception('Запрещено редактировать завершённую заявку');
|
throw new exception('Запрещено редактировать завершённую заявку');
|
||||||
|
|
||||||
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
||||||
|
@ -861,7 +861,7 @@ final class task extends core
|
||||||
// Перевод ключей на русский язык
|
// Перевод ключей на русский язык
|
||||||
foreach ($this->view->task as $key => $value)
|
foreach ($this->view->task as $key => $value)
|
||||||
if ($key === 'updates')
|
if ($key === 'updates')
|
||||||
foreach ($value as $key => $value) $buffer['updates'][$key] = [
|
foreach ($value ?? [] as $key => $value) $buffer['updates'][$key] = [
|
||||||
'label' => match ($key) {
|
'label' => match ($key) {
|
||||||
'operator' => 'Оператор',
|
'operator' => 'Оператор',
|
||||||
'market' => 'Магазин',
|
'market' => 'Магазин',
|
||||||
|
@ -1473,31 +1473,41 @@ final class task extends core
|
||||||
// Иниализация сотрудника
|
// Иниализация сотрудника
|
||||||
$worker = worker::read('d.id == "' . $task->worker . '"');
|
$worker = worker::read('d.id == "' . $task->worker . '"');
|
||||||
|
|
||||||
// Инициализация магазина
|
if ($worker instanceof _document) {
|
||||||
$market = market::read('d.id == "' . $task->market . '"');
|
// Найден сотрудник
|
||||||
|
|
||||||
// Подсчёт часов работы
|
// Инициализация магазина
|
||||||
$hours = model::hours($task->start, $task->end, $this->errors);
|
$market = market::read('d.id == "' . $task->market . '"');
|
||||||
|
|
||||||
// Инициализация цены работы за 1 час
|
if ($market instanceof _document) {
|
||||||
$hour = payments::hour($market->city, $task->work);
|
// Найден магазин
|
||||||
|
|
||||||
// Подсчёт оплаты за работу
|
// Подсчёт часов работы
|
||||||
$payment = $hour * $hours;
|
$hours = model::hours($task->start, $task->end, $this->errors);
|
||||||
|
|
||||||
// Инициализация штрафа
|
// Инициализация цены работы сотрудника за 1 час
|
||||||
$penalty = payments::penalty($task->rating ?? null);
|
$hour = payments::hour('worker', $market->city, $task->work);
|
||||||
|
|
||||||
// Инициализация премии
|
// Подсчёт оплаты за работу
|
||||||
$bonus = payments::bonus($task->rating ?? null);
|
$payment = $hour * $hours;
|
||||||
|
|
||||||
// Инициализация транзакции к оплате сотруднику
|
// Инициализация штрафа
|
||||||
model::transaction(
|
$penalty = payments::penalty($task->rating ?? null);
|
||||||
$task->getId(),
|
if ($penalty === null) $penalty = -$payment;
|
||||||
$worker->getId(),
|
|
||||||
$payment - ($penalty === null ? $payment : -$penalty) + $bonus,
|
// Инициализация премии
|
||||||
$this->errors
|
$bonus = payments::bonus($task->rating ?? null);
|
||||||
);
|
|
||||||
|
// Запись результатов
|
||||||
|
$task->result = [
|
||||||
|
'hours' => $hours,
|
||||||
|
'hour' => $hour,
|
||||||
|
'penalty' => $penalty,
|
||||||
|
'bonus' => $bonus,
|
||||||
|
'processed' => false
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Запись в реcстре последних обновивших
|
// Запись в реcстре последних обновивших
|
||||||
|
@ -1709,15 +1719,15 @@ final class task extends core
|
||||||
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
||||||
|
|
||||||
// Заявка уже начата?
|
// Заявка уже начата?
|
||||||
if (time() - $start > 0)
|
if (time() - $start > 0 && time() - $end < 0)
|
||||||
throw new exception('Запрещено удалять начатую заявку');
|
throw new exception('Запрещено удалять начатую заявку');
|
||||||
|
|
||||||
// Заявка уже прошла?
|
// Заявка уже прошла?
|
||||||
if (time() - $end > 0)
|
else if (time() - $end > 0 && $task->completed !== true)
|
||||||
throw new exception('Запрещено удалять прошедшую заявку');
|
throw new exception('Запрещено удалять прошедшую заявку');
|
||||||
|
|
||||||
// Заявка уже завершена?
|
// Заявка уже завершена?
|
||||||
if ($task->completed === true)
|
else if ($task->completed === true)
|
||||||
throw new exception('Запрещено удалять завершённую заявку');
|
throw new exception('Запрещено удалять завершённую заявку');
|
||||||
|
|
||||||
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
||||||
|
@ -2092,15 +2102,15 @@ final class task extends core
|
||||||
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
||||||
|
|
||||||
// Заявка уже начата?
|
// Заявка уже начата?
|
||||||
if (time() - $start > 0)
|
if (time() - $start > 0 && time() - $end < 0)
|
||||||
throw new exception('Запрещено редактировать тип работы начатой заявки');
|
throw new exception('Запрещено редактировать тип работы начатой заявки');
|
||||||
|
|
||||||
// Заявка уже прошла?
|
// Заявка уже прошла?
|
||||||
if (time() - $end > 0)
|
else if (time() - $end > 0 && $task->completed !== true)
|
||||||
throw new exception('Запрещено редактировать тип работы прошедшей заявки');
|
throw new exception('Запрещено редактировать тип работы прошедшей заявки');
|
||||||
|
|
||||||
// Заявка уже завершена?
|
// Заявка уже завершена?
|
||||||
if ($task->completed === true)
|
else if ($task->completed === true)
|
||||||
throw new exception('Запрещено редактировать тип работы завершённой заявки');
|
throw new exception('Запрещено редактировать тип работы завершённой заявки');
|
||||||
|
|
||||||
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
||||||
|
@ -2348,15 +2358,15 @@ final class task extends core
|
||||||
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
||||||
|
|
||||||
// Заявка уже начата?
|
// Заявка уже начата?
|
||||||
if (time() - $start > 0)
|
if (time() - $start > 0 && time() - $end < 0)
|
||||||
throw new exception('Запрещено редактировать дату и время начатой заявки');
|
throw new exception('Запрещено редактировать дату и время начатой заявки');
|
||||||
|
|
||||||
// Заявка уже прошла?
|
// Заявка уже прошла?
|
||||||
if (time() - $end > 0)
|
else if (time() - $end > 0 && $task->completed !== true)
|
||||||
throw new exception('Запрещено редактировать дату и время прошедшей заявки');
|
throw new exception('Запрещено редактировать дату и время прошедшей заявки');
|
||||||
|
|
||||||
// Заявка уже завершена?
|
// Заявка уже завершена?
|
||||||
if ($task->completed === true)
|
else if ($task->completed === true)
|
||||||
throw new exception('Запрещено редактировать дату и время завершённой заявки');
|
throw new exception('Запрещено редактировать дату и время завершённой заявки');
|
||||||
|
|
||||||
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
||||||
|
|
|
@ -146,41 +146,55 @@ final class worker extends core
|
||||||
? null
|
? null
|
||||||
: <<<AQL
|
: <<<AQL
|
||||||
SEARCH
|
SEARCH
|
||||||
a.commentary IN TOKENS(@search, 'text_ru')
|
b.commentary IN TOKENS(@search, 'text_ru')
|
||||||
|| a.address IN TOKENS(@search, 'text_ru')
|
|| b.address IN TOKENS(@search, 'text_ru')
|
||||||
|| a.passport IN TOKENS(@search, 'text_ru')
|
|| b.passport IN TOKENS(@search, 'text_ru')
|
||||||
|| a.department.address IN TOKENS(@search, 'text_ru')
|
|| b.department.address IN TOKENS(@search, 'text_ru')
|
||||||
|| a.requisites IN TOKENS(@search, 'text_ru')
|
|| b.requisites IN TOKENS(@search, 'text_ru')
|
||||||
|| STARTS_WITH(a._key, @search)
|
|| STARTS_WITH(a._key, @search)
|
||||||
|| STARTS_WITH(a.id, @search)
|
|| STARTS_WITH(a.id, @search)
|
||||||
|| STARTS_WITH(a.name.first, @search)
|
|| STARTS_WITH(a.name.first, @search)
|
||||||
|| STARTS_WITH(a.name.second, @search)
|
|| STARTS_WITH(a.name.second, @search)
|
||||||
|| STARTS_WITH(a.name.last, @search)
|
|| STARTS_WITH(a.name.last, @search)
|
||||||
|| STARTS_WITH(a.address, @search)
|
|| STARTS_WITH(b._key, @search)
|
||||||
|| STARTS_WITH(a.city, @search)
|
|| STARTS_WITH(b.id, @search)
|
||||||
|| STARTS_WITH(a.district, @search)
|
|| STARTS_WITH(b.name.first, @search)
|
||||||
|
|| STARTS_WITH(b.name.second, @search)
|
||||||
|
|| STARTS_WITH(b.name.last, @search)
|
||||||
|
|| STARTS_WITH(b.address, @search)
|
||||||
|
|| STARTS_WITH(b.city, @search)
|
||||||
|
|| STARTS_WITH(b.district, @search)
|
||||||
|| STARTS_WITH(a.number, @search)
|
|| STARTS_WITH(a.number, @search)
|
||||||
|
|| STARTS_WITH(b.number, @search)
|
||||||
|| STARTS_WITH(a.mail, @search)
|
|| STARTS_WITH(a.mail, @search)
|
||||||
|| STARTS_WITH(a.passport, @search)
|
|| STARTS_WITH(b.mail, @search)
|
||||||
|| STARTS_WITH(a.department.number, @search)
|
|| STARTS_WITH(b.passport, @search)
|
||||||
|| STARTS_WITH(a.department.address, @search)
|
|| STARTS_WITH(b.department.number, @search)
|
||||||
|| STARTS_WITH(a.requisites, @search)
|
|| STARTS_WITH(b.department.address, @search)
|
||||||
|| STARTS_WITH(a.tax, @search)
|
|| STARTS_WITH(b.requisites, @search)
|
||||||
|
|| STARTS_WITH(b.tax, @search)
|
||||||
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(a._key, TOKENS(@search, 'text_en')[0], 2, true))
|
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(a._key, TOKENS(@search, 'text_en')[0], 2, true))
|
||||||
|| (LENGTH(@search) > 4 && LEVENSHTEIN_MATCH(a.id, TOKENS(@search, 'text_en')[0], 1, true))
|
|| (LENGTH(@search) > 4 && LEVENSHTEIN_MATCH(a.id, TOKENS(@search, 'text_en')[0], 1, true))
|
||||||
|| (LENGTH(@search) > 3 && LEVENSHTEIN_MATCH(a.name.first, TOKENS(@search, 'text_ru')[0], 2, true))
|
|| (LENGTH(@search) > 3 && LEVENSHTEIN_MATCH(a.name.first, TOKENS(@search, 'text_ru')[0], 2, true))
|
||||||
|| (LENGTH(@search) > 3 && LEVENSHTEIN_MATCH(a.name.second, TOKENS(@search, 'text_ru')[0], 2, true))
|
|| (LENGTH(@search) > 3 && LEVENSHTEIN_MATCH(a.name.second, TOKENS(@search, 'text_ru')[0], 2, true))
|
||||||
|| (LENGTH(@search) > 3 && LEVENSHTEIN_MATCH(a.name.last, TOKENS(@search, 'text_ru')[0], 2, true))
|
|| (LENGTH(@search) > 3 && LEVENSHTEIN_MATCH(a.name.last, TOKENS(@search, 'text_ru')[0], 2, true))
|
||||||
|| (LENGTH(@search) > 7 && LEVENSHTEIN_MATCH(a.address, TOKENS(@search, 'text_ru')[0], 2, true))
|
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(b._key, TOKENS(@search, 'text_en')[0], 2, true))
|
||||||
|| (LENGTH(@search) > 4 && LEVENSHTEIN_MATCH(a.city, TOKENS(@search, 'text_ru')[0], 1, true))
|
|| (LENGTH(@search) > 4 && LEVENSHTEIN_MATCH(b.id, TOKENS(@search, 'text_en')[0], 1, true))
|
||||||
|| (LENGTH(@search) > 4 && LEVENSHTEIN_MATCH(a.district, TOKENS(@search, 'text_ru')[0], 1, true))
|
|| (LENGTH(@search) > 3 && LEVENSHTEIN_MATCH(b.name.first, TOKENS(@search, 'text_ru')[0], 2, true))
|
||||||
|
|| (LENGTH(@search) > 3 && LEVENSHTEIN_MATCH(b.name.second, TOKENS(@search, 'text_ru')[0], 2, true))
|
||||||
|
|| (LENGTH(@search) > 3 && LEVENSHTEIN_MATCH(b.name.last, TOKENS(@search, 'text_ru')[0], 2, true))
|
||||||
|
|| (LENGTH(@search) > 7 && LEVENSHTEIN_MATCH(b.address, TOKENS(@search, 'text_ru')[0], 2, true))
|
||||||
|
|| (LENGTH(@search) > 4 && LEVENSHTEIN_MATCH(b.city, TOKENS(@search, 'text_ru')[0], 1, true))
|
||||||
|
|| (LENGTH(@search) > 4 && LEVENSHTEIN_MATCH(b.district, TOKENS(@search, 'text_ru')[0], 1, true))
|
||||||
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(a.number, TOKENS(@search, 'text_en')[0], 2, true))
|
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(a.number, TOKENS(@search, 'text_en')[0], 2, true))
|
||||||
|
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(b.number, TOKENS(@search, 'text_en')[0], 2, true))
|
||||||
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(a.mail, TOKENS(@search, 'text_en')[0], 2, true))
|
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(a.mail, TOKENS(@search, 'text_en')[0], 2, true))
|
||||||
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(a.passport, TOKENS(@search, 'text_ru')[0], 1, true))
|
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(b.mail, TOKENS(@search, 'text_en')[0], 2, true))
|
||||||
|| (LENGTH(@search) > 6 && LEVENSHTEIN_MATCH(a.department.number, TOKENS(@search, 'text_en')[0], 1, true))
|
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(b.passport, TOKENS(@search, 'text_ru')[0], 1, true))
|
||||||
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(a.department.address, TOKENS(@search, 'text_ru')[0], 1, true))
|
|| (LENGTH(@search) > 6 && LEVENSHTEIN_MATCH(b.department.number, TOKENS(@search, 'text_en')[0], 1, true))
|
||||||
|| (LENGTH(@search) > 4 && LEVENSHTEIN_MATCH(a.requisites, TOKENS(@search, 'text_ru')[0], 1, true))
|
|| (LENGTH(@search) > 5 && LEVENSHTEIN_MATCH(b.department.address, TOKENS(@search, 'text_ru')[0], 1, true))
|
||||||
|| (LENGTH(@search) > 7 && LEVENSHTEIN_MATCH(a.tax, TOKENS(@search, 'text_ru')[0], 1, true))
|
|| (LENGTH(@search) > 4 && LEVENSHTEIN_MATCH(b.requisites, TOKENS(@search, 'text_ru')[0], 1, true))
|
||||||
|
|| (LENGTH(@search) > 7 && LEVENSHTEIN_MATCH(b.tax, TOKENS(@search, 'text_ru')[0], 1, true))
|
||||||
OPTIONS { collections: ["account", "worker"] }
|
OPTIONS { collections: ["account", "worker"] }
|
||||||
AQL;
|
AQL;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ final class payments extends core
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// Чтение заявок
|
// Чтение заявок
|
||||||
$tasks = @task::read("d.date >= $from && d.date <= $to && d.problematic == false && d.completed == true", amount: 999999, return: '{worker: d.worker, market: d.market, date: d.date, work: d.work, start: d.start, end: d.end, commentary: d.commentary, rating: d.rating, review: d.review}', errors: $errors);
|
$tasks = @task::read("d.date >= $from && d.date <= $to && d.problematic == false && d.completed == true && d.result.processed != true", amount: 999999, return: '{worker: d.worker, market: d.market, date: d.date, work: d.work, start: d.start, end: d.end, commentary: d.commentary, rating: d.rating, review: d.review}', errors: $errors);
|
||||||
|
|
||||||
if (is_array($tasks) && count($tasks) > 0) {
|
if (is_array($tasks) && count($tasks) > 0) {
|
||||||
// Найдены заявки
|
// Найдены заявки
|
||||||
|
@ -208,9 +208,9 @@ final class payments extends core
|
||||||
->setCellValue("M$row", $worker->name['second'] . ' ' . $worker->name['first'] . ' ' . $worker->name['last'])
|
->setCellValue("M$row", $worker->name['second'] . ' ' . $worker->name['first'] . ' ' . $worker->name['last'])
|
||||||
->setCellValue("N$row", $hour = static::hour('worker', $market->city, $task->work))
|
->setCellValue("N$row", $hour = static::hour('worker', $market->city, $task->work))
|
||||||
->setCellValue("O$row", $payment = $hour * $hours)
|
->setCellValue("O$row", $payment = $hour * $hours)
|
||||||
->setCellValue("P$row", ($penalty = static::penalty($task->rating ?? null)) === null ? $payment : $penalty)
|
->setCellValue("P$row", ($penalty = static::penalty($task->rating ?? null)) === null ? -$payment : $penalty)
|
||||||
->setCellValue("Q$row", $bonus = static::bonus($task->rating ?? null))
|
->setCellValue("Q$row", $bonus = static::bonus($task->rating ?? null))
|
||||||
->setCellValue("R$row", $payment + (($penalty = static::penalty($task->rating ?? null)) === null ? $payment : $penalty) + $bonus)
|
->setCellValue("R$row", $payment + ($penalty === null ? -$payment : $penalty) + $bonus)
|
||||||
->setCellValue("S$row", '')
|
->setCellValue("S$row", '')
|
||||||
->setCellValue("T$row", $worker->payment) // Наличные?
|
->setCellValue("T$row", $worker->payment) // Наличные?
|
||||||
->setCellValue("U$row", '')
|
->setCellValue("U$row", '')
|
||||||
|
@ -253,7 +253,7 @@ final class payments extends core
|
||||||
/**
|
/**
|
||||||
* Магазины
|
* Магазины
|
||||||
*
|
*
|
||||||
* Расчитать ... и сгенерировать excel-документ
|
* Расчитать прибыль с магазинов и сгенерировать excel-документ
|
||||||
*
|
*
|
||||||
* @param int $from Начальная дата для выборки заявок (unixtime)
|
* @param int $from Начальная дата для выборки заявок (unixtime)
|
||||||
* @param int $to Конечная дата для выборки заявок (unixtime)
|
* @param int $to Конечная дата для выборки заявок (unixtime)
|
||||||
|
@ -488,7 +488,15 @@ final class payments extends core
|
||||||
// Инкрементация счётчика для генерации следующей строки
|
// Инкрементация счётчика для генерации следующей строки
|
||||||
++$row;
|
++$row;
|
||||||
}
|
}
|
||||||
}
|
} // Чтение заявок
|
||||||
|
$tasks = @task::collect(
|
||||||
|
"d.date >= $from && d.date <= $to && d.problematic == false && d.completed == true",
|
||||||
|
sort: 'd.date DESC',
|
||||||
|
amount: 999999,
|
||||||
|
index: 'd.date',
|
||||||
|
return: '{worker: d.worker, market: d.market, date: d.date, work: d.work, start: d.start, end: d.end, commentary: d.commentary, rating: d.rating, review: d.review}',
|
||||||
|
errors: $errors
|
||||||
|
);
|
||||||
|
|
||||||
// Запись строки с общими данными магазина
|
// Запись строки с общими данными магазина
|
||||||
$spreadsheet
|
$spreadsheet
|
||||||
|
@ -575,6 +583,60 @@ final class payments extends core
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Подтвердить обработку
|
||||||
|
*
|
||||||
|
* Отметить в базе данных то, что выбранные заявки были обработаны
|
||||||
|
*
|
||||||
|
* @param int $from Начальная дата для выборки заявок (unixtime)
|
||||||
|
* @param int $to Конечная дата для выборки заявок (unixtime)
|
||||||
|
* @param string $type Тип документа для подтверждения (workers, markets)
|
||||||
|
* @param array $errors Errors registry
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function confirm(int $from, int $to, string $type, array &$errors = []): bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Чтение заявок
|
||||||
|
$tasks = @task::read("d.date >= $from && d.date <= $to && d.problematic == false && d.completed == true && d.result.processed != true", amount: 999999, errors: $errors);
|
||||||
|
|
||||||
|
if (is_array($tasks) && count($tasks) > 0) {
|
||||||
|
// Найдены заявки
|
||||||
|
|
||||||
|
if ($type === 'workers') {
|
||||||
|
// Подтверждена обработка зарплат сотрудников за выбранный период
|
||||||
|
|
||||||
|
foreach ($tasks as $task) {
|
||||||
|
// Перебор заявок
|
||||||
|
|
||||||
|
// Подтверждение того, что заявка обработана (выплачены деньги сотруднику)
|
||||||
|
$task->result = ['processed' => true] + ($task->result ?? []);
|
||||||
|
|
||||||
|
// Запись обновления в базу данных
|
||||||
|
core::update($task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
throw new exception('Не найдены заявки');
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Write to the errors registry
|
||||||
|
$errors[] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit (fail)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine tariff
|
* Determine tariff
|
||||||
|
|
|
@ -259,7 +259,7 @@ final class task extends core
|
||||||
public static function transaction(
|
public static function transaction(
|
||||||
string $task,
|
string $task,
|
||||||
string $worker,
|
string $worker,
|
||||||
int $amount = 0,
|
int|float $amount = 0,
|
||||||
array &$errors = []
|
array &$errors = []
|
||||||
): ?string {
|
): ?string {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -44,6 +44,12 @@ div#popup>section.list>div.row.endless {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
section.panel.list> :is(form, search).row.menu>label>div:has(>button) {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
section.panel.list> :is(form, search).row.menu>label>button {
|
section.panel.list> :is(form, search).row.menu>label>button {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -49,6 +49,9 @@ $router->write('/workers/create', 'worker', 'create', 'POST');
|
||||||
$router->write('/market/$market/read', 'task', 'market', 'POST');
|
$router->write('/market/$market/read', 'task', 'market', 'POST');
|
||||||
$router->write('/market/$id/fields', 'market', 'fields', 'POST');
|
$router->write('/market/$id/fields', 'market', 'fields', 'POST');
|
||||||
$router->write('/market/$id/update', 'market', 'update', 'POST');
|
$router->write('/market/$id/update', 'market', 'update', 'POST');
|
||||||
|
$router->write('/market/ban/$worker', 'market', 'ban', 'POST');
|
||||||
|
$router->write('/market/unban/$worker', 'market', 'unban', 'POST');
|
||||||
|
$router->write('/market/banned/$worker', 'market', 'banned', 'POST');
|
||||||
$router->write('/markets', 'market', 'index', 'GET');
|
$router->write('/markets', 'market', 'index', 'GET');
|
||||||
$router->write('/markets', 'market', 'index', 'POST');
|
$router->write('/markets', 'market', 'index', 'POST');
|
||||||
$router->write('/markets/read', 'market', 'read', 'POST');
|
$router->write('/markets/read', 'market', 'read', 'POST');
|
||||||
|
@ -103,6 +106,7 @@ $router->write('/task/$task/chat/send', 'task', 'message', 'POST');
|
||||||
$router->write('/elements/menu', 'index', 'menu', 'POST');
|
$router->write('/elements/menu', 'index', 'menu', 'POST');
|
||||||
$router->write('/payments/workers', 'payments', 'workers', 'POST');
|
$router->write('/payments/workers', 'payments', 'workers', 'POST');
|
||||||
$router->write('/payments/markets', 'payments', 'markets', 'POST');
|
$router->write('/payments/markets', 'payments', 'markets', 'POST');
|
||||||
|
$router->write('/payments/confirm/$type', 'payments', 'confirm', 'POST');
|
||||||
|
|
||||||
// Инициализация ядра
|
// Инициализация ядра
|
||||||
$core = new core(namespace: __NAMESPACE__, router: $router, controller: new controller(false), model: new model(false));
|
$core = new core(namespace: __NAMESPACE__, router: $router, controller: new controller(false), model: new model(false));
|
||||||
|
|
|
@ -185,10 +185,7 @@ if (typeof window.loader !== "function") {
|
||||||
*
|
*
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
static async account() {
|
static async account(account = Cookies.get(`account_id`) ?? "account") {
|
||||||
// Initialization of the account identifier
|
|
||||||
account = Cookies.get(`account_id`) ?? "account";
|
|
||||||
|
|
||||||
return await fetch(`/${account}`, {
|
return await fetch(`/${account}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -198,10 +195,10 @@ if (typeof window.loader !== "function") {
|
||||||
.then((response) => response.text())
|
.then((response) => response.text())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
// Write path in history
|
// Write path in history
|
||||||
history.pushState(this.storage, "/account", "/account");
|
history.pushState(this.storage, `/${account}`, `/${account}`);
|
||||||
|
|
||||||
// Write path to the current directory buffer
|
// Write path to the current directory buffer
|
||||||
core.page = 'account';
|
core.page = account;
|
||||||
|
|
||||||
// Write content in document
|
// Write content in document
|
||||||
document.body.getElementsByTagName("main")[0].innerHTML = data;
|
document.body.getElementsByTagName("main")[0].innerHTML = data;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -52,8 +52,8 @@ if (typeof window.payments !== "function") {
|
||||||
|
|
||||||
if (header !== null) {
|
if (header !== null) {
|
||||||
// Найден заголовок (подразумевается, что передан файл, а не случайная ошибка)
|
// Найден заголовок (подразумевается, что передан файл, а не случайная ошибка)
|
||||||
|
|
||||||
// Инициализация названия файла
|
// Инициализация названия файла
|
||||||
const name = header.split(";")[1].split("=")[1];
|
const name = header.split(";")[1].split("=")[1];
|
||||||
|
|
||||||
// Чтение полученного файла (подразумевается ошибка при инициализации json)
|
// Чтение полученного файла (подразумевается ошибка при инициализации json)
|
||||||
|
@ -129,7 +129,7 @@ if (typeof window.payments !== "function") {
|
||||||
if (header !== null) {
|
if (header !== null) {
|
||||||
// Найден заголовок (подразумевается, что передан файл, а не случайная ошибка)
|
// Найден заголовок (подразумевается, что передан файл, а не случайная ошибка)
|
||||||
|
|
||||||
// Инициализация названия файла
|
// Инициализация названия файла
|
||||||
const name = header.split(";")[1].split("=")[1];
|
const name = header.split(";")[1].split("=")[1];
|
||||||
|
|
||||||
// Чтение полученного файла (подразумевается ошибка при инициализации json)
|
// Чтение полученного файла (подразумевается ошибка при инициализации json)
|
||||||
|
@ -157,6 +157,53 @@ if (typeof window.payments !== "function") {
|
||||||
});
|
});
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Подтвердить обработку документа
|
||||||
|
*
|
||||||
|
* @param {string} type Тип обработанного документа (workers, markets)
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
static confirm = damper((type) => {
|
||||||
|
// Инициализация оболочки фильтров
|
||||||
|
const filters = document.getElementById("filters").children[0];
|
||||||
|
|
||||||
|
tasks
|
||||||
|
.filter("from", new Date(filters.children[0].value) / 1000, null, true)
|
||||||
|
.then(() => {
|
||||||
|
tasks
|
||||||
|
.filter(
|
||||||
|
"to",
|
||||||
|
new Date(filters.children[1].value) / 1000,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
// Запрос к серверу
|
||||||
|
fetch(`/payments/confirm/${type}`, { method: "POST" }).then(
|
||||||
|
(response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
// Сервер вернул код успешного выполнения
|
||||||
|
|
||||||
|
response
|
||||||
|
.clone()
|
||||||
|
.json()
|
||||||
|
.then(
|
||||||
|
(data) => {
|
||||||
|
if (this.errors(data.errors)) {
|
||||||
|
// Сгенерированы ошибки
|
||||||
|
} else {
|
||||||
|
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, 200);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сгенерировать HTML-элемент со списком ошибок
|
* Сгенерировать HTML-элемент со списком ошибок
|
||||||
*
|
*
|
||||||
|
|
|
@ -2210,34 +2210,6 @@ if (typeof window.tasks !== "function") {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Инициализация оболочки для кнопок
|
|
||||||
const buttons_worker = document.createElement("div");
|
|
||||||
buttons_worker.classList.add("row", "buttons", "divided", "merged");
|
|
||||||
|
|
||||||
// Инициализация кнопки подтверждения
|
|
||||||
const ban = document.createElement("button");
|
|
||||||
if (true) {
|
|
||||||
// Забанен сотрудник
|
|
||||||
|
|
||||||
ban.classList.add("earth", "stretched");
|
|
||||||
ban.innerText = "Разблокировать";
|
|
||||||
ban.setAttribute('title', 'Сотрудник снова сможет записываться на ваши заявки');
|
|
||||||
ban.setAttribute(
|
|
||||||
"onclick",
|
|
||||||
`tasks.unban(this, this.parentElement.previousElementSibling.previousElementSibling.children[0], this.parentElement.previousElementSibling, document.getElementById('${task}'))`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// Не забанен сотрудник
|
|
||||||
|
|
||||||
ban.classList.add("clay", "stretched");
|
|
||||||
ban.innerText = "Заблокировать";
|
|
||||||
ban.setAttribute('title', 'Сотрудник не сможет записываться на ваши заявки');
|
|
||||||
ban.setAttribute(
|
|
||||||
"onclick",
|
|
||||||
`tasks.ban(this, this.parentElement.previousElementSibling.previousElementSibling.children[0], this.parentElement.previousElementSibling, document.getElementById('${task}'))`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Инициализация оболочки для кнопок
|
// Инициализация оболочки для кнопок
|
||||||
const buttons = document.createElement("div");
|
const buttons = document.createElement("div");
|
||||||
buttons.classList.add("row", "buttons", "merged");
|
buttons.classList.add("row", "buttons", "merged");
|
||||||
|
@ -2325,8 +2297,61 @@ if (typeof window.tasks !== "function") {
|
||||||
if (data.completed !== true) {
|
if (data.completed !== true) {
|
||||||
// Зявка не завершена
|
// Зявка не завершена
|
||||||
|
|
||||||
buttons_worker.appendChild(ban);
|
if (typeof window.markets === "function") {
|
||||||
column.appendChild(buttons_worker);
|
// Инициализирована программа-обработчик магазинов (подразумевается)
|
||||||
|
|
||||||
|
// Инициализация оболочки для кнопок
|
||||||
|
const buttons_worker = document.createElement("div");
|
||||||
|
buttons_worker.classList.add(
|
||||||
|
"row",
|
||||||
|
"buttons",
|
||||||
|
"divided",
|
||||||
|
"merged"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Инициализация кнопки подтверждения
|
||||||
|
const ban = document.createElement("button");
|
||||||
|
|
||||||
|
// Инициализация идентификатора сотрудника
|
||||||
|
const worker = row.querySelector(
|
||||||
|
'[data-column="worker"]'
|
||||||
|
).innerText;
|
||||||
|
|
||||||
|
markets.banned(worker).then((banned) => {
|
||||||
|
if (banned) {
|
||||||
|
// Забанен сотрудник
|
||||||
|
|
||||||
|
ban.classList.add("earth", "stretched");
|
||||||
|
ban.innerText = "Разблокировать";
|
||||||
|
ban.setAttribute(
|
||||||
|
"title",
|
||||||
|
"Сотрудник снова сможет записываться на заявки"
|
||||||
|
);
|
||||||
|
ban.setAttribute(
|
||||||
|
"onclick",
|
||||||
|
`markets.unban(${worker}, this)`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Не забанен сотрудник
|
||||||
|
|
||||||
|
ban.classList.add("clay", "stretched");
|
||||||
|
ban.innerText = "Заблокировать";
|
||||||
|
ban.setAttribute(
|
||||||
|
"title",
|
||||||
|
"Сотрудник не сможет записываться на заявки"
|
||||||
|
);
|
||||||
|
ban.setAttribute(
|
||||||
|
"onclick",
|
||||||
|
`markets.ban(${worker}, this)`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons_worker.appendChild(ban);
|
||||||
|
column.insertBefore(buttons_worker, buttons);
|
||||||
|
|
||||||
|
top(this.body.errors);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
buttons.appendChild(problem);
|
buttons.appendChild(problem);
|
||||||
buttons.appendChild(complete);
|
buttons.appendChild(complete);
|
||||||
|
@ -2607,7 +2632,7 @@ if (typeof window.tasks !== "function") {
|
||||||
this.works(task).then((html) => (work.innerHTML = html));
|
this.works(task).then((html) => (work.innerHTML = html));
|
||||||
work.setAttribute("title", "Тип работы");
|
work.setAttribute("title", "Тип работы");
|
||||||
work.setAttribute(
|
work.setAttribute(
|
||||||
'onchange',
|
"onchange",
|
||||||
`tasks.work(document.getElementById('${task}'), this)`
|
`tasks.work(document.getElementById('${task}'), this)`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2948,12 +2973,11 @@ if (typeof window.tasks !== "function") {
|
||||||
core.interface === "administrator"
|
core.interface === "administrator"
|
||||||
) {
|
) {
|
||||||
// Оператор или администратор
|
// Оператор или администратор
|
||||||
|
|
||||||
// Активация виртуальной кнопки "подтвердить"
|
// Активация виртуальной кнопки "подтвердить"
|
||||||
confirm.click();
|
confirm.click();
|
||||||
} else {
|
} else {
|
||||||
// Магазин или сотрудник
|
// Магазин или сотрудник
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Возвращение статуса блокировки закрытия окна
|
// Возвращение статуса блокировки закрытия окна
|
||||||
|
|
|
@ -31,8 +31,11 @@
|
||||||
</li> -->
|
</li> -->
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li id="account">
|
<li id="account">
|
||||||
<button class="transparent" onclick="loader.profile()" title="Настройки профиля">{{ account.name.first }} {{
|
<button class="transparent" onclick="loader.account({{ account.getKey() }})">{%
|
||||||
account.name.second }}</button>
|
if account.name.first is not empty %}{{
|
||||||
|
account.name.first|slice(0, 1)|upper }}.{% endif %}{% if account.name.last is not empty %} {{
|
||||||
|
account.name.last|slice(0, 1)|upper }}.{% endif %}{% if account.name.second is not empty %} {{
|
||||||
|
account.name.second }}{% endif %}</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
{% extends('index.html') %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/list.css">
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/pages/account.css">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<section id="account" class="panel small list">
|
||||||
|
<section id="information">
|
||||||
|
<!-- <h1>{% if account.name.first is not empty %}{{ account.name.first }}{% endif %}{% if account.name.second is not
|
||||||
|
empty
|
||||||
|
%} {{ account.name.second }}{% endif %}{% if account.name.last is not empty %} {{ account.name.last }}{% endif %}
|
||||||
|
</h1> -->
|
||||||
|
<h2>{{ account.getKey() }}</h2>
|
||||||
|
</section>
|
||||||
|
<section id="balance">
|
||||||
|
<p><b>Баланс:</b> <span>{{ balance ?? 0 }}</span></p>
|
||||||
|
</section>
|
||||||
|
<section id="history">
|
||||||
|
{% for entry in history %}
|
||||||
|
<p class="{% if entry.task.result.processed %}processed{% endif %}"><b>{{ entry.task._key }}</b><span>{{
|
||||||
|
entry.task.work }}</span><span>{{ entry.task.result.hours ?? 0 }} часов</span><span>{{ entry.task.result.hour ??
|
||||||
|
0 * entry.task.result.hours ?? 0 }}р.</span><span>{{ entry.task.result.penalty ?? 0 }}р (штраф)</span><span>{{
|
||||||
|
entry.task.result.bonus ?? 0 }}р. (бонус)</span><span>{{ entry.task.result.hour ?? 0 * entry.task.result.hours
|
||||||
|
?? 0 + entry.task.result.penalty ?? 0 + entry.task.result.bonus ?? 0 }}р. (итого)</span></p>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
<script type="text/javascript" data-reinitializer-once="true" src="/js/imask-7.1.0-alpha.js" defer></script>
|
||||||
|
<script type="text/javascript" src="/js/account.js" defer></script>
|
||||||
|
{% endblock %}
|
|
@ -21,8 +21,14 @@
|
||||||
<button class="grass dense" onclick="tasks.create()">Создать</button>
|
<button class="grass dense" onclick="tasks.create()">Создать</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if account.type == 'administrator' or account.type == 'operator' %}
|
{% if account.type == 'administrator' or account.type == 'operator' %}
|
||||||
<button class="sea" onclick="payments.workers()">Сотрудники</button>
|
<div>
|
||||||
<button class="sea" onclick="payments.markets()">Магазины</button>
|
<button class="sea merged right" onclick="payments.workers()">Сотрудники</button>
|
||||||
|
<button class="river merged left" onclick="payments.confirm('workers')">Подтвердить</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button class="sea merged right" onclick="payments.markets()">Магазины</button>
|
||||||
|
<button class="river merged left" onclick="payments.confirm('markets')">Подтвердить</button>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</label>
|
</label>
|
||||||
</form>
|
</form>
|
||||||
|
|
Reference in New Issue