Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
46ff0a1d9b | |||
cb5abd9358 | |||
efb85a2609 | |||
03391a1269 |
@@ -359,7 +359,7 @@ final class market extends core
|
||||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных магазина
|
||||
$market = model::read('d.id == "' . $parameters['id'] . '"', return: '{ name: d.name, number: d.number, mail: d.mail, type: d.type, city: d.city, district: d.district, address: d.address}')->getAll();
|
||||
$market = model::read('d.id == "' . urldecode($parameters['id']) . '"', return: '{ name: d.name, number: d.number, mail: d.mail, type: d.type, city: d.city, district: d.district, address: d.address}')->getAll();
|
||||
|
||||
if (!empty($market)) {
|
||||
// Найдены данные магазина
|
||||
@@ -399,7 +399,7 @@ final class market extends core
|
||||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных магазина
|
||||
$market = model::read('d.id == "' . $parameters['id'] . '"');
|
||||
$market = model::read('d.id == "' . urldecode($parameters['id']) . '"');
|
||||
|
||||
if (!empty($market)) {
|
||||
// Найден магазин
|
||||
|
@@ -364,8 +364,8 @@ final class session extends core
|
||||
|
||||
// Проверка параметров на соответствование требованиям
|
||||
if ($length === 0) throw new exception('Идентификатор аккаунта аккаунта не может быть пустым');
|
||||
if ($length > 40) throw new exception('Идентификатор аккаунта аккаунта должен иметь не более 40 символов');
|
||||
if (preg_match_all('/[^\d\(\)\-\s\r\n\t\0]+/u', $parameters['market'], $matches) > 0) throw new exception('Нельзя использовать символы: ' . implode(', ', ...$matches ?? []));
|
||||
if ($length > 3) throw new exception('Идентификатор аккаунта аккаунта должен иметь не более 3 символов');
|
||||
if (preg_match_all('/[^\d]+/u', $parameters['market'], $matches) > 0) throw new exception('Нельзя использовать символы: ' . implode(', ', ...$matches ?? []));
|
||||
|
||||
if ($remember = isset($parameters['remember']) && $parameters['remember'] === '1') {
|
||||
// Запрошено запоминание
|
||||
|
@@ -11,6 +11,7 @@ use mirzaev\ebala\controllers\core,
|
||||
mirzaev\ebala\models\account,
|
||||
mirzaev\ebala\models\worker,
|
||||
mirzaev\ebala\models\market,
|
||||
mirzaev\ebala\models\payments,
|
||||
mirzaev\ebala\models\core as _core;
|
||||
|
||||
// Библиотека для ArangoDB
|
||||
@@ -542,8 +543,46 @@ final class task extends core
|
||||
// Заявка подтверждена?
|
||||
if ($task->confirmed) throw new exception('Запрещено редактировать подтверждённую заявку');
|
||||
|
||||
// Заявка завершена?
|
||||
if ($this->account->type === 'market' && $task->completed) throw new exception('Запрещено редактировать завершённую заявку');
|
||||
if ($this->account->type === 'market') {
|
||||
// Магазин
|
||||
|
||||
// Инициализация даты
|
||||
$date = (new DateTime('@' . $task->date))->setTimezone(new DateTimeZone('Asia/Krasnoyarsk'));
|
||||
|
||||
// Инициализация времени
|
||||
$start = datetime::createFromFormat('H:i', (string) $task->start);
|
||||
$end = datetime::createFromFormat('H:i', (string) $task->end);
|
||||
|
||||
// Перенос времени в дату
|
||||
$start = $date->setTime((int) $start->format('H'), (int) $start->format('i'))->format('U');
|
||||
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
||||
|
||||
// Заявка уже начата?
|
||||
if (time() - $start > 0)
|
||||
throw new exception('Запрещено редактировать начатую заявку');
|
||||
|
||||
// Заявка уже прошла?
|
||||
if (time() - $end > 0)
|
||||
throw new exception('Запрещено редактировать прошедшую заявку');
|
||||
|
||||
// Заявка уже завершена?
|
||||
if ($task->completed === true)
|
||||
throw new exception('Запрещено редактировать завершённую заявку');
|
||||
|
||||
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
||||
/* if (time() - $task->created > 1800)
|
||||
throw new exception('Запрещено редактировать заявку спустя 30 минут после создания'); */
|
||||
|
||||
// До начала заявки осталось менее 16 часов? (57600 секунд = 16 часов)
|
||||
if ($start - time() < 57600)
|
||||
throw new exception('Запрещено редактировать заявку за менее 16 часов до её начала');
|
||||
}
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (!empty($parameters['worker'])) {
|
||||
// Передан сотрудник
|
||||
@@ -786,7 +825,7 @@ final class task extends core
|
||||
'd._key == "' . $parameters['task'] . '"',
|
||||
return: $this->account->type === 'market'
|
||||
? '{_key: d._key, created: d.created, updated: d.updated, date: d.date, start: d.start, end: d.end, market: d.market, confirmed: d.confirmed, completed: d.completed }'
|
||||
: '{_key: d._key, created: d.created, updated: d.updated, date: d.date, start: d.start, end: d.end, market: d.market, confirmed: d.confirmed, completed: d.completed, hided: d.hided }'
|
||||
: '{_key: d._key, created: d.created, updated: d.updated, date: d.date, start: d.start, end: d.end, market: d.market, confirmed: d.confirmed, completed: d.completed, hided: d.hided, updates: d.updates }'
|
||||
)->getAll();
|
||||
|
||||
// Заявка не принадлежит запросившему магазину?
|
||||
@@ -821,7 +860,18 @@ final class task extends core
|
||||
|
||||
// Перевод ключей на русский язык
|
||||
foreach ($this->view->task as $key => $value)
|
||||
if (match ($key) {
|
||||
if ($key === 'updates')
|
||||
foreach ($value as $key => $value) $buffer['updates'][$key] = [
|
||||
'label' => match ($key) {
|
||||
'operator' => 'Оператор',
|
||||
'market' => 'Магазин',
|
||||
'administrator' => 'Администратор',
|
||||
'worker' => 'Сотрудник',
|
||||
default => $key
|
||||
},
|
||||
'value' => $value
|
||||
];
|
||||
else if (match ($key) {
|
||||
'created', 'updated', 'confirmed', 'hided', 'completed', '_key' => true,
|
||||
'start', 'end' => $passed, // Только для завершённой заявки
|
||||
default => false
|
||||
@@ -909,7 +959,6 @@ final class task extends core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Прочитать данные сотрудника
|
||||
*
|
||||
@@ -958,6 +1007,7 @@ final class task extends core
|
||||
'tax' => 'ИНН',
|
||||
'city' => 'Город',
|
||||
'payment' => 'Форма оплаты',
|
||||
'works' => 'Формы работ',
|
||||
default => $key
|
||||
},
|
||||
'value' => $value
|
||||
@@ -1158,6 +1208,12 @@ final class task extends core
|
||||
// Изменение статуса подтверждения
|
||||
$task->confirmed = !$task->confirmed;
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано изменение в базу данных
|
||||
|
||||
@@ -1277,6 +1333,12 @@ final class task extends core
|
||||
}
|
||||
}
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано изменение в базу данных
|
||||
|
||||
@@ -1392,7 +1454,7 @@ final class task extends core
|
||||
else {
|
||||
// Получена оценка
|
||||
|
||||
// Запись оценики
|
||||
// Запись оценки
|
||||
$task->rating = $parameters['rating'];
|
||||
|
||||
if (!empty($parameters['review'])) {
|
||||
@@ -1407,8 +1469,43 @@ final class task extends core
|
||||
|
||||
// Снятие с публикации
|
||||
$task->published = false;
|
||||
|
||||
// Иниализация сотрудника
|
||||
$worker = worker::read('d.id == "' . $task->worker . '"');
|
||||
|
||||
// Инициализация магазина
|
||||
$market = market::read('d.id == "' . $task->market . '"');
|
||||
|
||||
// Подсчёт часов работы
|
||||
$hours = model::hours($task->start, $task->end, $this->errors);
|
||||
|
||||
// Инициализация цены работы за 1 час
|
||||
$hour = payments::hour($market->city, $task->work);
|
||||
|
||||
// Подсчёт оплаты за работу
|
||||
$payment = $hour * $hours;
|
||||
|
||||
// Инициализация штрафа
|
||||
$penalty = payments::penalty($task->rating ?? null);
|
||||
|
||||
// Инициализация премии
|
||||
$bonus = payments::bonus($task->rating ?? null);
|
||||
|
||||
// Инициализация транзакции к оплате сотруднику
|
||||
model::transaction(
|
||||
$task->getId(),
|
||||
$worker->getId(),
|
||||
$payment - ($penalty === null ? $payment : -$penalty) + $bonus,
|
||||
$this->errors
|
||||
);
|
||||
}
|
||||
|
||||
// Запись в реcстре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано изменение в базу данных
|
||||
|
||||
@@ -1500,6 +1597,12 @@ final class task extends core
|
||||
// Изменение статуса скрытия
|
||||
$task->hided = !$task->hided;
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано изменение в базу данных
|
||||
|
||||
@@ -1591,28 +1694,40 @@ final class task extends core
|
||||
// Заявка подтверждена?
|
||||
if ($task->confirmed) throw new exception('Запрещено удалять подтверждённую заявку');
|
||||
|
||||
// Инициализация даты
|
||||
$date = (new DateTime('@' . $task->date))->setTimezone(new DateTimeZone('Asia/Krasnoyarsk'));
|
||||
if ($this->account->type === 'market') {
|
||||
// Магазин
|
||||
|
||||
// Инициализация времени
|
||||
$start = datetime::createFromFormat('H:i', (string) $task->start);
|
||||
$end = datetime::createFromFormat('H:i', (string) $task->end);
|
||||
// Инициализация даты
|
||||
$date = (new DateTime('@' . $task->date))->setTimezone(new DateTimeZone('Asia/Krasnoyarsk'));
|
||||
|
||||
// Перенос времени в дату
|
||||
$start = $date->setTime((int) $start->format('H'), (int) $start->format('i'))->format('U');
|
||||
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
||||
// Инициализация времени
|
||||
$start = datetime::createFromFormat('H:i', (string) $task->start);
|
||||
$end = datetime::createFromFormat('H:i', (string) $task->end);
|
||||
|
||||
// Заявка уже начата
|
||||
if ($this->account->type === 'market' and time() - $start > 0)
|
||||
throw new exception('Запрещено удалять начатую заявку');
|
||||
// Перенос времени в дату
|
||||
$start = $date->setTime((int) $start->format('H'), (int) $start->format('i'))->format('U');
|
||||
$end = $date->setTime((int) $end->format('H'), (int) $end->format('i'))->format('U');
|
||||
|
||||
// Заявка уже завершена
|
||||
if ($this->account->type === 'market' and $task->completed === true || time() - $end > 0)
|
||||
throw new exception('Запрещено удалять завершённую заявку');
|
||||
// Заявка уже начата?
|
||||
if (time() - $start > 0)
|
||||
throw new exception('Запрещено удалять начатую заявку');
|
||||
|
||||
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
||||
if ($this->account->type === 'market' and time() - $task->created > 1800)
|
||||
throw new exception('Запрещено удалять заявку спустя 30 минут после создания');
|
||||
// Заявка уже прошла?
|
||||
if (time() - $end > 0)
|
||||
throw new exception('Запрещено удалять прошедшую заявку');
|
||||
|
||||
// Заявка уже завершена?
|
||||
if ($task->completed === true)
|
||||
throw new exception('Запрещено удалять завершённую заявку');
|
||||
|
||||
// Прошло более 30 минут после создания заявки? (1800 секунд = 30 минут)
|
||||
/* if (time() - $task->created > 1800)
|
||||
throw new exception('Запрещено удалять заявку спустя 30 минут после создания'); */
|
||||
|
||||
// До начала заявки осталось менее 16 часов? (57600 секунд = 16 часов)
|
||||
if ($start - time() < 57600)
|
||||
throw new exception('Запрещено удалять заявку за менее 16 часов до её начала');
|
||||
}
|
||||
|
||||
if ($task instanceof _document) {
|
||||
// Найдена заявка
|
||||
@@ -1620,6 +1735,12 @@ final class task extends core
|
||||
// Изменение статуса
|
||||
$task->status = 'deleted';
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Помечено как удалённое
|
||||
|
||||
@@ -1761,7 +1882,6 @@ final class task extends core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Прочитать данные работ для <datalist>
|
||||
*
|
||||
@@ -1985,6 +2105,12 @@ final class task extends core
|
||||
default => 'Кассир'
|
||||
};
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано в ArangoDB
|
||||
|
||||
@@ -2101,6 +2227,12 @@ final class task extends core
|
||||
// Изменение статуса
|
||||
$task->description = $parameters['description'];
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано в ArangoDB
|
||||
|
||||
@@ -2212,6 +2344,12 @@ final class task extends core
|
||||
if (!empty($parameters['start'])) $task->start = $parameters['start'];
|
||||
if (!empty($parameters['end'])) $task->end = $parameters['end'];
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано в ArangoDB
|
||||
|
||||
@@ -2299,6 +2437,12 @@ final class task extends core
|
||||
// Запись комментария
|
||||
$task->commentary = $parameters['commentary'];
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано в ArangoDB
|
||||
|
||||
@@ -2386,6 +2530,12 @@ final class task extends core
|
||||
// Запись статуса о публикации
|
||||
$task->published = true;
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано в ArangoDB
|
||||
|
||||
@@ -2473,6 +2623,12 @@ final class task extends core
|
||||
// Запись статуса о публикации
|
||||
$task->published = false;
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано в ArangoDB
|
||||
|
||||
@@ -2822,6 +2978,12 @@ final class task extends core
|
||||
$task->problematic = false;
|
||||
}
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано в ArangoDB
|
||||
|
||||
@@ -2894,6 +3056,12 @@ final class task extends core
|
||||
$task->problematic = false;
|
||||
}
|
||||
|
||||
// Запись в реестре последних обновивших
|
||||
$task->updates = [$this->account->type => match ($this->account->type) {
|
||||
'worker', 'market' => account::{$this->account->type}($this->account->getId())?->id,
|
||||
default => $this->account->getKey()
|
||||
}] + ($task->updates ?? []);
|
||||
|
||||
if (_core::update($task)) {
|
||||
// Записано в ArangoDB
|
||||
|
||||
@@ -2907,7 +3075,6 @@ final class task extends core
|
||||
|
||||
// Инициализация буфера вывода
|
||||
ob_start();
|
||||
|
||||
// Генерация ответа
|
||||
echo json_encode(
|
||||
[
|
||||
|
@@ -396,7 +396,7 @@ final class worker extends core
|
||||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных сотрудника
|
||||
$worker = model::read('d.id == "' . $parameters['id'] . '"', return: '{ name: d.name, number: d.number, mail: d.mail, birth: d.birth, passport: d.passport, issued: d.issued, department: d.department, requisites: d.requisites, payment: d.payment, tax: d.tax, city: d.city, district: d.district, address: d.address, worl: d.work, hiring: d.hiring}')->getAll();
|
||||
$worker = model::read('d.id == "' . urldecode($parameters['id']) . '"', return: '{ name: d.name, number: d.number, mail: d.mail, birth: d.birth, passport: d.passport, issued: d.issued, department: d.department, requisites: d.requisites, payment: d.payment, tax: d.tax, city: d.city, district: d.district, address: d.address, worl: d.work, hiring: d.hiring}')->getAll();
|
||||
|
||||
if (!empty($worker)) {
|
||||
// Найдены данные сотрудника
|
||||
@@ -436,7 +436,7 @@ final class worker extends core
|
||||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных сотрудника
|
||||
$worker = model::read('d.id == "' . $parameters['id'] . '"');
|
||||
$worker = model::read('d.id == "' . urldecode($parameters['id']) . '"');
|
||||
|
||||
if (!empty($worker)) {
|
||||
// Найден сотрудник
|
||||
@@ -533,7 +533,7 @@ final class worker extends core
|
||||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных сотрудника
|
||||
$worker = model::read('d.id == "' . $parameters['id'] . '"');
|
||||
$worker = model::read('d.id == "' . urldecode($parameters['id']) . '"');
|
||||
|
||||
if (!empty($worker)) {
|
||||
// Найден сотрудник
|
||||
@@ -587,7 +587,7 @@ final class worker extends core
|
||||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных сотрудника
|
||||
$worker = model::read('d.id == "' . $parameters['id'] . '"');
|
||||
$worker = model::read('d.id == "' . urldecode($parameters['id']) . '"');
|
||||
|
||||
if (!empty($worker)) {
|
||||
// Найден сотрудник
|
||||
|
@@ -206,7 +206,7 @@ final class payments extends core
|
||||
->setCellValue("K$row", $task->rating ?? 'Отсутствует')
|
||||
->setCellValue("L$row", $task->review ?? '')
|
||||
->setCellValue("M$row", $worker->name['second'] . ' ' . $worker->name['first'] . ' ' . $worker->name['last'])
|
||||
->setCellValue("N$row", $hour = static::hour($market->city, $task->work))
|
||||
->setCellValue("N$row", $hour = static::hour('worker', $market->city, $task->work))
|
||||
->setCellValue("O$row", $payment = $hour * $hours)
|
||||
->setCellValue("P$row", ($penalty = static::penalty($task->rating ?? null)) === null ? $payment : $penalty)
|
||||
->setCellValue("Q$row", $bonus = static::bonus($task->rating ?? null))
|
||||
@@ -431,6 +431,15 @@ final class payments extends core
|
||||
// Инициализация счётчика строк
|
||||
$row = 9;
|
||||
|
||||
// Инициализация буфера объединённых данных всех магазинов
|
||||
$total = [
|
||||
'workers' => 0,
|
||||
'hours' => 0,
|
||||
'hour' => [],
|
||||
'payment' => 0,
|
||||
'vat' => 0
|
||||
];
|
||||
|
||||
foreach ($merged as $id => $dates) {
|
||||
// Перебор магазинов
|
||||
|
||||
@@ -465,7 +474,7 @@ final class payments extends core
|
||||
->setCellValue("E$row", $work)
|
||||
->setCellValue("F$row", $task['workers'])
|
||||
->setCellValue("G$row", $task['hours'])
|
||||
->setCellValue("H$row", $hour = static::hour($market->city, $work))
|
||||
->setCellValue("H$row", $hour = static::hour('market', $market->city, $work))
|
||||
->setCellValue("I$row", $payment = $hour * $task['hours'])
|
||||
->setCellValue("J$row", $payment);
|
||||
|
||||
@@ -491,10 +500,17 @@ final class payments extends core
|
||||
->setCellValue("E$row", '')
|
||||
->setCellValue("F$row", $result['workers'])
|
||||
->setCellValue("G$row", $result['hours'])
|
||||
->setCellValue("H$row", array_sum($result['hour']) / count($result['hour']))
|
||||
->setCellValue("H$row", $hour = array_sum($result['hour']) / count($result['hour']))
|
||||
->setCellValue("I$row", $result['payment'])
|
||||
->setCellValue("J$row", $result['vat']);
|
||||
|
||||
// Запись в буфер объединённых данных всех магазинов
|
||||
$total['workers'] += $result['workers'];
|
||||
$total['hours'] += $result['hours'];
|
||||
$total['hour'][] = $hour;
|
||||
$total['payment'] += $result['payment'];
|
||||
$total['vat'] += $result['vat'];
|
||||
|
||||
// Запись цвета строки с общими данными магазина
|
||||
$spreadsheet
|
||||
->getActiveSheet()
|
||||
@@ -508,6 +524,36 @@ final class payments extends core
|
||||
}
|
||||
}
|
||||
|
||||
// Запись строки с общими данными всех магазинов
|
||||
$spreadsheet
|
||||
->setActiveSheetIndex(0)
|
||||
->setCellValue("A$row", "Итого")
|
||||
->setCellValue("B$row", '')
|
||||
->setCellValue("C$row", '')
|
||||
->setCellValue("D$row", '')
|
||||
->setCellValue("E$row", '')
|
||||
->setCellValue("F$row", $total['workers'])
|
||||
->setCellValue("G$row", $total['hours'])
|
||||
->setCellValue("H$row", array_sum($total['hour']) / count($total['hour']))
|
||||
->setCellValue("I$row", $total['payment'])
|
||||
->setCellValue("J$row", $total['vat']);
|
||||
|
||||
// Запись цвета строки с общими данными всех магазинов
|
||||
$spreadsheet
|
||||
->getActiveSheet()
|
||||
->getStyle("A$row:J$row")
|
||||
->getFill()
|
||||
->setFillType(Fill::FILL_SOLID)
|
||||
->getStartColor()
|
||||
->setARGB('ffdfe4ec');
|
||||
|
||||
// Запись жирного текста для строки с общими данными всех магазинов
|
||||
$spreadsheet
|
||||
->getActiveSheet()
|
||||
->getStyle("A$row:J$row")
|
||||
->getFont()
|
||||
->setBold(true);
|
||||
|
||||
// Write to output buffer
|
||||
IOFactory::createWriter($spreadsheet, 'Xlsx')->save('php://output');
|
||||
|
||||
@@ -533,46 +579,84 @@ final class payments extends core
|
||||
/**
|
||||
* Determine tariff
|
||||
*
|
||||
* @param string $type Type of tariffs (market, worker)
|
||||
* @param string $city City in which the place of work is located
|
||||
* @param string $work Type of work
|
||||
*
|
||||
* @return int|float Cost of work per hour (rubles)
|
||||
*/
|
||||
public static function hour(string $city, string $work): int|float
|
||||
public static function hour(string $type, string $city, string $work): int|float
|
||||
{
|
||||
return match ($city) {
|
||||
'Красноярск' => match (mb_strtolower($work)) {
|
||||
'cashiers', 'cashier', 'кассиры', 'кассир' => 257.07,
|
||||
'displayers', 'displayer', 'выкладчики', 'выкладчик' => 257.07,
|
||||
'gastronomes', 'gastronome', 'гастрономы', 'гастроном' => 257.07,
|
||||
'brigadiers', 'brigadier', 'бригадиры', 'бригадир' => 360,
|
||||
'loaders', 'loader', 'грузчики', 'грузчик' => 255.645,
|
||||
'loaders_mobile', 'loader_mobile', 'мобильные грузчики', 'мобильный грузчик' => 305,
|
||||
'universals_mobile', 'universal_mobile', 'мобильные универсалы', 'мобильный универсал' => 305,
|
||||
return
|
||||
match (mb_strtolower($type)) {
|
||||
'market', 'магазин' => match (mb_strtolower($city)) {
|
||||
'красноярск' => match (mb_strtolower($work)) {
|
||||
'cashiers', 'cashier', 'кассиры', 'кассир' => 257.07,
|
||||
'displayers', 'displayer', 'выкладчики', 'выкладчик' => 257.07,
|
||||
'gastronomes', 'gastronome', 'гастрономы', 'гастроном' => 257.07,
|
||||
'brigadiers', 'brigadier', 'бригадиры', 'бригадир' => 360,
|
||||
'loaders', 'loader', 'грузчики', 'грузчик' => 255.645,
|
||||
'loaders_mobile', 'loader_mobile', 'мобильные грузчики', 'мобильный грузчик' => 305,
|
||||
'universals_mobile', 'universal_mobile', 'мобильные универсалы', 'мобильный универсал' => 305,
|
||||
default => 0
|
||||
},
|
||||
'железногорск', 'сосновоборск', 'тыва' => match (mb_strtolower($work)) {
|
||||
'cashiers', 'cashier', 'кассиры', 'кассир' => 263.34,
|
||||
'displayers', 'displayer', 'выкладчики', 'выкладчик' => 263.34,
|
||||
'gastronomes', 'gastronome', 'гастрономы', 'гастроном' => 263.34,
|
||||
'brigadiers', 'brigadier', 'бригадиры', 'бригадир' => 360,
|
||||
'loaders', 'loader', 'грузчики', 'грузчик' => 255.645,
|
||||
'loaders_mobile', 'loader_mobile', 'мобильные грузчики', 'мобильный грузчик' => 305,
|
||||
'universals_mobile', 'universal_mobile', 'мобильные универсалы', 'мобильный универсал' => 305,
|
||||
default => 0
|
||||
},
|
||||
'хакасия', 'иркутск' => match (mb_strtolower($work)) {
|
||||
'cashiers', 'cashier', 'кассиры', 'кассир' => 245.385,
|
||||
'displayers', 'displayer', 'выкладчики', 'выкладчик' => 245.385,
|
||||
'gastronomes', 'gastronome', 'гастрономы', 'гастроном' => 245.385,
|
||||
'brigadiers', 'brigadier', 'бригадиры', 'бригадир' => 360,
|
||||
'loaders', 'loader', 'грузчики', 'грузчик' => 255.645,
|
||||
'loaders_mobile', 'loader_mobile', 'мобильные грузчики', 'мобильный грузчик' => 305,
|
||||
'universals_mobile', 'universal_mobile', 'мобильные универсалы', 'мобильный универсал' => 305,
|
||||
default => 0
|
||||
},
|
||||
default => 0
|
||||
},
|
||||
'worker', 'сотрудник' => match (mb_strtolower($city)) {
|
||||
'красноярск' => match (mb_strtolower($work)) {
|
||||
'cashiers', 'cashier', 'кассиры', 'кассир' => 190.91,
|
||||
'displayers', 'displayer', 'выкладчики', 'выкладчик' => 190.91,
|
||||
'gastronomes', 'gastronome', 'гастрономы', 'гастроном' => 190.91,
|
||||
'brigadiers', 'brigadier', 'бригадиры', 'бригадир' => 250,
|
||||
'loaders', 'loader', 'грузчики', 'грузчик' => 177.27,
|
||||
'loaders_mobile', 'loader_mobile', 'мобильные грузчики', 'мобильный грузчик' => 250,
|
||||
'universals_mobile', 'universal_mobile', 'мобильные универсалы', 'мобильный универсал' => 250,
|
||||
default => 0
|
||||
},
|
||||
'железногорск', 'сосновоборск', 'тыва' => match (mb_strtolower($work)) {
|
||||
'cashiers', 'cashier', 'кассиры', 'кассир' => 190.91,
|
||||
'displayers', 'displayer', 'выкладчики', 'выкладчик' => 190.91,
|
||||
'gastronomes', 'gastronome', 'гастрономы', 'гастроном' => 190.91,
|
||||
'brigadiers', 'brigadier', 'бригадиры', 'бригадир' => 250,
|
||||
'loaders', 'loader', 'грузчики', 'грузчик' => 177.27,
|
||||
'loaders_mobile', 'loader_mobile', 'мобильные грузчики', 'мобильный грузчик' => 250,
|
||||
'universals_mobile', 'universal_mobile', 'мобильные универсалы', 'мобильный универсал' => 250,
|
||||
default => 0
|
||||
},
|
||||
'хакасия', 'иркутск' => match (mb_strtolower($work)) {
|
||||
'cashiers', 'cashier', 'кассиры', 'кассир' => 181.82,
|
||||
'displayers', 'displayer', 'выкладчики', 'выкладчик' => 181.82,
|
||||
'gastronomes', 'gastronome', 'гастрономы', 'гастроном' => 181.82,
|
||||
'brigadiers', 'brigadier', 'бригадиры', 'бригадир' => 250,
|
||||
'loaders', 'loader', 'грузчики', 'грузчик' => 168.18,
|
||||
'loaders_mobile', 'loader_mobile', 'мобильные грузчики', 'мобильный грузчик' => 250,
|
||||
'universals_mobile', 'universal_mobile', 'мобильные универсалы', 'мобильный универсал' => 250,
|
||||
default => 0
|
||||
},
|
||||
default => 0
|
||||
},
|
||||
default => 0
|
||||
},
|
||||
'Железногорск', 'Сосновоборск', 'Тыва' => match (mb_strtolower($work)) {
|
||||
'cashiers', 'cashier', 'кассиры', 'кассир' => 263.34,
|
||||
'displayers', 'displayer', 'выкладчики', 'выкладчик' => 263.34,
|
||||
'gastronomes', 'gastronome', 'гастрономы', 'гастроном' => 263.34,
|
||||
'brigadiers', 'brigadier', 'бригадиры', 'бригадир' => 360,
|
||||
'loaders', 'loader', 'грузчики', 'грузчик' => 255.645,
|
||||
'loaders_mobile', 'loader_mobile', 'мобильные грузчики', 'мобильный грузчик' => 305,
|
||||
'universals_mobile', 'universal_mobile', 'мобильные универсалы', 'мобильный универсал' => 305,
|
||||
default => 0
|
||||
},
|
||||
'Хакасия', 'Иркутск' => match (mb_strtolower($work)) {
|
||||
'cashiers', 'cashier', 'кассиры', 'кассир' => 245.385,
|
||||
'displayers', 'displayer', 'выкладчики', 'выкладчик' => 245.385,
|
||||
'gastronomes', 'gastronome', 'гастрономы', 'гастроном' => 245.385,
|
||||
'brigadiers', 'brigadier', 'бригадиры', 'бригадир' => 360,
|
||||
'loaders', 'loader', 'грузчики', 'грузчик' => 255.645,
|
||||
'loaders_mobile', 'loader_mobile', 'мобильные грузчики', 'мобильный грузчик' => 305,
|
||||
'universals_mobile', 'universal_mobile', 'мобильные универсалы', 'мобильный универсал' => 305,
|
||||
default => 0
|
||||
},
|
||||
default => 0
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -245,4 +245,51 @@ final class task extends core
|
||||
default => $work
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a transaction for work on a task
|
||||
*
|
||||
* @param string $task
|
||||
* @param string $worker
|
||||
* @param int $amount
|
||||
* @param array $errors
|
||||
*
|
||||
* @return ?string Identificator of instance of ArangoDB
|
||||
*/
|
||||
public static function transaction(
|
||||
string $task,
|
||||
string $worker,
|
||||
int $amount = 0,
|
||||
array &$errors = []
|
||||
): ?string {
|
||||
try {
|
||||
if (
|
||||
collection::init(static::$arangodb->session, self::COLLECTION)
|
||||
&& collection::init(static::$arangodb->session, worker::COLLECTION)
|
||||
&& collection::init(static::$arangodb->session, 'transaction', true)
|
||||
) {
|
||||
// Инициализированы коллекции
|
||||
|
||||
// Запись документа в базу данны и возврат (успех)
|
||||
return document::write(static::$arangodb->session, 'transaction', [
|
||||
'_from' => $task,
|
||||
'_to' => $worker,
|
||||
'amount' => $amount,
|
||||
'processed' => 0,
|
||||
]);
|
||||
} else 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 null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -296,3 +296,10 @@ div#popup>section.list>section.main>div.column>section.row.message>textarea+butt
|
||||
div#popup>section.list.errors>section.body>dl>dd {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
div#popup > section.list .separator {
|
||||
border-top: 2px solid var(--separator, var(--cloud));
|
||||
padding-top: 10px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
@@ -2210,9 +2210,37 @@ 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");
|
||||
buttons.classList.add("row", "buttons");
|
||||
buttons.classList.add("row", "buttons", "merged");
|
||||
|
||||
// Инициализация кнопки заявления о проблеме
|
||||
const problem = document.createElement("button");
|
||||
@@ -2245,7 +2273,7 @@ if (typeof window.tasks !== "function") {
|
||||
complete.innerText = "Завершить";
|
||||
complete.setAttribute(
|
||||
"onclick",
|
||||
`tasks.complete(this, this.parentElement.previousElementSibling.previousElementSibling.children[0], this.parentElement.previousElementSibling, document.getElementById('${task}'))`
|
||||
`tasks.complete(this, this.parentElement.previousElementSibling.previousElementSibling.previousElementSibling.children[0], this.parentElement.previousElementSibling.previousElementSibling, document.getElementById('${task}'))`
|
||||
);
|
||||
|
||||
// Инициализация окна с ошибками
|
||||
@@ -2297,6 +2325,9 @@ if (typeof window.tasks !== "function") {
|
||||
if (data.completed !== true) {
|
||||
// Зявка не завершена
|
||||
|
||||
buttons_worker.appendChild(ban);
|
||||
column.appendChild(buttons_worker);
|
||||
|
||||
buttons.appendChild(problem);
|
||||
buttons.appendChild(complete);
|
||||
column.appendChild(buttons);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<!-- MARKET #{{ market.id.value }} -->
|
||||
{% for key, data in market | filter((data, key) => key != 'id') -%}
|
||||
{% for key, data in market | filter((data, key) => key != 'id' and key != '_key') -%}
|
||||
{% if key == 'created' or key == 'updated' %}
|
||||
<span id="{{ market.id.value }}_{{ key }}"><b>{{ data.label }}:</b>{{ data.value is empty ? 'Никогда' :
|
||||
data.value|date('Y.m.d H:i:s') }}</span>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<!-- TASK #{{ task._key.value }} -->
|
||||
{% for key, data in task | filter((data, key) => key != '_key') -%}
|
||||
{% for key, data in task | filter((data, key) => key != '_key' and key != 'updates') -%}
|
||||
{% if (key == 'created' or key == 'updated') %}
|
||||
<span id="{{ task.id.value }}_{{ key }}"><b>{{ data.label }}:</b>{{ data.value is empty ? 'Никогда' :
|
||||
data.value|date('d.m.Y H:i') }}</span>
|
||||
@@ -11,3 +11,8 @@
|
||||
data.value is same as(false) %}Нет{% elseif data.value is empty %}{% else %}{{ data.value }}{% endif %}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if account.type == 'administrator' or account.type == 'operator' %}
|
||||
{% for key, data in task.updates %}
|
||||
<span id="{{ task.id.value }}_{{ key }}"><b>{{ data.label }}:</b>{% if data.value is empty %}{% else %}{{ data.value }}{% endif %}</span>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<!-- TASK #{{ task._key.value }} -->
|
||||
{% for key, data in task | filter((data, key) => key != '_key') -%}
|
||||
{% for key, data in task | filter((data, key) => key != '_key' and key != 'updates') -%}
|
||||
{% if (key == 'created' or key == 'updated' or key == 'start' or key == 'end') %}
|
||||
<span id="{{ task.id.value }}_{{ key }}"><b>{{ data.label }}:</b>{{ data.value is empty ? 'Никогда' :
|
||||
data.value|date('d.m.Y H:i') }}</span>
|
||||
@@ -11,3 +11,9 @@
|
||||
data.value is same as(false) %}Нет{% elseif data.value is empty %}{% else %}{{ data.value }}{% endif %}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if account.type == 'administrator' or account.type == 'operator' %}
|
||||
<h4 class="separator unselectable">Последние изменения</h4>
|
||||
{% for key, data in task.updates %}
|
||||
<span id="{{ task.id.value }}_{{ key }}"><b>{{ data.label }}:</b>{% if data.value is empty %}{% else %}{{ data.value }}{% endif %}</span>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<!-- WORKER #{{ worker.id.value }} -->
|
||||
{% for key, data in worker | filter((data, key) => key != 'id') -%}
|
||||
{% for key, data in worker | filter((data, key) => key != 'id' and key != '_key') -%}
|
||||
{% if key == 'created' or key == 'updated' %}
|
||||
<span id="{{ worker.id.value }}_{{ key }}"><b>{{ data.label }}:</b>{{ data.value is empty ? 'Никогда' :
|
||||
data.value|date('Y.m.d H:i:s') }}</span>
|
||||
|
@@ -25,7 +25,7 @@
|
||||
class="icon arrow right"></i></button>
|
||||
<datalist id="markets">
|
||||
{% for account in accounts %}
|
||||
<option value="{{ account.market }}">{{ account.market }} {{
|
||||
<option value="{{ account.market.id }}">{{ account.market.id }} {{
|
||||
account.market.name.first }} {{ account.market.name.second }}</option>
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
@@ -74,7 +74,7 @@
|
||||
fields.password.button = fields.password.label.getElementsByTagName('button')[0];
|
||||
|
||||
// Инициализация маски идентификатора магазина
|
||||
fields.market.input.mask = IMask(fields.market.input, {mask: '000000000000'});
|
||||
fields.market.input.mask = IMask(fields.market.input, {mask: '000'});
|
||||
|
||||
/**
|
||||
* Отправить входной псевдоним на сервер
|
||||
|
Reference in New Issue
Block a user