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
eac923968d
commit
63c36555a5
24 changed files with 1607 additions and 92 deletions
102
app/Http/Controllers/Admin/OrderWithdrawalController.php
Normal file
102
app/Http/Controllers/Admin/OrderWithdrawalController.php
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\OrderWithdrawal;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class OrderWithdrawalController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('admin');
|
||||
}
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.withdrawal.index');
|
||||
}
|
||||
|
||||
public function detail(int $id): View
|
||||
{
|
||||
$withdrawal = OrderWithdrawal::with('shopping_order.shopping_user', 'user_shop')->findOrFail($id);
|
||||
|
||||
return view('admin.withdrawal.detail', [
|
||||
'withdrawal' => $withdrawal,
|
||||
'statuses' => OrderWithdrawal::statuses(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(Request $request, int $id): RedirectResponse
|
||||
{
|
||||
$withdrawal = OrderWithdrawal::findOrFail($id);
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'status' => ['required', 'in:'.implode(',', OrderWithdrawal::statuses())],
|
||||
'admin_note' => ['nullable', 'string', 'max:5000'],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return back()->withErrors($validator)->withInput();
|
||||
}
|
||||
|
||||
$withdrawal->update([
|
||||
'status' => $request->input('status'),
|
||||
'admin_note' => $request->input('admin_note'),
|
||||
]);
|
||||
|
||||
\Session()->flash('alert-success', __('Gespeichert!'));
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function datatable()
|
||||
{
|
||||
$query = OrderWithdrawal::query()->select('order_withdrawals.*');
|
||||
|
||||
return \DataTables::eloquent($query)
|
||||
->addColumn('id', function (OrderWithdrawal $w): string {
|
||||
return '<a href="'.route('admin_withdrawals_detail', [$w->id]).'" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-eye"></span></a> '.$w->id;
|
||||
})
|
||||
->addColumn('declared_at', function (OrderWithdrawal $w): string {
|
||||
return $w->declared_at ? $w->declared_at->format('d.m.Y H:i') : '';
|
||||
})
|
||||
->addColumn('order_reference', function (OrderWithdrawal $w): string {
|
||||
return '#'.e($w->order_reference);
|
||||
})
|
||||
->addColumn('customer', function (OrderWithdrawal $w): string {
|
||||
return e($w->customer_name).'<br><small>'.e($w->customer_email).'</small>';
|
||||
})
|
||||
->addColumn('type', function (OrderWithdrawal $w): string {
|
||||
$label = $w->isFullWithdrawal() ? __('withdrawal.scope_full') : __('withdrawal.scope_partial');
|
||||
$color = $w->isFullWithdrawal() ? 'dark' : 'info';
|
||||
|
||||
return '<span class="badge badge-pill badge-'.$color.'">'.e($label).'</span>';
|
||||
})
|
||||
->addColumn('status', function (OrderWithdrawal $w): string {
|
||||
$colors = [
|
||||
OrderWithdrawal::STATUS_RECEIVED => 'warning',
|
||||
OrderWithdrawal::STATUS_PROCESSING => 'info',
|
||||
OrderWithdrawal::STATUS_DONE => 'success',
|
||||
OrderWithdrawal::STATUS_REJECTED => 'danger',
|
||||
];
|
||||
$color = $colors[$w->status] ?? 'default';
|
||||
|
||||
return '<span class="badge badge-pill badge-'.$color.'">'.e($w->status).'</span>';
|
||||
})
|
||||
->addColumn('action', function (OrderWithdrawal $w): string {
|
||||
return '<a href="'.route('admin_withdrawals_detail', [$w->id]).'" class="btn btn-sm btn-primary"><i class="fa fa-eye"></i></a>';
|
||||
})
|
||||
->filterColumn('customer', function ($query, $keyword): void {
|
||||
$query->where('customer_email', 'LIKE', '%'.$keyword.'%')
|
||||
->orWhere('customer_name', 'LIKE', '%'.$keyword.'%');
|
||||
})
|
||||
->orderColumn('declared_at', 'declared_at $1')
|
||||
->rawColumns(['id', 'customer', 'type', 'status', 'action'])
|
||||
->make(true);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue