framework = $framework;
$this->tokenChecker = $tokenChecker;
$this->translator = $translator;
}
public function __invoke(Request $request)
{
System::loadLanguageFile('default');
if (!$this->tokenChecker->hasFrontendUser())
{
return $this->renderUnauthorized();
}
if (empty($_REQUEST['do']))
{
return new Response('Required parameter missing',412);
}
$blnModal = true;
if (!empty($_REQUEST['modal']))
{
$blnModal = !(strtolower($_REQUEST['modal']) == 'false');
}
switch ($_REQUEST['do'])
{
case 'details':
return $this->renderDetails($blnModal);
case 'annotation':
return $this->renderAnnotation($blnModal);
case 'booking':
return $this->renderBooking($blnModal);
case 'reservate':
return $this->reservate();
case 'updateReservation':
return $this->updateReservation();
case 'availableUnitAmount':
return $this->renderAvailableUnitAmount();
case 'availableBookingUnitAmount':
return $this->renderAvailableBookingUnitAmount();
case 'delete':
return $this->deleteReservation();
}
return new Response('',500);
}
protected function renderDetails(bool $blnModal=true,string $error=null)
{
$insertTagService = Controller::getContainer()->get('contao.insert_tag.parser');
if (empty($_REQUEST['id']))
{
return new Response('Required parameter missing',412);
}
if (($Slot = WeinanlieferungSlotsModel::findPublishedById($_REQUEST['id'])) === null)
{
return new Response('Could not load slot data',500);
}
// Get slot reservations from user
$arrReservations = [];
if (($Reservations = WeinanlieferungReservationModel::findBy(["uid = ?","pid = ?"],[FrontendUser::getInstance()->id,$Slot->id])) !== null)
{
foreach ($Reservations as $reservation)
{
$Unit = WeinanlieferungUnitsModel::findByPk($reservation->unit);
$arrReservations[] = array_merge($reservation->row(),[
'unitLabel' => $Unit->title ?? $this->translator->trans('tl_vr_wa_units.containers.0', [], 'contao_tl_vr_wa_units')
]);
}
}
// Build data
$intAvailableBehaelter = max(0,$Slot->getAvailableBehaelter());
$intBookableBehaelter = $Slot->getAvailableBehaelter() + $Slot->getOvercapacityBehaelter();
$arrUnits = [];
if (($Site = $Slot->getRelated('pid')) !== null)
{
if (($Units = $Site->getRelated('units')) !== null)
{
foreach ($Units as $unit)
{
// $arrUnits[$unit->id] = $unit->title . ' (' . $unit->containers . ' '.$this->translator->trans('tl_vr_wa_units.containers.0', [], 'contao_tl_vr_wa_units').')';
$arrUnits[$unit->id] = $unit->title;
}
}
}
// Load attribute groups and attributes
$arrAttributeGroups = [];
// Get selected attributes
$selectedAttributeIds = [];
if ($Slot->attributes) {
$selectedAttributeIds = array_map('trim', explode(',', $Slot->attributes));
}
// If no attributes are selected, don't show any
if (empty($selectedAttributeIds)) {
// Keep the attribute_groups array empty
} else {
// Fetch the selected attributes
$selectedAttributes = WeinanlieferungAttributeModel::findMultipleByIds($selectedAttributeIds);
if ($selectedAttributes !== null) {
// Group the attributes by their parent group
$attributesByGroup = [];
$groupIds = [];
// First pass: collect all group IDs and organize attributes by group
foreach ($selectedAttributes as $attribute) {
$groupId = $attribute->pid;
$groupIds[] = $groupId;
if (!isset($attributesByGroup[$groupId])) {
$attributesByGroup[$groupId] = [];
}
$attributesByGroup[$groupId][] = [
'id' => $attribute->id,
'title' => $attribute->title,
'description' => $attribute->description
];
}
// Get unique group IDs
$groupIds = array_unique($groupIds);
// Fetch the groups
if (!empty($groupIds)) {
$groups = WeinanlieferungAttributeGroupModel::findMultipleByIds($groupIds);
if ($groups !== null) {
// Create the attribute groups array
foreach ($groups as $group) {
if (isset($attributesByGroup[$group->id])) {
$arrAttributeGroups[] = [
'id' => $group->id,
'title' => $group->title,
'description' => $group->description,
'type' => $group->type,
'multiple' => (bool)$group->multiple,
'required' => (bool)$group->required,
'attributes' => $attributesByGroup[$group->id]
];
}
}
}
}
}
}
$standort = $Slot->getRelated('pid');
$disable_base_unit = !empty($standort->disable_base_unit);
// Determine default selected unit
$defaultUnitId = '';
if ($disable_base_unit && !empty($arrUnits)) {
// If base unit is disabled, select the first available unit
reset($arrUnits);
$defaultUnitId = key($arrUnits);
}
// Adjust quantity options based on default unit
$behaelterOptions = range(min($intBookableBehaelter,1), $intBookableBehaelter);
if ($defaultUnitId && ($Unit = WeinanlieferungUnitsModel::findByPk($defaultUnitId)) !== null) {
$intDefault = floor($intAvailableBehaelter / max(1, $Unit->containers));
$intAmount = floor($intBookableBehaelter / max(1, $Unit->containers));
$behaelterOptions = $intAmount ? range(1, $intAmount) : [];
}
$arrData = [
'modal' => $blnModal,
'id' => $Slot->id,
'slot' => array_merge($Slot->row(),[
'anmerkungen' => $insertTagService->replace($Slot->anmerkungen ?? ''),
'behaelterAvailable' => $intAvailableBehaelter
]),
'standort' => $standort,
'buchen' => [
'buchbar' => (boolean) $intAvailableBehaelter,
'behaelter' => $behaelterOptions,
'units' => $arrUnits,
'disable_base_unit' => $disable_base_unit,
'default_unit' => $defaultUnitId
],
'reservations' => $arrReservations,
'attribute_groups' => $arrAttributeGroups
];
if (!empty($error))
{
$arrData['toast'] = $error;
}
return $this->render('@Contao/modal_slot_details.html.twig',$arrData);
}
protected function renderAnnotation(bool $blnModal=true,string $error=null)
{
$insertTagService = Controller::getContainer()->get('contao.insert_tag.parser');
if (empty($_REQUEST['id']))
{
return new Response('Required parameter missing',412);
}
if (($Slot = WeinanlieferungSlotsModel::findPublishedById($_REQUEST['id'])) === null)
{
return new Response('Could not load slot data',500);
}
// Build data
$arrSorten = [];
$Sorten = StringUtil::deserialize($Slot->sorten,true);
foreach($Sorten as $sorte)
{
$objSorte = WeinanlieferungRebsorteModel::findByPk($sorte['sorte']);
$objLeseart = WeinanlieferungLeseartModel::findByPk($sorte['leseart']);
$arrSorten[$objSorte->id.','.$objLeseart->id] = ($objSorte !== null ? $objSorte->title : '') . ' ' . ($objLeseart !== null ? $objLeseart->title : '');
}
$arrErnteart = [];
if ($Slot->ernteart !== null)
{
foreach (explode(',', $Slot->ernteart) as $ernteart)
{
$arrErnteart[] = $GLOBALS['TL_LANG']['REF']['wa_ernteart'][$ernteart] ?? $ernteart;
}
}
$arrLage = [];
if (($Lage = $Slot->getRelated('lage')) !== null)
{
$arrLage = $Lage->fetchEach('title');
}
$intAvailableBehaelter = max(0,$Slot->getAvailableBehaelter());
$arrData = [
'modal' => $blnModal,
'id' => $Slot->id,
'slot' => array_merge($Slot->row(),[
'anmerkungen' => $insertTagService->replace($Slot->anmerkungen ?? ''),
'sorte' => $arrSorten,
'behaelterAvailable' => $intAvailableBehaelter
]),
'standort' => $Slot->getRelated('pid'),
'lage' => $arrLage,
'ernteart' => $arrErnteart,
'buchen' => [
'buchbar' => (boolean) $intAvailableBehaelter,
'behaelter' => range(min($intAvailableBehaelter,1),$intAvailableBehaelter),
'sorten' => $arrSorten
],
];
return $this->render('@Contao/modal_slot_annotation.html.twig',$arrData);
}
protected function renderBooking(bool $blnModal=true,string $error=null)
{
$insertTagService = Controller::getContainer()->get('contao.insert_tag.parser');
$arrData = [];
if (empty($_REQUEST['id']))
{
return new Response('Required parameter missing',412);
}
/** @var WeinanlieferungSlotsModel $Slot */
if (($Booking = WeinanlieferungReservationModel::findById($_REQUEST['id'])) === null || ($Slot = $Booking->getRelated('pid')) === null)
{
return new Response('Could not load booking data',500);
}
$objFile = FilesModel::findByUuid($Booking->upload);
if (!empty($_REQUEST['deleteFile']) && $_REQUEST['deleteFile'] && $objFile !== null)
{
$File = new File($objFile->path);
if ($File->delete())
{
$objFile->delete();
$objFile = null;
}
}
if (!empty($Booking->upload) && $objFile !== null)
{
$File = new File($objFile->path);
$strHref = Environment::get('request');
// Remove an existing file parameter (see #5683)
if (isset($_GET['file']))
{
$strHref = preg_replace('/(&(amp;)?|\?)file=[^&]+/', '', $strHref);
}
$strHref .= (strpos($strHref, '?') !== false ? '&' : '?') . 'file=' . System::urlEncode($File->value);
$arrData['file'] = [
'link' => $strHref,
'filename' => $File->filename,
'extension' => $File->extension,
'name' => $File->name,
'path' => $File->dirname
];
}
// Send the file to the browser (see #4632 and #8375)
if ($objFile !== null && ($file = Input::get('file', true)))
{
if ($file == $objFile->path)
{
Controller::sendFileToBrowser($file);
}
}
$intAvailableBehaelter = max(0,$Slot->getAvailableBehaelter());
$intBookableBehaelter = $Slot->getAvailableBehaelter() + $Slot->getOvercapacityBehaelter();
$intDefaultAmount = $intAvailableBehaelter+$Booking->behaelter;
$intUnitAmount = $intBookableBehaelter+$Booking->behaelter;
$arrUnits = [];
if (($Site = $Slot->getRelated('pid')) !== null)
{
if (($Units = $Site->getRelated('units')) !== null)
{
foreach ($Units as $unit)
{
//$arrUnits[$unit->id] = $unit->title . ' (' . $unit->containers . ' '.$this->translator->trans('tl_vr_wa_units.containers.0', [], 'contao_tl_vr_wa_units').')';
$arrUnits[$unit->id] = $unit->title;
}
}
if ($Booking->unit > 0 && \in_array($Booking->unit, array_keys($arrUnits)))
{
if (($Unit = WeinanlieferungUnitsModel::findByPk($Booking->unit)) === null)
{
return new Response('Could not load unit data', 500);
}
$intDefaultAmount = floor($intDefaultAmount / max(1, $Unit->containers));
$intUnitAmount = floor($intUnitAmount / max(1, $Unit->containers));
}
}
// Load attribute groups and attributes
$arrAttributeGroups = [];
$attributeValues = [];
// Parse existing attribute values if available
if (!empty($Booking->attribute_values)) {
try {
$attributeValues = json_decode($Booking->attribute_values, true);
if (!is_array($attributeValues)) {
$attributeValues = [];
}
} catch (\Exception $e) {
$attributeValues = [];
}
}
// Get selected attributes
$selectedAttributeIds = [];
if ($Slot->attributes) {
$selectedAttributeIds = array_map('trim', explode(',', $Slot->attributes));
}
// If no attributes are selected, don't show any
if (empty($selectedAttributeIds)) {
// Keep the attribute_groups array empty
} else {
// Fetch the selected attributes
$selectedAttributes = WeinanlieferungAttributeModel::findMultipleByIds($selectedAttributeIds);
if ($selectedAttributes !== null) {
// Group the attributes by their parent group
$attributesByGroup = [];
$groupIds = [];
// First pass: collect all group IDs and organize attributes by group
foreach ($selectedAttributes as $attribute) {
$groupId = $attribute->pid;
$groupIds[] = $groupId;
if (!isset($attributesByGroup[$groupId])) {
$attributesByGroup[$groupId] = [];
}
$attributesByGroup[$groupId][] = [
'id' => $attribute->id,
'title' => $attribute->title,
'description' => $attribute->description,
'value' => $attributeValues[$attribute->id] ?? null
];
}
// Get unique group IDs
$groupIds = array_unique($groupIds);
// Fetch the groups
if (!empty($groupIds)) {
$groups = WeinanlieferungAttributeGroupModel::findMultipleByIds($groupIds);
if ($groups !== null) {
// Create the attribute groups array
foreach ($groups as $group) {
if (isset($attributesByGroup[$group->id])) {
$arrAttributeGroups[] = [
'id' => $group->id,
'title' => $group->title,
'description' => $group->description,
'type' => $group->type,
'multiple' => (bool)$group->multiple,
'required' => (bool)$group->required,
'attributes' => $attributesByGroup[$group->id]
];
}
}
}
}
}
}
$standort = $Slot->getRelated('pid');
$disable_base_unit = !empty($standort->disable_base_unit);
// Determine default selected unit
$defaultUnitId = $Booking->unit ?: '';
if ($defaultUnitId === '' && $disable_base_unit && !empty($arrUnits)) {
// If base unit is disabled and no unit is selected, select the first available unit
reset($arrUnits);
$defaultUnitId = key($arrUnits);
}
// Adjust quantity options based on default unit if needed
$behaelterOptions = $intUnitAmount ? range(1, $intUnitAmount) : [];
$arrData = array_merge($arrData,[
'modal' => $blnModal,
'id' => $Booking->id,
'slot' => array_merge($Slot->row(),[
'anmerkungen' => $insertTagService->replace($Slot->anmerkungen ?? ''),
'behaelterAvailable' => $intAvailableBehaelter + $Booking->behaelter,
]),
'buchung' => $Booking->row(),
'standort' => $standort,
'buchen' => [
'buchbar' => (boolean) $intBookableBehaelter,
'default' => $intDefaultAmount,
'behaelter' => $behaelterOptions,
'units' => $arrUnits,
'disable_base_unit' => $disable_base_unit,
'default_unit' => $defaultUnitId
],
'attribute_groups' => $arrAttributeGroups
]);
if (!empty($error))
{
$arrData['toast'] = $error;
}
return $this->render('@Contao/modal_booking_details.html.twig',$arrData);
}
protected function reservate()
{
Controller::loadDataContainer('tl_vr_wa_reservation');
$arrData = [];
if (($Slot = WeinanlieferungSlotsModel::findByPk($_REQUEST['id'])) === null)
{
return $this->renderDetails(false,'
Fehler: der Zeitslot ist nicht verfügbar.
');
}
if (($rootPage = Frontend::getRootPageFromUrl()) !== null && !empty($rootPage->vr_wa_uploadFolderSRC))
{
$File = new FormFileUpload(\Contao\Widget::getAttributesFromDca($GLOBALS['TL_DCA']['tl_vr_wa_reservation']['fields']['upload'], 'upload'));
$File->storeFile = true;
$File->doNotOverwrite = true;
$File->uploadFolder = $rootPage->vr_wa_uploadFolderSRC;
$File->validate();
if ($File->hasErrors())
{
return $this->renderDetails(false,'' . $File->getErrorAsHTML() . '
');
}
if (!empty($_SESSION['FILES'][$File->name]))
{
$arrData['filename'] = $_SESSION['FILES'][$File->name]['name'] ?? '';
$arrData['upload'] = $_SESSION['FILES'][$File->name]['uuid'] ? StringUtil::uuidToBin($_SESSION['FILES'][$File->name]['uuid']) : null;
}
}
if (empty($_REQUEST['id']))
{
return new Response('Missing parameter',412);
}
// Form validation
$intBehaelter = Input::post('behaelter');
if (Input::post('behaelter') > $Slot->getAvailableBehaelter(true))
{
return $this->renderDetails(false,sprintf('Fehler: Es sind mittlerweile nur noch %s Bottiche verfügbar.
',$Slot->getAvailableBehaelter(true)));
}
$arrError = [];
foreach (['behaelter'] as $field)
{
if (empty(Input::post($field)))
{
$arrError = [$field];
}
}
// Get allowed units
if (Input::post('unit'))
{
if (($SelectedUnit = WeinanlieferungUnitsModel::findByPk(intval(Input::post('unit')))) === null)
{
return $this->renderDetails(false, 'Die gewünschte Botticheinheit steht nicht zur Verfügung. Bitte versuchen Sie es noch einmal.
');
}
if (($Site = $Slot->getRelated('pid')) !== null)
{
$unitIds = StringUtil::deserialize($Site->units, true);
$Units = WeinanlieferungUnitsModel::findMultipleByIds($unitIds);
if (!\in_array(intval(Input::post('unit')), $Units->fetchEach('id')))
{
return $this->renderDetails(false, 'Die gewünschte Botticheinheit steht nicht mehr zur Verfügung. Bitte versuchen Sie es noch einmal.
');
}
}
$intBehaelter = intval($intBehaelter) * intval($SelectedUnit->containers);
}
// Process attribute values
$attributeValues = [];
// Get selected attributes
$selectedAttributeIds = [];
if ($Slot->attributes) {
$selectedAttributeIds = array_map('trim', explode(',', $Slot->attributes));
}
// If no attributes are selected, skip attribute processing
if (!empty($selectedAttributeIds)) {
// Fetch the selected attributes
$selectedAttributes = WeinanlieferungAttributeModel::findMultipleByIds($selectedAttributeIds);
if ($selectedAttributes !== null) {
// Group the attributes by their parent group
$attributesByGroup = [];
$groupIds = [];
// First pass: collect all group IDs
foreach ($selectedAttributes as $attribute) {
$groupId = $attribute->pid;
$groupIds[] = $groupId;
}
// Get unique group IDs
$groupIds = array_unique($groupIds);
// Fetch the groups
if (!empty($groupIds)) {
$groups = WeinanlieferungAttributeGroupModel::findMultipleByIds($groupIds);
if ($groups !== null) {
// Create maps for attribute-to-group, group-required status, and group-type
$attributeToGroupMap = [];
$groupRequiredMap = [];
$groupTypeMap = [];
foreach ($groups as $group) {
$groupRequiredMap[$group->id] = (bool)$group->required;
$groupTypeMap[$group->id] = $group->type;
}
foreach ($selectedAttributes as $attribute) {
$attributeToGroupMap[$attribute->id] = $attribute->pid;
}
// Track which groups have values
$groupHasValue = [];
// Process the selected attributes
foreach ($selectedAttributes as $attribute) {
$attributeKey = 'attribute_' . $attribute->id;
$groupId = $attributeToGroupMap[$attribute->id];
$groupType = $groupTypeMap[$groupId];
$groupKey = 'group_' . $groupId;
if ($groupType === 'text') {
// For text attributes, store the text value
if (!empty(Input::post($attributeKey))) {
$attributeValues[$attribute->id] = Input::post($attributeKey);
$groupHasValue[$groupId] = true;
}
} else if ($groupType === 'option') {
// For option attributes with multiple values (checkboxes)
if (Input::post($attributeKey)) {
$attributeValues[$attribute->id] = true;
$groupHasValue[$groupId] = true;
}
// For option attributes with single value (radio buttons)
else if (Input::post($groupKey) == $attribute->id) {
$attributeValues[$attribute->id] = true;
$groupHasValue[$groupId] = true;
}
}
}
// Check if required groups have values
foreach ($groupRequiredMap as $groupId => $isRequired) {
if ($isRequired && empty($groupHasValue[$groupId])) {
$arrError[] = 'attribute_group_' . $groupId;
}
}
}
}
}
}
if (count($arrError))
{
return $this->renderDetails(false,'Bitte geben Sie alle Pflichtangaben (mit * markierte Felder) an
');
}
$Reservation = new WeinanlieferungReservationModel();
$arrData = array_merge($arrData,[
'pid' => $_REQUEST['id'],
'tstamp' => time(),
'uid' => FrontendUser::getInstance()->id,
'unit' => intval(Input::post('unit')),
'behaelter' => $intBehaelter,
'amount' => Input::post('behaelter'),
'annotation' => Input::post('annotation'),
'attribute_values' => !empty($attributeValues) ? json_encode($attributeValues) : null,
]);
$Reservation->setRow($arrData);
$Reservation->save();
return new Response('',200,['HX-Trigger'=> 'updateWaList']);
}
protected function updateReservation()
{
Controller::loadDataContainer('tl_vr_wa_reservation');
if (empty($_REQUEST['id']))
{
return new Response('Missing parameter',412);
}
if (($Reservation = WeinanlieferungReservationModel::findById($_REQUEST['id'])) === null)
{
return $this->renderBooking(false,'Fehler: Buchung kann nicht geladen werden.
');
}
if (($Slot = $Reservation->getRelated('pid')) === null)
{
return $this->renderBooking(false,'Fehler: der Zeitslot ist nicht verfügbar.
');
}
if (($rootPage = Frontend::getRootPageFromUrl()) !== null && !empty($rootPage->vr_wa_uploadFolderSRC))
{
$File = new FormFileUpload(\Contao\Widget::getAttributesFromDca($GLOBALS['TL_DCA']['tl_vr_wa_reservation']['fields']['upload'], 'upload'));
$File->storeFile = true;
$File->doNotOverwrite = true;
$File->uploadFolder = $rootPage->vr_wa_uploadFolderSRC;
$File->validate();
if ($File->hasErrors())
{
return $this->renderBooking(false,'' . $File->getErrorAsHTML() . '
');
}
if (!empty($_SESSION['FILES'][$File->name]))
{
$Reservation->filename = $_SESSION['FILES'][$File->name]['name'] ?? '';
$Reservation->upload = $_SESSION['FILES'][$File->name]['uuid'] ? StringUtil::uuidToBin($_SESSION['FILES'][$File->name]['uuid']) : null;
}
}
// Form validation
$intBehaelter = Input::post('behaelter');
if (Input::post('behaelter') > $Slot->getAvailableBehaelter(true)+$Reservation->behaelter)
{
return $this->renderBooking(false,sprintf('Fehler: Es sind mittlerweile nur noch %s Bottiche verfügbar.
',$Slot->getAvailableBehaelter(true)+$Reservation->behaelter));
}
$arrError = [];
foreach (['behaelter'] as $field)
{
if (empty(Input::post($field)))
{
$arrError = [$field];
}
}
// Get allowed units
if (Input::post('unit'))
{
if (($SelectedUnit = WeinanlieferungUnitsModel::findByPk(intval(Input::post('unit')))) === null)
{
return $this->renderDetails(false, 'Die gewünschte Botticheinheit steht nicht zur Verfügung. Bitte versuchen Sie es noch einmal.
');
}
if (($Site = $Slot->getRelated('pid')) !== null)
{
$unitIds = StringUtil::deserialize($Site->units, true);
$Units = WeinanlieferungUnitsModel::findMultipleByIds($unitIds);
if (!\in_array(intval(Input::post('unit')), $Units->fetchEach('id')))
{
return $this->renderDetails(false, 'Die gewünschte Botticheinheit steht nicht mehr zur Verfügung. Bitte versuchen Sie es noch einmal.
');
}
}
$intBehaelter = intval($intBehaelter) * intval($SelectedUnit->containers);
}
// Process attribute values
$attributeValues = [];
// Get selected attributes
$selectedAttributeIds = [];
if ($Slot->attributes) {
$selectedAttributeIds = array_map('trim', explode(',', $Slot->attributes));
}
// If no attributes are selected, skip attribute processing
if (!empty($selectedAttributeIds)) {
// Fetch the selected attributes
$selectedAttributes = WeinanlieferungAttributeModel::findMultipleByIds($selectedAttributeIds);
if ($selectedAttributes !== null) {
// Group the attributes by their parent group
$attributesByGroup = [];
$groupIds = [];
// First pass: collect all group IDs
foreach ($selectedAttributes as $attribute) {
$groupId = $attribute->pid;
$groupIds[] = $groupId;
}
// Get unique group IDs
$groupIds = array_unique($groupIds);
// Fetch the groups
if (!empty($groupIds)) {
$groups = WeinanlieferungAttributeGroupModel::findMultipleByIds($groupIds);
if ($groups !== null) {
// Create maps for attribute-to-group, group-required status, and group-type
$attributeToGroupMap = [];
$groupRequiredMap = [];
$groupTypeMap = [];
foreach ($groups as $group) {
$groupRequiredMap[$group->id] = (bool)$group->required;
$groupTypeMap[$group->id] = $group->type;
}
foreach ($selectedAttributes as $attribute) {
$attributeToGroupMap[$attribute->id] = $attribute->pid;
}
// Track which groups have values
$groupHasValue = [];
// Process the selected attributes
foreach ($selectedAttributes as $attribute) {
$attributeKey = 'attribute_' . $attribute->id;
$groupId = $attributeToGroupMap[$attribute->id];
$groupType = $groupTypeMap[$groupId];
$groupKey = 'group_' . $groupId;
if ($groupType === 'text') {
// For text attributes, store the text value
if (!empty(Input::post($attributeKey))) {
$attributeValues[$attribute->id] = Input::post($attributeKey);
$groupHasValue[$groupId] = true;
}
} else if ($groupType === 'option') {
// For option attributes with multiple values (checkboxes)
if (Input::post($attributeKey)) {
$attributeValues[$attribute->id] = true;
$groupHasValue[$groupId] = true;
}
// For option attributes with single value (radio buttons)
else if (Input::post($groupKey) == $attribute->id) {
$attributeValues[$attribute->id] = true;
$groupHasValue[$groupId] = true;
}
}
}
// Check if required groups have values
foreach ($groupRequiredMap as $groupId => $isRequired) {
if ($isRequired && empty($groupHasValue[$groupId])) {
$arrError[] = 'attribute_group_' . $groupId;
}
}
}
}
}
}
if (count($arrError))
{
return $this->renderBooking(false,'Bitte geben Sie alle Pflichtangaben (mit * markierte Felder) an
');
}
$Reservation->tstamp = time();
$Reservation->unit = intval(Input::post('unit'));
$Reservation->behaelter = $intBehaelter;
$Reservation->amount = Input::post('behaelter');
$Reservation->annotation = Input::post('annotation');
$Reservation->attribute_values = !empty($attributeValues) ? json_encode($attributeValues) : null;
$Reservation->save();
return new Response('Reservierung erfolgreich geändert
',200,['HX-Trigger'=> 'updateWaBooking']);
}
protected function deleteReservation()
{
if (empty($_REQUEST['id']))
{
return new Response('Missing parameter',412);
}
/** @var Connection $db */
$db = Controller::getContainer()->get('database_connection');
$arrCriteria = [
'uid' => FrontendUser::getInstance()->id,
'id' => $_REQUEST['id']
];
if ($db->delete('tl_vr_wa_reservation',$arrCriteria))
{
return new Response(null,203,['HX-Trigger'=> 'updateWaBooking']);
}
return new Response('Could not delete',500);
}
protected function renderUnauthorized()
{
return $this->render('@Contao/modal_unauthorized.html.twig');
}
protected function renderAvailableUnitAmount(): Response
{
if (empty($_REQUEST['id']))
{
return new Response('Required parameter missing',412);
}
if (($Slot = WeinanlieferungSlotsModel::findPublishedById($_REQUEST['id'])) === null)
{
return new Response('Could not load slot data',500);
}
$intDefault = max(0,$Slot->getAvailableBehaelter());
$intAmount = $intDefault;
if ($intDefault > 0)
{
$intOvercapacityBehaelter = $Slot->getOvercapacityBehaelter();
$intAmount += $intOvercapacityBehaelter;
}
if (!empty($_REQUEST['unit']) && intval($_REQUEST['unit']) > 0)
{
if (($Site = $Slot->getRelated('pid')) === null || ($Unit = WeinanlieferungUnitsModel::findByPk($_REQUEST['unit'])) === null)
{
return new Response('Could not load unit data', 500);
}
$intDefault = floor($intDefault / max(1, $Unit->containers));
$intAmount = floor($intAmount / max(1, $Unit->containers));
}
$strOutput = "\n";
return new Response($strOutput);
}
protected function renderAvailableBookingUnitAmount(): Response
{
if (empty($_REQUEST['id']))
{
return new Response('Required parameter missing',412);
}
if (($Reservation = WeinanlieferungReservationModel::findByPk($_REQUEST['id'])) === null || ($Slot = $Reservation->getRelated('pid')) === null)
{
return new Response('Could not load slot data',500);
}
$intDefault = max(0,$Slot->getAvailableBehaelter())+$Reservation->behaelter;
$intAmount = $intDefault;
if ($intDefault > 0)
{
$intOvercapacityBehaelter = $Slot->getOvercapacityBehaelter();
$intAmount += $intOvercapacityBehaelter;
}
if (!empty($_REQUEST['unit']) && intval($_REQUEST['unit']) > 0)
{
if (($Site = $Slot->getRelated('pid')) === null || ($Unit = WeinanlieferungUnitsModel::findByPk($_REQUEST['unit'])) === null)
{
return new Response('Could not load unit data', 500);
}
$intDefault = floor($intDefault / max(1, $Unit->containers));
$intAmount = floor($intAmount / max(1, $Unit->containers));
}
$strOutput = "\n";
return new Response($strOutput);
}
}