diff --git a/app/Model/Facade/ZakaznikFacade.php b/app/Model/Facade/ZakaznikFacade.php new file mode 100644 index 0000000..f4855ab --- /dev/null +++ b/app/Model/Facade/ZakaznikFacade.php @@ -0,0 +1,109 @@ +kufrikExplorer->query($sql, ...$params)->fetchAll(); + } + + /** + * Detail zákazníka podle ID + */ + public function getById(int $id) + { + return $this->kufrikExplorer->table('ZAKAZNIK')->where('ID', $id)->fetch(); + } + + /** + * Uložení / Aktualizace zákazníka + */ + public function save(array $data, ?int $id = null, int $firmaId): void + { + // Sanitizace prázdných řetězců na NULL pro volitelné položky + $values = [ + 'FIRMA_ID' => $firmaId, + 'JMENO' => $data['JMENO'] ?: null, + 'PRIJMENI' => $data['PRIJMENI'], + 'ULICE' => $data['ULICE'] ?: null, + 'MESTO' => $data['MESTO'] ?: null, + 'PSC' => $data['PSC'] ?: null, + 'IC' => $data['IC'] ?: null, + 'DIC' => $data['DIC'] ?: null, + 'TELEFON' => $data['TELEFON'] ?: null, + 'EMAIL' => $data['EMAIL'] ?: null, + 'AKTIVNI' => (int) ($data['AKTIVNI'] ?? 1), + ]; + + if ($id) { + unset($values['FIRMA_ID']); // FIRMA_ID se při úpravě nemění + $this->kufrikExplorer->table('ZAKAZNIK')->where('ID', $id)->update($values); + } else { + $this->kufrikExplorer->table('ZAKAZNIK')->insert($values); + } + } + + /** + * Přepnutí stavu Aktivní / Neaktivní + */ + public function toggleAktivni(int $id): bool + { + $zakaznik = $this->getById($id); + if (!$zakaznik) { + return false; + } + + $novyStav = !$zakaznik->AKTIVNI; + + // OPRAVA: Provedeme update přímo přes Selection podle sloupce 'ID' + $this->kufrikExplorer->table('ZAKAZNIK') + ->where('ID', $id) + ->update(['AKTIVNI' => (int) $novyStav]); + + return $novyStav; + } + + /** + * Smazání zákazníka + */ + public function delete(int $id): void + { + $this->kufrikExplorer->table('ZAKAZNIK')->where('ID', $id)->delete(); + } +} \ No newline at end of file diff --git a/app/Model/Login/ServerCredentials.php b/app/Model/Login/ServerCredentials.php deleted file mode 100644 index bf1ad49..0000000 --- a/app/Model/Login/ServerCredentials.php +++ /dev/null @@ -1,48 +0,0 @@ -parseServer($server_string); - } - - private function parseServer($server_string) - { - $this->server = $server_string; //default - $this->databaze = "psx"; //default - - if (str_contains($server_string, "@")) { //je tam zavináč - $str_arr = explode("@", $server_string); - if (count($str_arr) <> 2) - return; //tady něco nehraje - $this->server = trim($str_arr[0]); - $this->databaze = trim($str_arr[1]); - } - } -} \ No newline at end of file diff --git a/app/Model/Login/UserIdentity.php b/app/Model/Login/UserIdentity.php deleted file mode 100644 index 836f7ea..0000000 --- a/app/Model/Login/UserIdentity.php +++ /dev/null @@ -1,31 +0,0 @@ -
- - +
diff --git a/app/UI/Zakaznik/ZakaznikPresenter.php b/app/UI/Zakaznik/ZakaznikPresenter.php index 2eca925..dcaeade 100644 --- a/app/UI/Zakaznik/ZakaznikPresenter.php +++ b/app/UI/Zakaznik/ZakaznikPresenter.php @@ -3,23 +3,51 @@ namespace App\UI\Zakaznik; use App\UI\BasePresenter; -use Nette\Database\Explorer; +use App\Model\Facade\ZakaznikFacade; class ZakaznikPresenter extends BasePresenter { + /** @persistent */ + public string $search = ''; + + /** @persistent */ + public string $zobrazit = 'aktivni'; + public function __construct( - private Explorer $kufrikExplorer + private ZakaznikFacade $zakaznikFacade ) { parent::__construct(); } - public function actionDefault(): void + public function renderDefault(): void { - // Seznam zákazníků + $this->template->zakaznici = $this->zakaznikFacade->getFiltered($this->search, $this->zobrazit); + $this->template->search = $this->search; + $this->template->zobrazit = $this->zobrazit; } - public function actionAdd(): void + public function handleToggleAktivni(int $id): void { - // Přidání zákazníka + $novyStav = $this->zakaznikFacade->toggleAktivni($id); + + $this->flashMessage( + $novyStav ? 'Zákazník byl aktivován.' : 'Zákazník byl deaktivován.', + 'success' + ); + + $this->redirect('this'); + } + + public function handleDelete(int $id): void + { + try { + $this->zakaznikFacade->delete($id); + $this->flashMessage('Zákazník byl úspěšně smazán.', 'info'); + } catch (\PDOException $e) { + // Pokud je navázán na FAKTURA, FK v MS SQL odmítne smazání + $this->flashMessage('Zákazníka nelze smazat, protože má v systému vystavené faktury. Můžete jej deaktivovat.', 'warning'); + } + + $this->redirect('this'); } } \ No newline at end of file diff --git a/app/UI/Zakaznik/default.latte b/app/UI/Zakaznik/default.latte new file mode 100644 index 0000000..95ec5b4 --- /dev/null +++ b/app/UI/Zakaznik/default.latte @@ -0,0 +1,150 @@ +{block content} + +
+ + + + + +
+
+
+
+ + +
+
+ +
+ +
+ +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + {foreach $zakaznici as $z} + + + + + + + + + {else} + + + + {/foreach} + +
Jméno / FirmaAdresaIČ / DIČKontaktStavAkce
+ {$z->PRIJMENI} {$z->JMENO} + + {if $z->ULICE || $z->MESTO} +
{$z->ULICE}
+
{$z->PSC} {$z->MESTO}
+ {else} + + {/if} +
+ {if $z->IC} +
IČ: {$z->IC}
+
DIČ: {$z->DIC}
+ {else} + + {/if} +
+ {if $z->TELEFON} +
{$z->TELEFON}
+ {/if} + {if $z->EMAIL} + + {/if} + {if !$z->TELEFON && !$z->EMAIL} + + {/if} +
+ {if $z->AKTIVNI} + Aktivní + {else} + Neaktivní + {/if} + +
+ + + + + + + + + + + + + + +
+
+ + Nebyli nalezeni žádní zákazníci odpovídající zadaným kritériím. +
+
+
+ +
+ + \ No newline at end of file diff --git a/app/UI/ZakaznikEdit/ZakaznikEditPresenter.php b/app/UI/ZakaznikEdit/ZakaznikEditPresenter.php new file mode 100644 index 0000000..24a0cf8 --- /dev/null +++ b/app/UI/ZakaznikEdit/ZakaznikEditPresenter.php @@ -0,0 +1,101 @@ +id = null; + $this->setView('edit'); // <--- Zde přikážeme Nette použít edit.latte + } + + public function actionEdit(int $id): void + { + $this->id = $id; + $zakaznik = $this->zakaznikFacade->getById($id); + + if (!$zakaznik) { + $this->flashMessage('Zákazník nebyl nalezen.', 'danger'); + $this->redirect('Zakaznik:default'); + } + + $this['zakaznikForm']->setDefaults($zakaznik->toArray()); + } + + public function renderEdit(?int $id = null): void + { + $this->template->isEdit = (bool) $this->id; + } + + public function renderNew(): void + { + $this->template->isEdit = false; + } + + protected function createComponentZakaznikForm(): Form + { + $form = new Form; + + // Základní údaje + $form->addText('PRIJMENI', 'Příjmení / Název firmy:') + ->setRequired('Zadejte příjmení nebo název firmy.'); + + $form->addText('JMENO', 'Jméno:'); + + // IČO / DIČ + $form->addText('IC', 'IČ:') + ->setMaxLength(8); + + $form->addText('DIC', 'DIČ:') + ->setMaxLength(10); + + // Adresa + $form->addText('ULICE', 'Ulice a ČP:'); + $form->addText('MESTO', 'Město:'); + $form->addText('PSC', 'PSČ:') + ->setMaxLength(5); + + // Kontaktní údaje + $form->addText('TELEFON', 'Telefon:'); + $form->addEmail('EMAIL', 'E-mail:'); + + // Příznak aktivity + $form->addCheckbox('AKTIVNI', 'Aktivní zákazník') + ->setDefaultValue(true); + + $form->addSubmit('save', 'Uložit zákazníka') + ->setHtmlAttribute('class', 'btn btn-primary'); + + $form->onSuccess[] = [$this, 'zakaznikFormSucceeded']; + + return $form; + } + + public function zakaznikFormSucceeded(Form $form, \stdClass $data): void + { + $firmaId = $this->getUser()->getIdentity()->firma_id; + + $this->zakaznikFacade->save((array) $data, $this->id, $firmaId); + + $this->flashMessage( + $this->id ? 'Údaje zákazníka byly upraveny.' : 'Nový zákazník byl úspěšně vytvořen.', + 'success' + ); + + $this->redirect('Zakaznik:default'); + } +} \ No newline at end of file diff --git a/app/UI/ZakaznikEdit/edit.latte b/app/UI/ZakaznikEdit/edit.latte new file mode 100644 index 0000000..8fe11df --- /dev/null +++ b/app/UI/ZakaznikEdit/edit.latte @@ -0,0 +1,90 @@ +{block content} + +
+
+
+

+ + {if $isEdit}Úprava zákazníka{else}Nový zákazník{/if} +

+ + Zpět na seznam + +
+ +
+ +
+
+
    +
  • {$error}
  • +
+
+
+ + +
+ + +
+
+ + +
+ + +
+ + +
+
+ + +
+ +
+ + +
+ + +
+
+ + +
+
+ + +
+ +
+ + +
+ + +
+
+ + +
+ + +
+
+ + +
+
+ + +
+ + Zrušit +
+
+
+
\ No newline at end of file