<?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
)
);
}
}