<?php declare(strict_types=1); /* * This file is part of contao-weinanlieferung-bundle. * * (c) vonRotenberg * * @license commercial */ namespace vonRotenberg\WeinanlieferungBundle\Controller\Backend; use Contao\Backend; use Contao\CoreBundle\Controller\AbstractController; use Contao\CoreBundle\Csrf\ContaoCsrfTokenManager; use Contao\Date; use Contao\Environment; use Contao\FrontendUser; use Contao\Input; use Contao\MemberModel; use Contao\StringUtil; use Contao\System; use Contao\FilesModel; use Doctrine\DBAL\Connection; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; use Twig\Environment as TwigEnvironment; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungLeseartModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungRebsorteModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungReservationModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungSlotsModel; use vonRotenberg\WeinanlieferungBundle\Model\WeinanlieferungUnitModel; /** * @Route("contao/weinanlieferung/buchungsliste", name=WeinanlieferungBookingsController::class, defaults={"_scope" = "backend"}) */ class WeinanlieferungBookingsController extends AbstractController { private $twig; private $tokenManager; private $request; private $db; public function __construct(TwigEnvironment $twig, ContaoCsrfTokenManager $tokenManager, RequestStack $requestStack, Connection $db) { $this->twig = $twig; $this->tokenManager = $tokenManager; $this->request = $requestStack->getCurrentRequest(); $this->db = $db; $container = System::getContainer(); $objSession = $container->get('session'); $strKey = Input::get('popup') ? 'popupReferer' : 'referer'; $strRefererId = $this->request->attributes->get('_contao_referer_id'); $session = $objSession->get($strKey); $session[$strRefererId]['current'] = substr(Environment::get('requestUri'), \strlen(Environment::get('path')) + 1); $objSession->set($strKey, $session); } public function __invoke(): Response { $GLOBALS['TL_CSS']['cirrus'] = 'bundles/vonrotenbergweinanlieferung/css/backend.css|static'; $arrData = [ 'request_token' => $this->tokenManager->getDefaultTokenValue(), 'ref' => $this->request->attributes->get('_contao_referer_id') ]; System::loadLanguageFile('default'); // Filter /** @var SessionInterface $objSession */ $objSession = \System::getContainer()->get('session'); $session = $objSession->get('filter'); if (Input::post('FORM_SUBMIT') === 'tl_filters') { $arrFilterFields = ['tl_day', 'tl_standort', 'tl_status']; foreach ($arrFilterFields as $v) { if ($v == Input::post($v) || Input::post('filter_reset') == '1') { unset($session['tl_vr_wa_reservation'][$v]); } // Apply the filter else { $session['tl_vr_wa_reservation'][$v] = Input::post($v); } } $objSession->set('filter', $session); Backend::reload(); } $queryBuilder = $this->db->createQueryBuilder() ->select('id') ->from(WeinanlieferungSlotsModel::getTable()); if (!empty($session['tl_vr_wa_reservation']['tl_day']) && is_numeric($session['tl_vr_wa_reservation']['tl_day'])) { $Day = new Date($session['tl_vr_wa_reservation']['tl_day']); $arrData['filter']['day']['selected'] = $session['tl_vr_wa_reservation']['tl_day']; $queryBuilder->andWhere('date BETWEEN :day_start AND :day_end') ->setParameter('day_start', $Day->dayBegin) ->setParameter('day_end', $Day->dayEnd); } else { $Today = new Date(); $queryBuilder->andWhere("time >= :today") ->setParameter('today',$Today->dayBegin); } /*if (!empty(Input::post('tl_month')) && is_numeric(Input::post('tl_month'))) { $Month = new Date(Input::post('tl_month')); $arrData['filter']['month']['selected'] = Input::post('tl_month'); $queryBuilder->andWhere('date BETWEEN :month_start AND :month_end') ->setParameter('month_start', $Month->monthBegin) ->setParameter('month_end', $Month->monthEnd); } else { $Today = new Date(); $queryBuilder->andWhere("time >= :today") ->setParameter('today',$Today->dayBegin); }*/ if (!empty($session['tl_vr_wa_reservation']['tl_standort']) && is_numeric($session['tl_vr_wa_reservation']['tl_standort'])) { $Month = new Date($session['tl_vr_wa_reservation']['tl_standort']); $arrData['filter']['standort']['selected'] = $session['tl_vr_wa_reservation']['tl_standort']; $queryBuilder->andWhere('pid = :pid') ->setParameter('pid', (int) $session['tl_vr_wa_reservation']['tl_standort']); } $arrSlots = $queryBuilder->fetchFirstColumn(); $arrDayOptions = []; $DayRequest = $this->db->executeQuery("SELECT s.date, DATE_FORMAT(FROM_UNIXTIME(s.date),'%d.%m.%Y') as 'day_label' FROM tl_vr_wa_reservation r INNER JOIN tl_vr_wa_slot s ON s.id = r.pid GROUP BY day_label ORDER BY s.date DESC"); foreach ($DayRequest->iterateAssociative() as $day) { $arrDayOptions[$day['date']] = Date::parse(Date::getNumericDateFormat(), $day['date']); } /*$arrMonthOptions = []; $MonthRequest = $this->db->executeQuery("SELECT s.date, DATE_FORMAT(FROM_UNIXTIME(s.date),'%m/%Y') as 'month_label' FROM tl_vr_wa_reservation r INNER JOIN tl_vr_wa_slot s ON s.id = r.pid GROUP BY month_label ORDER BY s.date ASC"); foreach ($MonthRequest->iterateAssociative() as $month) { $arrMonthOptions[$month['date']] = $month['month_label']; }*/ $arrStandortOptions = []; $StandortRequest = $this->db->executeQuery("SELECT l.id, l.title FROM tl_vr_wa_reservation r INNER JOIN tl_vr_wa_slot s ON s.id = r.pid INNER JOIN tl_vr_wa_standort l ON l.id = s.pid GROUP BY l.id ORDER BY l.title ASC"); foreach ($StandortRequest->iterateAssociative() as $standort) { $arrStandortOptions[$standort['id']] = $standort['title']; } $arrData['filter']['day']['options'] = $arrDayOptions; // $arrData['filter']['month']['options'] = $arrMonthOptions; $arrData['filter']['standort']['options'] = $arrStandortOptions; // Get bookings if (isset($queryBuilder)) { $arrColumns = null; if (count($arrSlots)) { $arrColumns[] = "pid IN (".implode(',',$arrSlots).")"; } if (!empty($session['tl_vr_wa_reservation']['tl_status'])) { $arrData['filter']['status']['selected'] = $session['tl_vr_wa_reservation']['tl_status']; switch ($session['tl_vr_wa_reservation']['tl_status']) { case 'pending': $arrColumns[] = "approved = ''"; break; case 'approved': $arrColumns[] = "approved = '1'"; break; case 'canceled': $arrColumns[] = "approved = '0'"; break; } } if (!$arrColumns) { $bookings = WeinanlieferungReservationModel::findAllFuture(['order' => "(SELECT tl_vr_wa_slot.time FROM tl_vr_wa_slot WHERE tl_vr_wa_slot.id=tl_vr_wa_reservation.pid) ASC"]); } else { $bookings = WeinanlieferungReservationModel::findBy($arrColumns,null,['order' => "(SELECT tl_vr_wa_slot.time FROM tl_vr_wa_slot WHERE tl_vr_wa_slot.id=tl_vr_wa_reservation.pid) ASC"]); } } else { $bookings = WeinanlieferungReservationModel::findAllFuture(['order' => "(SELECT tl_vr_wa_slot.time FROM tl_vr_wa_slot WHERE tl_vr_wa_slot.id=tl_vr_wa_reservation.pid) ASC"]); } if ($bookings !== null) { /** @var WeinanlieferungReservationModel $booking */ foreach ($bookings as $booking) { /** @var WeinanlieferungSlotsModel $Slot */ if (($Slot = $booking->getRelated('pid')) !== null) { $day = new Date($Slot->date); $arrSorten = []; $arrErnteart = []; $arrLagen = []; if (!isset($arrData['days'][$day->dayBegin][$Slot->pid])) { $Standort = $Slot->getRelated('pid'); $arrData['days'][$day->dayBegin][$Slot->pid] = [ 'standort' => $Standort !== null ? $Standort->title : '' ]; } if (!isset($arrData['days'][$day->dayBegin][$Slot->pid]['times'][$Slot->time])) { $arrSortenAvailable = []; $Sorten = StringUtil::deserialize($Slot->sorten,true); foreach($Sorten as $sorte) { $objSorte = WeinanlieferungRebsorteModel::findByPk($sorte['sorte']); $objLeseart = WeinanlieferungLeseartModel::findByPk($sorte['leseart']); $arrSortenAvailable[] = ($objSorte !== null ? $objSorte->title : '') . ' ' . ($objLeseart !== null ? $objLeseart->title : ''); } $arrData['days'][$day->dayBegin][$Slot->pid]['times'][$Slot->time] = array_merge($Slot->row(),[ 'sorten' => $arrSortenAvailable, 'behaelterAvailable' => $Slot->getAvailableBehaelter(), ]); } if ($booking->sorten !== null) { $SortenLeseart = explode(';', $booking->sorten); foreach ($SortenLeseart as $sorteLeseart) { list($sorte, $leseart) = explode(',', $sorteLeseart); $objSorte = WeinanlieferungRebsorteModel::findByPk($sorte); $objLeseart = WeinanlieferungLeseartModel::findByPk($leseart); $arrSorten[$objSorte->id . ',' . $objLeseart->id] = ($objSorte !== null ? $objSorte->title : '') . ' ' . ($objLeseart !== null ? $objLeseart->title : ''); } } if ($booking->ernteart !== null) { foreach (explode(',', $booking->ernteart) as $ernteart) { $arrErnteart[$ernteart] = $GLOBALS['TL_LANG']['REF']['wa_ernteart'][$ernteart] ?? $ernteart; } } if (($Lagen = $booking->getRelated('lage')) !== null) { foreach ($Lagen as $lage) { $arrLagen[$lage->id] = $lage->title; } } $strStandort = ''; if (($Standort = $Slot->getRelated('pid')) !== null) { $strStandort = $Standort->title; } $behaelterNumbers = json_decode($booking->behaelter_numbers ?? '[]', true); $isNewFormat = isset($behaelterNumbers[0]) && is_array($behaelterNumbers[0]) && isset($behaelterNumbers[0]['behaelter']); // If it's the old format, convert it to the new format for compatibility if (!$isNewFormat) { $oldFormat = $behaelterNumbers; $memberModel = MemberModel::findById($booking->uid); $behaelterNumbers = []; foreach ($oldFormat as $number) { $behaelterNumbers[] = [ 'behaelter' => $number, 'member' => $memberModel->memberno ]; } } // Prepare upload file info if available $uploadFile = null; if (!empty($booking->upload)) { $objFile = FilesModel::findByUuid($booking->upload); if ($objFile !== null) { $router = System::getContainer()->get('router'); $popupHref = $router->generate('contao_backend_popup', ['src' => base64_encode($objFile->path)]); $uploadFile = [ 'name' => $objFile->name, 'filename' => $objFile->name, 'path' => $objFile->path, 'popup_href' => $popupHref, 'popup_title' => $objFile->name ]; } } // Compute unit display fields for backend list $unitTitle = 'Behälter'; $unitAmountDisplay = (int) $booking->behaelter; if (!empty($booking->unit_id) && (int)$booking->unit_id > 0) { $unitModel = WeinanlieferungUnitModel::findByPk((int)$booking->unit_id); if (null !== $unitModel) { $unitTitle = (string)$unitModel->title; } $unitAmountDisplay = (int) ($booking->unit_amount ?: 0); if ($unitAmountDisplay <= 0) { // Fallback just in case: derive amount by multiplier if available $mult = (int) ($unitModel ? $unitModel->multiplier : 0); $unitAmountDisplay = $mult > 0 ? max(1, (int) ($booking->behaelter / $mult)) : (int) $booking->behaelter; } } $arrData['days'][$day->dayBegin][$Slot->pid]['times'][$Slot->time]['items'][] = array_merge($booking->row(), [ 'sorte' => $arrSorten, 'ernteart' => $arrErnteart, 'lage' => $arrLagen, 'slot' => $Slot->row(), 'standort' => $strStandort, 'member' => $booking->getRelated('uid') !== null ? $booking->getRelated('uid')->row() : null, 'behaelter_numbers' => $behaelterNumbers, 'upload_file' => $uploadFile, 'unit_title' => $unitTitle, 'unit_amount_display' => $unitAmountDisplay, ]); } } } return new Response( $this->twig->render( '@Contao_VonrotenbergWeinanlieferungBundle/be_wa_buchungsliste.html.twig', $arrData ) ); } }