Manage bookings in the W&K-Sync backend group instead of at the event
Bookings get their own backend module (W&K-Sync → Anmeldungen) with a sortable, filterable list; the operation on calendar events is removed and the calendar module no longer exposes tl_wk_booking. Inbox edit links point to the new module. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
142afa6e52
commit
efce662b4f
10 files changed
+25
-63
No files matched your search
@@ -67,7 +67,7 @@ vendor/bin/contao-console contao:migrate
|
||||
|
||||
5. **Benachrichtigungen** (Notification Center 2): Benachrichtigungen vom Typ **W&K-Anmeldung** anlegen und im Kalender zuordnen. Tokens: `##recipient_email##`, `##subscription_*##` (alle Felder der Anmeldung, Auswahlfelder zusätzlich als `##subscription_gender_label##` usw., Ja/Nein-Felder als `##subscription_vegetarian_label##`), `##event_*##` (alle Felder der Veranstaltung, Datumsfelder formatiert), `##event_datetime##`, `##event_link##`, `##event_categories##`, `##event_speakers##`, `##subscription_event_wk_id##`, `##subscription_confirmation_page_url##`, `##calendar_*##`, `##admin_email##`. Die bisherigen Token-Namen `event_organizerCity` und `event_internalEventNumber` bleiben erhalten.
|
||||
|
||||
6. **Benutzergruppen**: Zugriff auf die Module „W&K-Sync“ (Import & Posteingang, Kategorien, Kontaktanfragen, Protokoll) und auf den Kalender (Anmeldungen je Veranstaltung) freigeben.
|
||||
6. **Benutzergruppen**: Zugriff auf die Module „W&K-Sync“ (Import & Posteingang, Anmeldungen, Kontaktanfragen, Kategorien, Protokoll) freigeben. Anmeldungen werden ausschließlich dort bearbeitet, nicht am Event im Kalender.
|
||||
|
||||
---
|
||||
|
||||
@@ -139,7 +139,7 @@ Die Bestätigungsseite wird mit `?booking=<Token>` aufgerufen. Formulare des For
|
||||
|
||||
## Posteingang und Export
|
||||
|
||||
**W&K-Sync → Import & Posteingang → Posteingang.** Neue Anmeldungen und Kontaktanfragen werden gesichtet und einzeln oder gesammelt verschoben. Doppelte Anmeldungen (gleiche E-Mail-Adresse, gleiche Veranstaltung) werden markiert. „Bearbeiten“ öffnet den Datensatz (Anmeldungen unter Kalender → Veranstaltung → Anmeldungen, Anfragen unter W&K-Sync → Kontaktanfragen).
|
||||
**W&K-Sync → Import & Posteingang → Posteingang.** Neue Anmeldungen und Kontaktanfragen werden gesichtet und einzeln oder gesammelt verschoben. Doppelte Anmeldungen (gleiche E-Mail-Adresse, gleiche Veranstaltung) werden markiert. „Bearbeiten“ öffnet den Datensatz unter W&K-Sync → Anmeldungen bzw. W&K-Sync → Kontaktanfragen; dort lassen sich alle Angaben korrigieren (Liste mit Filter nach Veranstaltung und Ordner, Suche nach Name/E-Mail). Beim Löschen einer Veranstaltung werden ihre Anmeldungen mitgelöscht.
|
||||
|
||||
**Export**: In der Download-Liste erzeugt „Download-Liste für W&K exportieren“ die Datei `JJJJ-MM-TT_website_kontaktanfragen_wk.csv` mit den Spalten `KBNR;KNKDAN;KNKDTITEL;KNKDN2;KNKDN1;KNKDSTR;KNKDPLZ;KNKDORT;KNGEBDAT;KDEMAIL;KDTEL1;KDFREI01;KDFREI02;KDFREI03;KDFREI04;KNUKAT;KNVEG;schoolName;schoolCity`. Kontaktanfragen stehen ohne Kursnummer in der Datei. Die Datensätze werden als „Exportiert“ markiert, die freien Plätze der Veranstaltungen um die Zahl der Anmeldungen reduziert (bis zum nächsten W&K-Import), und die Datei bleibt unter „Exporte für W&K“ zum erneuten Download.
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ ArrayUtil::arrayInsert($GLOBALS['BE_MOD'], 1, [
|
||||
'callback' => WkSyncModule::class,
|
||||
'stylesheet' => 'bundles/contaowksync/wk-sync-backend.css',
|
||||
],
|
||||
'wk_sync_bookings' => [
|
||||
'tables' => ['tl_wk_booking'],
|
||||
],
|
||||
'wk_sync_categories' => [
|
||||
'tables' => ['tl_wk_category'],
|
||||
],
|
||||
@@ -23,6 +26,3 @@ ArrayUtil::arrayInsert($GLOBALS['BE_MOD'], 1, [
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
// Anmeldungen werden als Untertabelle der Veranstaltungen im Kalender-Modul verwaltet
|
||||
$GLOBALS['BE_MOD']['content']['calendar']['tables'][] = 'tl_wk_booking';
|
||||
@@ -7,13 +7,9 @@ use Mummert\ContaoWkSyncBundle\Import\WkState;
|
||||
|
||||
$dca = &$GLOBALS['TL_DCA']['tl_calendar_events'];
|
||||
|
||||
// Anmeldungen werden mit der Veranstaltung gelöscht, aber nicht am Event bearbeitet (dafür: W&K-Sync → Anmeldungen)
|
||||
$dca['config']['ctable'][] = 'tl_wk_booking';
|
||||
|
||||
$dca['list']['operations']['wk_bookings'] = [
|
||||
'href' => 'table=tl_wk_booking',
|
||||
'icon' => 'mgroup.svg',
|
||||
];
|
||||
|
||||
$manipulator = PaletteManipulator::create()
|
||||
->addLegend('wk_legend', 'title_legend', PaletteManipulator::POSITION_AFTER)
|
||||
->addLegend('wk_content_legend', 'wk_legend', PaletteManipulator::POSITION_AFTER)
|
||||
|
||||
@@ -26,11 +26,14 @@ $GLOBALS['TL_DCA']['tl_wk_booking'] = [
|
||||
],
|
||||
'list' => [
|
||||
'sorting' => [
|
||||
'mode' => DataContainer::MODE_PARENT,
|
||||
'mode' => DataContainer::MODE_SORTABLE,
|
||||
'fields' => ['dateCreated DESC'],
|
||||
'headerFields' => ['title', 'wkId', 'startDate', 'endDate', 'wkPlacesLeft'],
|
||||
'panelLayout' => 'filter;search,limit',
|
||||
'disableGrouping' => true,
|
||||
'panelLayout' => 'filter;sort,search,limit',
|
||||
'defaultSearchField' => 'lastname',
|
||||
],
|
||||
'label' => [
|
||||
'fields' => ['dateCreated', 'lastname', 'firstname', 'email', 'pid', 'state'],
|
||||
'showColumns' => true,
|
||||
],
|
||||
'global_operations' => [
|
||||
'all',
|
||||
@@ -43,7 +46,7 @@ $GLOBALS['TL_DCA']['tl_wk_booking'] = [
|
||||
],
|
||||
'palettes' => [
|
||||
'__selector__' => ['addDifferentInvoiceAddress', 'addNotes', 'teacherPosition'],
|
||||
'default' => '{state_legend},state,dateCreated,notification;'
|
||||
'default' => '{state_legend},pid,state,dateCreated,notification;'
|
||||
.'{person_legend},gender,academicTitle,firstname,lastname,street,postal,city,email,phone,position,birthday;'
|
||||
.'{school_legend},teacherPosition;'
|
||||
.'{stay_legend},vegetarian,overnightStay;'
|
||||
@@ -62,7 +65,11 @@ $GLOBALS['TL_DCA']['tl_wk_booking'] = [
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'autoincrement' => true],
|
||||
],
|
||||
'pid' => [
|
||||
'filter' => true,
|
||||
'sorting' => true,
|
||||
'inputType' => 'select',
|
||||
'foreignKey' => 'tl_calendar_events.title',
|
||||
'eval' => ['mandatory' => true, 'includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'belongsTo', 'load' => 'lazy'],
|
||||
],
|
||||
@@ -119,6 +126,7 @@ $GLOBALS['TL_DCA']['tl_wk_booking'] = [
|
||||
],
|
||||
'lastname' => [
|
||||
'search' => true,
|
||||
'sorting' => true,
|
||||
'inputType' => 'text',
|
||||
'eval' => ['mandatory' => true, 'maxlength' => 128, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'string', 'length' => 128, 'default' => ''],
|
||||
@@ -143,6 +151,7 @@ $GLOBALS['TL_DCA']['tl_wk_booking'] = [
|
||||
],
|
||||
'email' => [
|
||||
'search' => true,
|
||||
'sorting' => true,
|
||||
'inputType' => 'text',
|
||||
'eval' => ['mandatory' => true, 'rgxp' => 'email', 'maxlength' => 255, 'decodeEntities' => true, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
|
||||
|
||||
@@ -11,3 +11,4 @@ $GLOBALS['TL_LANG']['MOD']['wk_sync_log'] = ['Protokoll', 'Protokoll der Importe
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_sync'] = 'W&K-Sync';
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_booking_form'] = ['W&K-Anmeldeformular', 'Anmeldeformular zur Veranstaltung aus der URL (Alias der Veranstaltung).'];
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_booking_status'] = ['W&K-Anmeldestatus', 'Freie Plätze, Anmeldeschluss und Link zur Anmeldung für die Veranstaltung aus der URL.'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_bookings'] = ['Anmeldungen', 'Anmeldungen zu Veranstaltungen ansehen und bearbeiten'];
|
||||
@@ -12,6 +12,7 @@ $lang['invoice_legend'] = 'Rechnungsanschrift';
|
||||
$lang['notes_legend'] = 'Nachricht';
|
||||
$lang['consent_legend'] = 'Einwilligungen';
|
||||
|
||||
$lang['pid'] = ['Veranstaltung', 'Veranstaltung, zu der die Anmeldung gehört.'];
|
||||
$lang['state'] = ['Ordner', 'Bearbeitungsstand im Posteingang. „Exportiert“ wird nur durch den Export gesetzt.'];
|
||||
$lang['dateCreated'] = ['Eingegangen am', ''];
|
||||
$lang['notification'] = ['Verschickte Benachrichtigung', 'ID der Benachrichtigung, die bei der Anmeldung verschickt wurde (0 = keine).'];
|
||||
|
||||
@@ -11,3 +11,4 @@ $GLOBALS['TL_LANG']['MOD']['wk_sync_log'] = ['Log', 'Log of imports and exports'
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_sync'] = 'W&K sync';
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_booking_form'] = ['W&K booking form', 'Booking form for the event given in the URL.'];
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_booking_status'] = ['W&K booking status', 'Free places, deadline and booking link for the event given in the URL.'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_bookings'] = ['Bookings', 'View and edit bookings'];
|
||||
@@ -12,6 +12,7 @@ $lang['invoice_legend'] = 'Rechnungsanschrift';
|
||||
$lang['notes_legend'] = 'Nachricht';
|
||||
$lang['consent_legend'] = 'Einwilligungen';
|
||||
|
||||
$lang['pid'] = ['Veranstaltung', 'Veranstaltung, zu der die Anmeldung gehört.'];
|
||||
$lang['state'] = ['Ordner', 'Bearbeitungsstand im Posteingang. „Exportiert“ wird nur durch den Export gesetzt.'];
|
||||
$lang['dateCreated'] = ['Eingegangen am', ''];
|
||||
$lang['notification'] = ['Verschickte Benachrichtigung', 'ID der Benachrichtigung, die bei der Anmeldung verschickt wurde (0 = keine).'];
|
||||
|
||||
@@ -410,7 +410,7 @@ class WkSyncBackend
|
||||
private function editUrl(InboxItem $item, string $referer): string
|
||||
{
|
||||
$params = $item->isBooking()
|
||||
? ['do' => 'calendar', 'table' => 'tl_wk_booking', 'act' => 'edit', 'id' => $item->id]
|
||||
? ['do' => 'wk_sync_bookings', 'table' => 'tl_wk_booking', 'act' => 'edit', 'id' => $item->id]
|
||||
: ['do' => 'wk_sync_inquiries', 'table' => 'tl_wk_inquiry', 'act' => 'edit', 'id' => $item->id];
|
||||
|
||||
if ('' !== $referer) {
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mummert\ContaoWkSyncBundle\EventListener\DataContainer;
|
||||
|
||||
use Contao\CoreBundle\DependencyInjection\Attribute\AsCallback;
|
||||
use Contao\CoreBundle\Framework\ContaoFramework;
|
||||
use Contao\Config;
|
||||
use Contao\Date;
|
||||
use Contao\StringUtil;
|
||||
use Mummert\ContaoWkSyncBundle\Inbox\InboxState;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* Zeile in der Anmeldeliste unterhalb einer Veranstaltung.
|
||||
*/
|
||||
#[AsCallback(table: 'tl_wk_booking', target: 'list.sorting.child_record')]
|
||||
class BookingLabelListener
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ContaoFramework $framework,
|
||||
private readonly TranslatorInterface $translator,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $row
|
||||
*/
|
||||
public function __invoke(array $row): string
|
||||
{
|
||||
$config = $this->framework->getAdapter(Config::class);
|
||||
$date = $this->framework->getAdapter(Date::class)->parse((string) $config->get('datimFormat'), (int) $row['dateCreated']);
|
||||
$state = InboxState::tryFrom((string) $row['state']) ?? InboxState::New;
|
||||
$stateLabel = $this->translator->trans('MSC.wk_sync.state.'.$state->translationKey(), [], 'contao_default');
|
||||
|
||||
$name = trim(($row['academicTitle'] ? $row['academicTitle'].' ' : '').$row['firstname'].' '.$row['lastname']);
|
||||
|
||||
return \sprintf(
|
||||
'<div class="tl_content_left">%s <span class="wk-sync-muted" style="color:#999;padding-left:3px">[%s]</span> <span style="color:#999;padding-left:3px">[%s]</span> <span style="color:#999;padding-left:3px">[%s]</span></div>',
|
||||
StringUtil::specialchars($name),
|
||||
StringUtil::specialchars((string) $row['email']),
|
||||
StringUtil::specialchars($date),
|
||||
StringUtil::specialchars($stateLabel),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user