Kufrik/app/UI/Admin/AdminPresenter.php

299 lines
9.9 KiB
PHP

<?php
namespace App\UI\Admin;
use App\Model\Facade\DatabazeFacade;
use App\Model\Sdf\SdfKufrikImporter;
use App\UI\BasePresenter;
use Nette\Application\AbortException;
use Nette\Application\UI\Form;
use Nette\Forms\Controls\UploadControl;
use Nette\Forms\Helpers;
use Nette\Http\FileUpload;
class AdminPresenter extends BasePresenter
{
private const SDF_MAX_BYTES = 50 * 1024 * 1024;
/** @persistent */
public string $db = '';
public function __construct(
private DatabazeFacade $databazeFacade,
private SdfKufrikImporter $sdfImporter
) {
parent::__construct();
}
protected function startup(): void
{
parent::startup();
if (!$this->getUser()->isInRole('admin')) {
$this->error('Sekce Admin je dostupná pouze administrátorovi systému.', 403);
}
if ($this->db === '') {
$this->db = $this->databazeFacade->getDefaultTenantDatabase();
}
}
public function actionDefault(): void
{
$this->redirect('databaze');
}
public function renderDatabaze(): void
{
$databases = $this->databazeFacade->getDatabases();
$this->template->databases = $databases;
$this->template->celkemCount = count($databases);
}
public function renderFirmy(): void
{
$databases = $this->databazeFacade->getDatabaseSelectItems();
if ($databases !== [] && !isset($databases[$this->db])) {
$this->db = (string) array_key_first($databases);
}
$firmy = $this->db !== ''
? $this->databazeFacade->getFirmy($this->db, $this->databazeFacade->getDefaultTenantServer())
: [];
$this->template->databases = $databases;
$this->template->selectedDb = $this->db;
$this->template->firmy = $firmy;
$this->template->celkemCount = count($firmy);
}
public function renderUzivatele(): void
{
$uzivatele = $this->databazeFacade->getUzivatele();
$aktivniCount = 0;
foreach ($uzivatele as $u) {
if ($u->AKTIVNI) {
$aktivniCount++;
}
}
$this->template->uzivatele = $uzivatele;
$this->template->celkemCount = count($uzivatele);
$this->template->aktivniCount = $aktivniCount;
$this->template->databases = $this->databazeFacade->getDatabaseSelectItems();
$this->template->defaultDb = $this->db !== ''
? $this->db
: $this->databazeFacade->getDefaultTenantDatabase();
$this->template->firmaItems = $this->databazeFacade->getFirmaSelectItems(
$this->template->defaultDb,
$this->databazeFacade->getDefaultTenantServer()
);
}
protected function createComponentAddFirmaForm(): Form
{
$form = new Form();
$form->addText('firmaNazev', 'Název firmy / OSVČ:')
->setRequired('Zadejte název firmy.')
->addRule($form::MaxLength, 'Název může mít nejvýše 255 znaků.', 255);
$form->addSubmit('send', 'Přidat firmu');
$form->onSuccess[] = [$this, 'addFirmaFormSucceeded'];
return $form;
}
public function addFirmaFormSucceeded(Form $form, \stdClass $data): void
{
try {
if ($this->db === '') {
throw new \InvalidArgumentException('Nejdřív vyberte databázi.');
}
$firmaId = $this->databazeFacade->createFirma(
$data->firmaNazev,
$this->db,
$this->databazeFacade->getDefaultTenantServer()
);
$this->flashMessage("Firma „{$data->firmaNazev}“ (#{$firmaId}) byla založena.", 'success');
} catch (AbortException $e) {
throw $e;
} catch (\Throwable $e) {
$form->addError($e->getMessage());
return;
}
$this->redirect('this');
}
protected function createComponentAddUzivatelForm(): Form
{
$form = new Form();
$databases = $this->databazeFacade->getDatabaseSelectItems();
$defaultDb = isset($databases[$this->db])
? $this->db
: ($databases !== [] ? (string) array_key_first($databases) : '');
$form->addSelect('database', 'Databáze:')
->setItems($databases)
->setDefaultValue($defaultDb)
->setRequired('Vyberte databázi.');
$form->addSelect('firmaId', 'Firma:')
->setItems($defaultDb !== ''
? $this->databazeFacade->getFirmaSelectItems($defaultDb)
: [])
->setPrompt('— vyberte firmu —')
->setRequired('Vyberte firmu.');
$form->addEmail('email', 'E-mail:')
->setRequired('Zadejte e-mail.')
->addRule($form::MaxLength, 'E-mail může mít nejvýše 100 znaků.', 100);
$form->addPassword('password', 'Heslo:')
->setRequired('Zadejte heslo.')
->addRule($form::MinLength, 'Heslo musí mít alespoň 8 znaků.', 8);
$form->addPassword('passwordVerify', 'Heslo znovu:')
->setRequired('Zadejte heslo znovu.')
->addRule($form::Equal, 'Hesla se neshodují.', $form['password']);
$form->addSubmit('send', 'Přidat uživatele');
$form->onSuccess[] = [$this, 'addUzivatelFormSucceeded'];
return $form;
}
public function addUzivatelFormSucceeded(Form $form, \stdClass $data): void
{
try {
$this->databazeFacade->createUzivatel(
$data->email,
$data->password,
$data->database,
(int) $data->firmaId,
$this->databazeFacade->getDefaultTenantServer()
);
$this->flashMessage('Uživatel byl založen s rolí User.', 'success');
} catch (AbortException $e) {
throw $e;
} catch (\Throwable $e) {
$form->addError($e->getMessage());
return;
}
$this->redirect('this');
}
protected function createComponentUserForm(): Form
{
$form = new Form();
$form->addHidden('loginId')
->addRule($form::Integer)
->setRequired();
$form->addEmail('email', 'E-mail / přihlašovací jméno:')
->setRequired('Zadejte e-mail.')
->addRule($form::MaxLength, 'E-mail může mít nejvýše 100 znaků.', 100);
$form->addPassword('password', 'Nové heslo:')
->setNullable()
->addCondition($form::Filled)
->addRule($form::MinLength, 'Heslo musí mít alespoň 8 znaků.', 8);
$form->addPassword('passwordVerify', 'Heslo znovu:')
->setNullable()
->addConditionOn($form['password'], $form::Filled)
->setRequired('Zadejte heslo znovu.')
->addRule($form::Equal, 'Hesla se neshodují.', $form['password']);
$form->addSubmit('send', 'Uložit uživatele');
$form->onSuccess[] = [$this, 'userFormSucceeded'];
return $form;
}
public function userFormSucceeded(Form $form, \stdClass $data): void
{
try {
$password = $data->password !== '' ? $data->password : null;
$this->databazeFacade->updateUserCredentials(
(int) $data->loginId,
$data->email,
$password
);
$this->flashMessage('Údaje uživatele byly uloženy.', 'success');
} catch (AbortException $e) {
throw $e;
} catch (\Throwable $e) {
$this->flashMessage('Uložení uživatele selhalo: ' . $e->getMessage(), 'danger');
}
$this->redirect('this');
}
protected function createComponentSdfImportForm(): Form
{
$form = new Form();
$form->addHidden('loginId')
->addRule($form::Integer, 'Vyberte firmu s uživatelem.')
->setRequired('Vyberte firmu s uživatelem.');
$iniLimits = array_filter([
Helpers::iniGetSize('upload_max_filesize'),
Helpers::iniGetSize('post_max_size'),
]);
$maxBytes = min(self::SDF_MAX_BYTES, ...($iniLimits ?: [self::SDF_MAX_BYTES]));
$maxMb = max(1, (int) floor($maxBytes / (1024 * 1024)));
$form->addUpload('sdf', 'Soubor SDF:')
->setRequired('Vyberte soubor s příponou .sdf.')
->addRule($form::MaxFileSize, "Soubor může mít nejvýše {$maxMb} MB.", $maxBytes)
->addRule(
function (UploadControl $control): bool {
$file = $control->getValue();
if (!$file instanceof FileUpload || !$file->hasFile()) {
return false;
}
return strtolower(pathinfo($file->getUntrustedName(), PATHINFO_EXTENSION)) === 'sdf';
},
'Soubor musí mít příponu .sdf.'
);
$form->addSubmit('send', 'Import');
$form->onSuccess[] = [$this, 'sdfImportFormSucceeded'];
return $form;
}
public function sdfImportFormSucceeded(Form $form, \stdClass $data): void
{
set_time_limit(180);
$loginId = (int) $data->loginId;
try {
$this->databazeFacade->saveSdf($loginId, $data->sdf);
$stats = $this->sdfImporter->import($loginId);
$this->flashMessage(
sprintf(
'Import ze SDF dokončen. Původní data firmy byla smazána. Zákazníci: %d. Faktury: %d. Položky: %d. Platby: %d.',
$stats['zakazniciInserted'],
$stats['fakturyInserted'],
$stats['polozkyInserted'],
$stats['platbyInserted']
),
'success'
);
} catch (AbortException $e) {
throw $e;
} catch (\Throwable $e) {
$this->flashMessage('Import ze SDF selhal: ' . $e->getMessage(), 'danger');
}
$this->redirect('this');
}
}