Direct payments for invoices
Events can be moved to archive and moved back Fixed validation
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Event\Actions\ArchiveEvent;
|
||||
|
||||
class ArchiveEventCommand {
|
||||
public ArchiveEventRequest $request;
|
||||
|
||||
public function __construct(ArchiveEventRequest $request) {
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function execute(): ArchiveEventResponse {
|
||||
$response = new ArchiveEventResponse();
|
||||
|
||||
$this->request->event->archived = true;
|
||||
$this->request->event->save();
|
||||
|
||||
$response->success = true;
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Event\Actions\ArchiveEvent;
|
||||
|
||||
use App\Models\Event;
|
||||
|
||||
class ArchiveEventRequest {
|
||||
public Event $event;
|
||||
|
||||
public function __construct(Event $event) {
|
||||
$this->event = $event;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Event\Actions\ArchiveEvent;
|
||||
|
||||
class ArchiveEventResponse {
|
||||
public bool $success;
|
||||
|
||||
public function __construct() {
|
||||
$this->success = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Event\Actions\UnarchiveEvent;
|
||||
|
||||
class UnarchiveEventCommand {
|
||||
public UnarchiveEventRequest $request;
|
||||
|
||||
public function __construct(UnarchiveEventRequest $request) {
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function execute(): UnarchiveEventResponse {
|
||||
$response = new UnarchiveEventResponse();
|
||||
|
||||
$this->request->event->archived = false;
|
||||
$this->request->event->save();
|
||||
|
||||
$response->success = true;
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Event\Actions\UnarchiveEvent;
|
||||
|
||||
use App\Models\Event;
|
||||
|
||||
class UnarchiveEventRequest {
|
||||
public Event $event;
|
||||
|
||||
public function __construct(Event $event) {
|
||||
$this->event = $event;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Event\Actions\UnarchiveEvent;
|
||||
|
||||
class UnarchiveEventResponse {
|
||||
public bool $success;
|
||||
|
||||
public function __construct() {
|
||||
$this->success = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Event\Controllers;
|
||||
|
||||
use App\Providers\InertiaProvider;
|
||||
use App\Scopes\CommonController;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Response;
|
||||
|
||||
class ArchivedEventsController extends CommonController
|
||||
{
|
||||
public function __invoke(Request $request): Response {
|
||||
$events = [];
|
||||
foreach ($this->events->getEventsByCriteria(['archived' => true]) as $event) {
|
||||
$events[] = [
|
||||
'id' => $event->id,
|
||||
'name' => $event->name,
|
||||
'location' => $event->location,
|
||||
'postalCode' => $event->postal_code,
|
||||
'eventBegin' => $event->start_date->format('d.m.Y'),
|
||||
'eventEnd' => $event->end_date->format('d.m.Y'),
|
||||
];
|
||||
}
|
||||
|
||||
return (new InertiaProvider('Event/ArchivedEvents', ['events' => $events]))->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Event\Controllers;
|
||||
|
||||
use App\Domains\Event\Actions\ArchiveEvent\ArchiveEventCommand;
|
||||
use App\Domains\Event\Actions\ArchiveEvent\ArchiveEventRequest;
|
||||
use App\Scopes\CommonController;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EventArchiveController extends CommonController
|
||||
{
|
||||
public function __invoke(string $eventId, Request $request): JsonResponse {
|
||||
$event = $this->events->getByIdentifier($eventId);
|
||||
|
||||
$archiveEventRequest = new ArchiveEventRequest($event);
|
||||
$archiveEventCommand = new ArchiveEventCommand($archiveEventRequest);
|
||||
$response = $archiveEventCommand->execute();
|
||||
|
||||
return response()->json([
|
||||
'status' => $response->success ? 'success' : 'error',
|
||||
'message' => $response->success ? 'Das Event wurde erfolgreich archiviert.' : 'Beim Archivieren des Events ist ein Fehler aufgetreten.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Event\Controllers;
|
||||
|
||||
use App\Domains\Event\Actions\UnarchiveEvent\UnarchiveEventCommand;
|
||||
use App\Domains\Event\Actions\UnarchiveEvent\UnarchiveEventRequest;
|
||||
use App\Scopes\CommonController;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EventUnarchiveController extends CommonController
|
||||
{
|
||||
public function __invoke(int $eventId, Request $request): JsonResponse {
|
||||
$event = $this->events->getById($eventId);
|
||||
|
||||
$unarchiveRequest = new UnarchiveEventRequest($event);
|
||||
$unarchiveCommand = new UnarchiveEventCommand($unarchiveRequest);
|
||||
$response = $unarchiveCommand->execute();
|
||||
|
||||
return response()->json(['status' => $response->success ? 'success' : 'error']);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
use App\Domains\Event\Controllers\CreateController;
|
||||
use App\Domains\Event\Controllers\DetailsController;
|
||||
use App\Domains\Event\Controllers\EventArchiveController;
|
||||
use App\Domains\Event\Controllers\EventUnarchiveController;
|
||||
use App\Domains\Event\Controllers\MailCompose\ByGroupController;
|
||||
use App\Domains\Event\Controllers\MailCompose\SendController;
|
||||
use App\Domains\Event\Controllers\ParticipantController;
|
||||
@@ -26,6 +28,7 @@ Route::prefix('api/v1')
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::post('/create', [CreateController::class, 'doCreate']);
|
||||
|
||||
|
||||
Route::prefix('{eventIdentifier}/mailing')->group(function () {
|
||||
Route::post('/compose/to-group/{groupType}', ByGroupController::class);
|
||||
Route::post('/send', SendController::class);
|
||||
@@ -37,8 +40,8 @@ Route::prefix('api/v1')
|
||||
Route::get('/summary', [DetailsController::class, 'summary']);
|
||||
|
||||
Route::get('/participants/{listType}', [DetailsController::class, 'listParticipants']);
|
||||
|
||||
|
||||
Route::post('/unarchive', EventUnarchiveController::class);
|
||||
Route::get('/archive', EventArchiveController::class);
|
||||
Route::post('/event-managers', [DetailsController::class, 'updateEventManagers']);
|
||||
Route::post('/participation-fees', [DetailsController::class, 'updateParticipationFees']);
|
||||
Route::post('/common-settings', [DetailsController::class, 'updateCommonSettings']);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Domains\Event\Controllers\ArchivedEventsController;
|
||||
use App\Domains\Event\Controllers\AvailableEventsController;
|
||||
use App\Domains\Event\Controllers\CreateController;
|
||||
use App\Domains\Event\Controllers\DetailsController;
|
||||
@@ -24,5 +25,6 @@ Route::middleware(IdentifyTenant::class)->group(function () {
|
||||
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::get('/create-event', CreateController::class);
|
||||
Route::get('/archived-events', ArchivedEventsController::class);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import AppLayout from "../../../../resources/js/layouts/AppLayout.vue";
|
||||
import ShadowedBox from "../../../Views/Components/ShadowedBox.vue";
|
||||
import { toast } from 'vue3-toastify';
|
||||
import axios from 'axios';
|
||||
|
||||
const props = defineProps({
|
||||
events: Array,
|
||||
});
|
||||
|
||||
const events = ref([...props.events]);
|
||||
|
||||
async function unarchiveEvent(eventId) {
|
||||
try {
|
||||
const response = await axios.post(`/api/v1/event/details/${eventId}/unarchive`);
|
||||
if (response.data.status === 'success') {
|
||||
events.value = events.value.filter(e => e.id !== eventId);
|
||||
toast.success('Veranstaltung wurde aus dem Archiv geholt.');
|
||||
} else {
|
||||
toast.error('Fehler beim Wiederherstellen der Veranstaltung.');
|
||||
}
|
||||
} catch {
|
||||
toast.error('Ein unerwarteter Fehler ist aufgetreten.');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout title="Archivierte Veranstaltungen">
|
||||
<div style="width: 95%; margin: 20px auto;">
|
||||
<h1 style="font-size: 1.5rem; font-weight: 700; margin-bottom: 20px;">Archivierte Veranstaltungen</h1>
|
||||
|
||||
<div
|
||||
v-if="events.length === 0"
|
||||
style="text-align: center; color: #6b7280; padding: 40px 0;"
|
||||
>
|
||||
Es sind keine archivierten Veranstaltungen vorhanden.
|
||||
</div>
|
||||
|
||||
<ShadowedBox
|
||||
v-for="event in events"
|
||||
:key="event.id"
|
||||
style="padding: 20px; margin-bottom: 16px;"
|
||||
>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px;">
|
||||
<div>
|
||||
<h2 style="margin: 0 0 4px 0; font-size: 1.1rem; font-weight: 600;">{{ event.name }}</h2>
|
||||
<span style="color: #6b7280; font-size: 0.875rem;">
|
||||
{{ event.postalCode }} {{ event.location }}
|
||||
·
|
||||
{{ event.eventBegin }} – {{ event.eventEnd }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<button
|
||||
@click="unarchiveEvent(event.id)"
|
||||
style="
|
||||
padding: 8px 20px;
|
||||
background-color: #f59e0b;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
"
|
||||
>
|
||||
Aus dem Archiv holen
|
||||
</button>
|
||||
</div>
|
||||
</ShadowedBox>
|
||||
</div>
|
||||
</AppLayout>
|
||||
</template>
|
||||
@@ -56,6 +56,16 @@
|
||||
mailCompose.value = true
|
||||
}
|
||||
|
||||
async function archiveEvent() {
|
||||
const response = await fetch("/api/v1/event/details/" + props.data.event.identifier + "/archive" );
|
||||
const data = await response.json();
|
||||
if (data.status === 'success') {
|
||||
toast.success(data.message)
|
||||
} else {
|
||||
toast.error(data.message)
|
||||
}
|
||||
}
|
||||
|
||||
async function sendPaymentReminder() {
|
||||
toast.info("Die Nachrichten werden gesendet. Bitte verlasse diese Seite nicht.");
|
||||
const response = await fetch("/api/v1/event/" + props.data.event.identifier + "/send-payment-reminder/" );
|
||||
@@ -150,6 +160,7 @@
|
||||
<label style="font-size: 9pt;" class="link" @click="showEventManagement">Veranstaltungsleitung</label>
|
||||
<label style="font-size: 9pt;" class="link" @click="showParticipationFees">Teilnahmegebühren</label>
|
||||
<a style="font-size: 9pt;" class="link" :href="'/cost-unit/' + props.data.event.costUnit.id">Ausgabenübersicht</a>
|
||||
<a v-if="!dynamicProps.event.registrationAllowed && !dynamicProps.event.archived" style="color: #ff0000; font-size: 9pt;" class="link" @click="archiveEvent">Archivieren</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user