resolved #61, resolved #59

This commit is contained in:
Arsen Mirzaev Tatyano-Muradovich 2024-02-22 20:17:00 +07:00
parent 5641a686a2
commit 6c4c0b1ada
7 changed files with 6910 additions and 5700 deletions

View File

@ -2,4 +2,6 @@
Site-registry of tasks for outsourced employees Site-registry of tasks for outsourced employees
From this project i earned **700 000** Russian rubles</br> From this project i earned **700 000** Russian rubles</br>
*As long as commits appear in the repository, this means that i continue paid development* *As long as commits appear in the repository, this means that i continue paid development*</br>
</br>
I am selling this site to **capitalist scum** for a lot of money, but you, friend, can use my code **for free** ✌️

View File

@ -34,7 +34,7 @@ final class task extends core
/** /**
* Создать * Создать
* *
* @param array $parameters Параметры запроса * @param array $parameters Параметры запроса (json в php://input)
* *
* @return void В буфер вывода JSON-документ с запрашиваемыми параметрами * @return void В буфер вывода JSON-документ с запрашиваемыми параметрами
*/ */
@ -47,11 +47,27 @@ final class task extends core
// Инициализация буфера ошибок // Инициализация буфера ошибок
$this->errors['tasks'] ??= []; $this->errors['tasks'] ??= [];
// Создание строк if (!empty($json = json_decode(file_get_contents('php://input'), true, 4))) {
for ($i = 0, $parameters['cashiers'] = (int) $parameters['cashiers']; $i < $parameters['cashiers']; ++$i) model::create(work: 'Кассир', market: $this->account->type === 'market' ? account::market($this->account->getId())?->id : null, start: $parameters['start'], end: $parameters['end'], date: $parameters['date'], errors: $this->errors['tasks']);
for ($i = 0, $parameters['displayers'] = (int) $parameters['displayers']; $i < $parameters['displayers']; ++$i) model::create(work: 'Выкладчик', market: $this->account->type === 'market' ? account::market($this->account->getId())?->id : null, start: $parameters['start'], end: $parameters['end'], date: $parameters['date'], errors: $this->errors['tasks']);
for ($i = 0, $parameters['loaders'] = (int) $parameters['loaders']; $i < $parameters['loaders']; ++$i) model::create(work: 'Грузчик', market: $this->account->type === 'market' ? account::market($this->account->getId())?->id : null, start: $parameters['start'], end: $parameters['end'], date: $parameters['date'], errors: $this->errors['tasks']); foreach ($json as $work => $tasks) {
for ($i = 0, $parameters['gastronomes'] = (int) $parameters['gastronomes']; $i < $parameters['gastronomes']; ++$i) model::create(work: 'Гастроном', market: $this->account->type === 'market' ? account::market($this->account->getId())?->id : null, start: $parameters['start'], end: $parameters['end'], date: $parameters['date'], errors: $this->errors['tasks']); // Перебор категорий (колонок)
foreach ($tasks as $task) {
// Перебор заявок
// Создание заявки
model::create(
work: model::label($work),
market: $this->account->type === 'market' ? account::market($this->account->getId())?->id : null,
start: $task['start'],
end: $task['end'],
date: $task['date'],
commentary: $task['commentary'],
errors: $this->errors['tasks']
);
}
}
// Запись заголовков ответа // Запись заголовков ответа
header('Content-Type: application/json'); header('Content-Type: application/json');
@ -74,6 +90,7 @@ final class task extends core
// Отправка и деинициализация буфера вывода // Отправка и деинициализация буфера вывода
ob_end_flush(); ob_end_flush();
flush(); flush();
} else throw new exception('Не удалось инициализировать JSON-документ с данными заявок');
} else throw new exception('Вы не авторизованы'); } else throw new exception('Вы не авторизованы');
} catch (exception $e) { } catch (exception $e) {
// Запись в реестр ошибок // Запись в реестр ошибок
@ -1758,7 +1775,7 @@ final class task extends core
// Найдена заявка // Найдена заявка
// Инициализация списка работ // Инициализация списка работ
$this->view->works = ['Кассир', 'Выкладчик', рузчик', 'Гастроном']; $this->view->works = ['Кассир', 'Выкладчик', астроном', 'Бригадир', 'Грузчик', 'Мобильный грузчик', 'Мобильный универсал'];
// Проверка на существование записанной в задаче работы в списке существующих работ и запись об этом в глобальную переменную шаблонизатора // Проверка на существование записанной в задаче работы в списке существующих работ и запись об этом в глобальную переменную шаблонизатора
foreach ($this->view->works as $work) if ($this->view->task->work === $work) $this->view->exist = true; foreach ($this->view->works as $work) if ($this->view->task->work === $work) $this->view->exist = true;

View File

@ -135,7 +135,7 @@ final class account extends core
if (!empty($session->buffer['market']['entry']['password'])) { if (!empty($session->buffer['market']['entry']['password'])) {
// Найден пароль в буфере сессии // Найден пароль в буфере сессии
if (($account = market::account(market::read('d.id == "' . $session->buffer['market']['entry']['id'] . '"', amount: 1)?->getId())) instanceof _document) { if (($account = market::account(market::read('d.id == "' . $session->buffer['market']['entry']['id'] . '"', amount: 1)?->getId()) ?? null) instanceof _document) {
// Найден аккаунт (игнорируются ошибки) // Найден аккаунт (игнорируются ошибки)
if (sodium_crypto_pwhash_str_verify($account->password, $session->buffer['market']['entry']['password'])) { if (sodium_crypto_pwhash_str_verify($account->password, $session->buffer['market']['entry']['password'])) {

View File

@ -40,7 +40,7 @@ final class task extends core
/** /**
* Create task in ArangoDB * Create task in ArangoDB
* *
* @param ?string $date * @param string|int|null $date
* @param ?string $worker * @param ?string $worker
* @param ?string $work * @param ?string $work
* @param ?string $start * @param ?string $start
@ -51,12 +51,13 @@ final class task extends core
* @param bool $hided * @param bool $hided
* @param bool $problematic * @param bool $problematic
* @param bool $completed * @param bool $completed
* @param ?string $commentary
* @param array $errors * @param array $errors
* *
* @return ?string Identificator of instance of ArangoDB * @return ?string Identificator of instance of ArangoDB
*/ */
public static function create( public static function create(
?string $date = null, string|int|null $date = null,
?string $worker = null, ?string $worker = null,
?string $work = null, ?string $work = null,
?string $start = null, ?string $start = null,
@ -67,6 +68,7 @@ final class task extends core
bool $hided = false, bool $hided = false,
bool $problematic = false, bool $problematic = false,
bool $completed = false, bool $completed = false,
?string $commentary = null,
array &$errors = [] array &$errors = []
): ?string { ): ?string {
try { try {
@ -90,6 +92,7 @@ final class task extends core
'hided' => $hided, 'hided' => $hided,
'problematic' => $problematic, 'problematic' => $problematic,
'completed' => $completed, 'completed' => $completed,
'commentary' => $commentary,
]); ]);
} else throw new exception('Не удалось инициализировать коллекции'); } else throw new exception('Не удалось инициализировать коллекции');
} catch (exception $e) { } catch (exception $e) {
@ -180,4 +183,25 @@ final class task extends core
// Exit (fail) // Exit (fail)
return []; return [];
} }
/**
* Generate work type label in Russian
*
* @param string $work Type of work
*
* @return string
*/
public static function label(string $work): string
{
return match (mb_strtolower($work)) {
'cashiers', 'cashier', 'кассиры', 'кассир' => 'Кассир',
'displayers', 'displayer', 'выкладчики', 'выкладчик' => 'Выкладчик',
'gastronomes', 'gastronome', 'гастрономы', 'гастроном' => 'Гастроном',
'brigadiers', 'brigadier', 'бригадиры', 'бригадир' => 'Бригадир',
'loaders', 'loader', 'грузчики', 'грузчик' => 'Грузчик',
'loaders_mobile', 'loader_mobile', 'мобильные грузчики', 'мобильный грузчик' => 'Мобильный грузчик',
'universals_mobile', 'universal_mobile', 'мобильные универсалы', 'мобильный универсал' => 'Мобильный универсал',
default => $work
};
}
} }

View File

@ -302,12 +302,14 @@ label * {
} }
textarea { textarea {
--padding-x: 12px;
--padding-y: 8px;
width: 100%; width: 100%;
min-width: calc(100% - 24px); min-width: calc(100% - 24px);
min-height: 120px; min-height: 120px;
max-width: calc(100% - 24px); max-width: calc(100% - 24px);
max-height: 300px; max-height: 300px;
padding: 8px 12px; padding: var(--padding-y, 8px) var(--padding-x, 12px);
font-size: smaller; font-size: smaller;
overflow: hidden; overflow: hidden;
border-radius: 3px; border-radius: 3px;

View File

@ -44,9 +44,12 @@ div#popup>section.calculated {
} }
div#popup>section.list { div#popup>section.list {
max-width: max(70vw, 1300px);
max-height: max(62vh, 600px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 30px; padding: 30px;
overflow-y: scroll;
border-radius: 3px; border-radius: 3px;
} }
@ -65,17 +68,30 @@ div#popup>section.list h4 {
} }
div#popup>section.list>section.main { div#popup>section.list>section.main {
--gap: 15px;
display: flex; display: flex;
gap: 15px; flex-flow: row wrap;
justify-content: space-between;
gap: var(--gap, 15px);
} }
div#popup>section.list>section.main>div.column { div#popup>section.list>section.main>div.column {
flex-grow: 1;
display: flex; display: flex;
flex-grow: 1;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
} }
div#popup>section.list>section.main.flow>div.column:not(:only-child) {
width: 300px;
}
div#popup>section.list>section.main>div.column:not(:only-child)[data-column="buttons"]:last-of-type {
margin-left: auto;
justify-content: end;
}
div#popup>section.list>section.main>div.column:only-child { div#popup>section.list>section.main>div.column:only-child {
width: 100%; width: 100%;
} }
@ -140,7 +156,21 @@ div#popup>section.list>section.main>div.column> :is(div, select).row.buttons {
div#popup>section.list>section.main>div.column> :is(div, select).row:not(.buttons, .stretchable, .endless), div#popup>section.list>section.main>div.column> :is(div, select).row:not(.buttons, .stretchable, .endless),
div#popup>section.list>section.main>div.column> :is(div, select).row:not(.buttons, .stretchable, .endless)>button { div#popup>section.list>section.main>div.column> :is(div, select).row:not(.buttons, .stretchable, .endless)>button {
height: 29px; --height: 29px;
height: var(--height, 29px);
}
div#popup>section.list>section.main>div.column> :is(div, select).row:not(.buttons .endless).stretchable,
div#popup>section.list>section.main>div.column> :is(div, select).row:not(.buttons, .endless).stretchable>button {
--height: 29px;
height: max(var(--height, 29px), fit-content);
}
div#popup>section.list>section.main>div.column> :is(div, select).row:not(.buttons .endless).stretchable>textarea {
/* min-height: calc(var(--height, 29px) - var(--padding-y, 8ox) * 2); */
min-height: 1rem;
max-height: 3rem;
height: 1rem;
} }
div#popup>section.list>section.main>div.column>:is(div, section).row:not(.merged)+:is(div, section).row.merged { div#popup>section.list>section.main>div.column>:is(div, section).row:not(.merged)+:is(div, section).row.merged {

File diff suppressed because it is too large Load Diff