Widerruf: Gesetzliche Online-Widerrufsfunktion (Formular, Bestätigungsmail, Admin-Verwaltung)
- Öffentliches Widerrufsformular /widerruf mit Bestell-Lookup (throttled) - Bestätigungsmail an Kunde + Weiterleitung an bestellungen@ (config app.withdrawal_mail) - Admin-Übersicht/-Detail unter /admin/withdrawals inkl. Sidenav-Eintrag - Widerruf-Button in Portal-Bestellansicht und Footer-Links - Model OrderWithdrawal + Migration + Factory + Tests Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
9dc138e45b
commit
83ef5f1e52
24 changed files with 1607 additions and 92 deletions
|
|
@ -1,5 +1,12 @@
|
|||
<?php
|
||||
|
||||
use App\Domain\EarlyDomainParser;
|
||||
use App\Models\IqImage;
|
||||
use App\Models\ProductImage;
|
||||
use App\Models\UserShop;
|
||||
use App\Models\UserShopOnSite;
|
||||
use App\Services\LocaleGuard;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Geteilte Routen (Shared Routes)
|
||||
|
|
@ -12,7 +19,7 @@
|
|||
|
||||
// Rechtliche und Kontakt-Routen - Umleitung zur Shop-Domain für checkout.*
|
||||
// Verwendet EarlyDomainParser für domain-awareness
|
||||
if (\App\Domain\EarlyDomainParser::getCurrentDomainType() === 'checkout') {
|
||||
if (EarlyDomainParser::getCurrentDomainType() === 'checkout') {
|
||||
// Shop-Domain aus Config laden
|
||||
$shopHost = config('domains.domains.shop.host');
|
||||
$protocol = config('domains.protocol', 'https://');
|
||||
|
|
@ -63,7 +70,7 @@ Route::post('/change_website_lang', 'Web\SiteController@changeLang')->name('lang
|
|||
|
||||
// Route für den Sprachwechsel (aus alter utility.php wiederhergestellt)
|
||||
Route::get('translation/{locale}', function ($locale) {
|
||||
$normalized = \App\Services\LocaleGuard::normalize($locale);
|
||||
$normalized = LocaleGuard::normalize($locale);
|
||||
if ($normalized === null) {
|
||||
return redirect()->back();
|
||||
}
|
||||
|
|
@ -84,7 +91,7 @@ Route::get('translation/{locale}', function ($locale) {
|
|||
|
||||
// Bild-Routen (aus alter utility.php wiederhergestellt)
|
||||
Route::get('/product/image/{slug}', function ($slug = null) {
|
||||
if ($image = \App\Models\ProductImage::where('slug', 'like', $slug)->first()) {
|
||||
if ($image = ProductImage::where('slug', 'like', $slug)->first()) {
|
||||
$path = storage_path('app/public').'/images/product'.'/'.$image->product_id.'/'.$image->filename;
|
||||
if (file_exists($path)) {
|
||||
return response()->file($path);
|
||||
|
|
@ -95,7 +102,7 @@ Route::get('/product/image/{slug}', function ($slug = null) {
|
|||
|
||||
Route::get('storage/images/{from}/{slug}', function ($from = null, $slug = null) {
|
||||
if ($from == 'shop') {
|
||||
if ($image = \App\Models\UserShop::where('filename', $slug)->first()) {
|
||||
if ($image = UserShop::where('filename', $slug)->first()) {
|
||||
$path = storage_path('app/public').'/images/shop'.'/'.$image->filename;
|
||||
if (file_exists($path)) {
|
||||
return Response::file($path);
|
||||
|
|
@ -105,7 +112,7 @@ Route::get('storage/images/{from}/{slug}', function ($from = null, $slug = null)
|
|||
})->name('storage_images');
|
||||
|
||||
Route::get('/iq/image/{slug}', function ($slug = null) {
|
||||
if ($image = \App\Models\IqImage::where('slug', $slug)->first()) {
|
||||
if ($image = IqImage::where('slug', $slug)->first()) {
|
||||
$path = storage_path('app/public').'/images/iq_images/'.$image->filename;
|
||||
if (file_exists($path)) {
|
||||
return Response::file($path);
|
||||
|
|
@ -114,7 +121,7 @@ Route::get('/iq/image/{slug}', function ($slug = null) {
|
|||
})->name('iq_image');
|
||||
|
||||
Route::get('/user_shop/image/{slug}', function ($slug = null) {
|
||||
if ($image = \App\Models\UserShopOnSite::where('slug', $slug)->first()) {
|
||||
if ($image = UserShopOnSite::where('slug', $slug)->first()) {
|
||||
$path = storage_path('app/public').'/images/user_shop'.'/'.$image->user_shop_id.'/'.$image->filename;
|
||||
if (file_exists($path)) {
|
||||
return Response::file($path);
|
||||
|
|
@ -123,7 +130,7 @@ Route::get('/user_shop/image/{slug}', function ($slug = null) {
|
|||
})->name('user_shop_image');
|
||||
|
||||
Route::get('/shop/product/image/{slug}', function ($slug = null) {
|
||||
if ($image = \App\Models\ProductImage::where('slug', $slug)->first()) {
|
||||
if ($image = ProductImage::where('slug', $slug)->first()) {
|
||||
$path = storage_path('app/public').'/images/product'.'/'.$image->product_id.'/'.$image->filename;
|
||||
if (file_exists($path)) {
|
||||
return Response::file($path);
|
||||
|
|
@ -134,7 +141,7 @@ Route::get('/shop/product/image/{slug}', function ($slug = null) {
|
|||
// Alias für /home, damit auch /home erreichbar ist
|
||||
|
||||
// Checkout-Weiterleitung nur für Domains, die NICHT checkout.* sind
|
||||
if (\App\Domain\EarlyDomainParser::getCurrentDomainType() !== 'checkout') {
|
||||
if (EarlyDomainParser::getCurrentDomainType() !== 'checkout') {
|
||||
// Checkout-Domain aus Config laden
|
||||
$checkoutHost = config('domains.domains.checkout.host');
|
||||
$protocol = config('domains.protocol', 'https://');
|
||||
|
|
@ -169,3 +176,12 @@ if (\App\Domain\EarlyDomainParser::getCurrentDomainType() !== 'checkout') {
|
|||
}
|
||||
|
||||
Route::get('/register/verify/{confirmationCode}', 'HomeController@verify')->name('register_verify');
|
||||
|
||||
// Gesetzliche Online-Widerrufsfunktion (Widerrufs-Button-Pflicht ab 19.06.2026)
|
||||
Route::get('/widerruf', 'Web\WithdrawalController@create')->name('withdrawal.create');
|
||||
Route::post('/widerruf/pruefen', 'Web\WithdrawalController@lookup')
|
||||
->middleware('throttle:20,1')
|
||||
->name('withdrawal.lookup');
|
||||
Route::post('/widerruf/absenden', 'Web\WithdrawalController@store')
|
||||
->middleware('throttle:10,1')
|
||||
->name('withdrawal.store');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue