<?php
namespace App\Controller\Support;
use App\Entity\Box;
use App\Classes\Dictionaries\BoxState;
use App\Entity\Configuration;
use App\Entity\OrderDelivery;
use App\Classes\Dictionaries\OrderState;
use App\Entity\PackageDelivery;
use App\Classes\Dictionaries\PackageState;
use Doctrine\DBAL\Exception;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Exception\ORMException;
use Doctrine\ORM\OptimisticLockException;
use Psr\Log\LoggerInterface;
use RuntimeException;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use PhpMyAdmin\SqlParser\Parser;
use PhpMyAdmin\SqlParser\Statement;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
use function in_array;
class UtilityController extends AbstractController
{
/**
* Dočasná metoda pro výpis objednávek/balíků v nekonzistentním stavu zrušen/nezrušen
* @param EntityManagerInterface $entityManager
* @return Response
*/
public function fixCanceledPackagesAndOrders(EntityManagerInterface $entityManager): Response
{
echo 'Objednávky, které obsahují jenom zrušené balíky, ale nejsou zrušené.' . '</br>';
$packageDeliveryRepo = $entityManager->getRepository(PackageDelivery::class);
//canceledPackagesWithActiveOrder
$canceledPackages = $packageDeliveryRepo->findBy(['packageState' => PackageState::STATE_CANCELED]);
foreach ($canceledPackages as $package) {
$order = $package->getOrder();
if ($order->getOrderState() === OrderState::STATE_CANCELED) {
//zrušený balík ve zrušené objednávce = ok
continue;
} else {
//zrušený balík ve objednávce která není zrušená = možná špatně
$cancelOrder = true;
if ($order->getPackages()->count() !== 1) {
foreach ($order->getPackages() as $packageInOrder) {
if ($packageInOrder->getPackageState() !== PackageState::STATE_CANCELED) {
$cancelOrder = false;
}
}
}
//balík je v obj jediný, nebo i ostatní jsou zrušené = zrušit obj
if ($cancelOrder) {
echo $order->getIdentifier() . '</br>';
}
}
}
echo '---------------------------' . '</br>';
echo 'Nezrušené balíky ve zrušených objednávkách' . '</br>';
$orderDeliveryRepo = $entityManager->getRepository(OrderDelivery::class);
//canceledPackagesWithActiveOrder
$canceledOrders = $orderDeliveryRepo->findBy(['orderState' => OrderState::STATE_CANCELED]);
foreach ($canceledOrders as $order) {
$packages = $order->getPackages();
//echo $order->getIdentifier()."</br>";
foreach ($packages as $package) {
if ($package->getPackageState() !== PackageState::STATE_CANCELED) {
echo $package->getPackageCode()->getCode() . '</br>';
}
}
}
return new Response();
}
/**
* Najde krabice, jejich balíčky jsou už naskladněny, nebo vydány, ale krabice sama je nedoručená. Krabice bude dodatečně označená jako doručená.
* @param EntityManagerInterface $entityManager
* @param Security $security
* @return RedirectResponse
* @throws ORMException
* @throws OptimisticLockException
*/
public function fixDeliveredBoxes(EntityManagerInterface $entityManager, Security $security): RedirectResponse
{
$boxRepo = $entityManager->getRepository(Box::class);
$boxes = $boxRepo->findBy(['delivered'=>null,'boxState'=>BoxState::STATE_CLOSED]);
$message = "";
foreach ($boxes as $box) {
$packages = $box->getPackages();
$toFix = true;
foreach ($packages as $package) {
if (!in_array($package->getPackageState(), [PackageState::STATE_ON_DELIVERY_POINT, PackageState::STATE_PICKED_UP, PackageState::STATE_CANCELED])) {
$toFix = false;
}
}
if ($toFix === true) {
$boxRepo->deliverBoxAndSave($box, $security->getUser());
$message .= ' ' .$box->getCode()->getCode(). ', ';
}
}
$message = substr($message, 0, -2);
$this->addFlash('success', 'Nedořučené krabice, které měly všechny balíky vydané nebo na výdejně byly nastaveny jako doručené.' .$message);
return $this->redirectToRoute('support_index');
}
/**
* Po zavolání url obnoví obsah databáze.
* Může zavolat přihlášený uživatel.
* @param KernelInterface $kernel
* @param EntityManagerInterface $entityManager
* @param LoggerInterface $logger
* @param TranslatorInterface $translator
* @return RedirectResponse
* @throws Exception
* @throws \Exception
*/
public function databaseReset(
KernelInterface $kernel,
EntityManagerInterface $entityManager,
LoggerInterface $logger,
TranslatorInterface $translator
): RedirectResponse {
if ($kernel->getEnvironment() === 'demo') {
$basePath = $kernel->getProjectDir() . '/docker/build/backend/database_bootstrap.sql';
$baseQuery = file_get_contents($basePath);
if ($baseQuery === '') {
throw new RuntimeException(
$translator->trans('SQL skript: %path% ...je prázdný', ['%path%' => $basePath], 'support')
);
}
$demoPath = $kernel->getProjectDir() . '/docker/build/backend/database_bootstrap_demo.sql';
$demoQuery = file_get_contents($demoPath);
if ($demoQuery === '') {
throw new RuntimeException(
$translator->trans('SQL skript: %path% ...je prázdný', ['%path%' => $demoPath], 'support')
);
}
$application = new Application($kernel);
$application->setAutoExit(false);
//dropnutí tabulek
$input = new StringInput('doctrine:schema:drop --force --full-database');
$output = new BufferedOutput();
$application->run($input, $output);
$info = $output->fetch();
$content = $info;
$logger->info($info);
//obnovení prázdné databáze
$input = new StringInput('doctrine:schema:update --force');
$output = new BufferedOutput();
$application->run($input, $output);
$info = $output->fetch();
$content .= $info;
$logger->info($info);
//naparsování a provedení SQL base skriptu
$sqlParser = new Parser($baseQuery);
$statementsCount = 0;
foreach ($sqlParser->statements as $statement) {
$entityManager->getConnection()->executeQuery(
/** @var Statement $statement */
str_replace('`', '', $statement->build()),
);
$statementsCount++;
}
$entityManager->clear();
//naparsování a provedení SQL base skriptu
$sqlParser = new Parser($demoQuery);
foreach ($sqlParser->statements as $statement) {
$entityManager->getConnection()->executeQuery(
/** @var Statement $statement */
str_replace('`', '', $statement->build()),
);
$statementsCount++;
}
$entityManager->clear();
$info = 'Executed ' . $statementsCount . ' statements. Database ready...[OK]';
$content .= $info;
$logger->info($info);
$this->addFlash('success', $content);
return $this->redirectToRoute('support_index');
}
throw new RuntimeException(
$translator->trans('Tento skript lze spustit pouze v prostředí "demo".', [], 'support')
);
}
/**
* Vrátí odpověď s blokem, který obsahuje číslo a email na podporu.
* Číslo a email je zvoleno podle domény. postman/delivery
* @param EntityManagerInterface $em
* @param LoggerInterface $logger
* @return Response
*/
public function supportContact(EntityManagerInterface $em, LoggerInterface $logger): Response
{
$config = $em->getRepository(Configuration::class);
try {
return $this->render('Support/InternalTemplates/Shared/support_contact.html.twig', [
'support_delivery_phone' => $config->get('support_delivery_phone'),
'support_postman_phone' => $config->get('support_postman_phone'),
'support_delivery_support_email' => $config->get('support_delivery_support_email'),
'support_postman_email' => $config->get('support_postman_email')
]);
} catch (\Exception $e) {
$logger->error($e->getMessage().' '.$e->getFile().':'.$e->getLine());
return new Response('');
}
}
}