Obvody/app/Model/ZaznamFacade.php

176 lines
5.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Model;
use Nette;
use Nette\Database\Explorer;
use Nette\Database\Row;
use Nette\Security\User;
use Nette\Utils\DateTime;
/**
* Třída pro načítání informací o obvodech z DB.
*/
final class ZaznamFacade
{
public function __construct(
private Explorer $database,
private User $user,
) {
}
/**
* Summary of getZaznamyObvodu
* @param int $obvod ID
* @return array
*/
public function getZaznamyObvodu(int $obvod): array
{
$sql = 'SELECT * FROM ZAZNAM WHERE OBVOD = ? AND DELETED = 0 ORDER BY VYDANO DESC, ID DESC';
return $this->database->fetchAll($sql, $obvod);
}
/**
* Jména zvěstovatelů pro výběr při přidělení.
* @return array<string, string>
*/
public function getZvestovatele(): array
{
$rows = $this->database->fetchAll(
'SELECT DISTINCT JMENO FROM ZAZNAM WHERE DELETED = 0 ORDER BY JMENO'
);
$jmena = [];
foreach ($rows as $row) {
$jmena[$row->JMENO] = $row->JMENO;
}
return $jmena;
}
/**
* Přidělení, která ještě nebyla vrácena.
*/
public function getOtevrene(int $obvod): array
{
return $this->database->fetchAll(
'SELECT * FROM ZAZNAM WHERE OBVOD = ? AND DELETED = 0 AND VRACENO IS NULL ORDER BY VYDANO, ID',
$obvod
);
}
public function getZaznam(int $id): Row|null
{
return $this->database->fetch('SELECT * FROM ZAZNAM WHERE ID = ? AND DELETED = 0', $id);
}
public function pridej(int $obvod, string $jmeno, \DateTimeInterface $vydano): void
{
$this->database->query(
'INSERT INTO ZAZNAM (OBVOD, JMENO, VYDANO, VRACENO, DELETED) VALUES (?, ?, ?, NULL, 0)',
$obvod,
$jmeno,
$vydano
);
}
public function uprav(int $id, int $obvod, string $jmeno, \DateTimeInterface $vydano, ?\DateTimeInterface $vraceno): bool
{
$zaznam = $this->getZaznam($id);
if ($zaznam === null || (int) $zaznam->OBVOD !== $obvod) {
return false;
}
$this->database->query(
'UPDATE ZAZNAM SET JMENO = ?, VYDANO = ?, VRACENO = ? WHERE ID = ? AND OBVOD = ? AND DELETED = 0',
$jmeno,
$vydano,
$vraceno,
$id,
$obvod
);
return true;
}
public function smaz(int $id, int $obvod): bool
{
$zaznam = $this->getZaznam($id);
if ($zaznam === null || (int) $zaznam->OBVOD !== $obvod) {
return false;
}
$this->database->query(
'UPDATE ZAZNAM SET DELETED = 1 WHERE ID = ? AND OBVOD = ? AND DELETED = 0',
$id,
$obvod
);
return true;
}
/**
* Stáří obvodů podle posledního vrácení a příznak probíhajícího přidělení.
* Klíčem je číslo obvodu.
*
* @return array<int, array{id: int, mesice: int|null, probiha: bool, vraceno: string|null, prideleni: int|null, prideleniDatum: string|null}>
*/
public function getStariObvodu(): array
{
$radky = $this->database->fetchAll(
'SELECT o.ID, o.CISLO,
MAX(CASE WHEN z.VRACENO IS NOT NULL THEN z.VRACENO END) AS POSLEDNI,
MIN(CASE WHEN z.VRACENO IS NULL THEN z.VYDANO END) AS PRIDELENO,
SUM(CASE WHEN z.ID IS NOT NULL AND z.VRACENO IS NULL THEN 1 ELSE 0 END) AS OTEVRENE
FROM OBVOD o
LEFT JOIN ZAZNAM z ON z.OBVOD = o.ID AND z.DELETED = 0
GROUP BY o.ID, o.CISLO'
);
$dnes = new \DateTimeImmutable('today');
$vysledek = [];
foreach ($radky as $radek) {
$mesice = null;
$vraceno = null;
if ($radek->POSLEDNI !== null) {
$datum = $radek->POSLEDNI instanceof \DateTimeInterface
? \DateTimeImmutable::createFromInterface($radek->POSLEDNI)
: new \DateTimeImmutable((string) $radek->POSLEDNI);
$vraceno = $datum->format('j. n. Y');
$rozdil = $datum->diff($dnes);
$mesice = $rozdil->invert === 1 ? 0 : ($rozdil->y * 12 + $rozdil->m);
}
$prideleni = null;
$prideleniDatum = null;
if ($radek->PRIDELENO !== null) {
$zacatek = $radek->PRIDELENO instanceof \DateTimeInterface
? \DateTimeImmutable::createFromInterface($radek->PRIDELENO)
: new \DateTimeImmutable((string) $radek->PRIDELENO);
$prideleniDatum = $zacatek->format('j. n. Y');
$odPrideleni = $zacatek->diff($dnes);
$prideleni = $odPrideleni->invert === 1 ? 0 : ($odPrideleni->y * 12 + $odPrideleni->m);
}
$vysledek[(int) $radek->CISLO] = [
'id' => (int) $radek->ID,
'mesice' => $mesice,
'probiha' => (int) $radek->OTEVRENE > 0,
'vraceno' => $vraceno,
'prideleni' => $prideleni,
'prideleniDatum' => $prideleniDatum,
];
}
return $vysledek;
}
public function vrat(int $id, int $obvod, \DateTimeInterface $vraceno): void
{
$this->database->query(
'UPDATE ZAZNAM SET VRACENO = ? WHERE ID = ? AND OBVOD = ? AND DELETED = 0 AND VRACENO IS NULL',
$vraceno,
$id,
$obvod
);
}
}