Newsletter-Listen: Empfaengerlisten filtern, speichern und exportieren
Admin-Bereich "Newsletter-Listen" (Plan dev/_tickets/entwicklungsplan- newsletter-listen.md): Berater und Kunden nach Filtern zusammenstellen, als Liste speichern und wieder laden, Export als XLSX/CSV. Jeder Export wird protokolliert (newsletter_list_exports). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ef7e333bd4
commit
d21d94a060
26 changed files with 3664 additions and 0 deletions
75
app/Http/Requests/Newsletter/NewsletterListFilterRequest.php
Normal file
75
app/Http/Requests/Newsletter/NewsletterListFilterRequest.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Newsletter;
|
||||
|
||||
use App\Services\Newsletter\NewsletterListFilter;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class NewsletterListFilterRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return (bool) $this->user()?->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, mixed>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'source' => ['nullable', Rule::in(NewsletterListFilter::sources())],
|
||||
'language' => ['nullable', 'string', 'max:2'],
|
||||
'country_ids' => ['nullable', 'array'],
|
||||
'country_ids.*' => ['integer'],
|
||||
'optin' => ['nullable', Rule::in(NewsletterListFilter::optinOptions())],
|
||||
'purchase' => ['nullable', Rule::in(NewsletterListFilter::purchaseOptions())],
|
||||
'member_id' => ['nullable', 'regex:/^(none|\d+)$/'],
|
||||
'created_from' => ['nullable', 'date'],
|
||||
'created_to' => ['nullable', 'date', 'after_or_equal:created_from'],
|
||||
'company' => ['nullable', Rule::in(NewsletterListFilter::companyOptions())],
|
||||
'consultant_status' => ['nullable', Rule::in(NewsletterListFilter::consultantStatusOptions())],
|
||||
'level_ids' => ['nullable', 'array'],
|
||||
'level_ids.*' => ['integer'],
|
||||
'include_admins' => ['nullable', 'boolean'],
|
||||
'template_only' => ['nullable', 'boolean'],
|
||||
'refresh' => ['nullable', 'boolean'],
|
||||
'list_id' => ['nullable', 'integer', 'exists:newsletter_lists,id'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'source.in' => __('newsletter.validation.source'),
|
||||
'optin.in' => __('newsletter.validation.option'),
|
||||
'purchase.in' => __('newsletter.validation.option'),
|
||||
'company.in' => __('newsletter.validation.option'),
|
||||
'consultant_status.in' => __('newsletter.validation.option'),
|
||||
'member_id.regex' => __('newsletter.validation.member'),
|
||||
'created_from.date' => __('newsletter.validation.date'),
|
||||
'created_to.date' => __('newsletter.validation.date'),
|
||||
'created_to.after_or_equal' => __('newsletter.validation.date_range'),
|
||||
'country_ids.*.integer' => __('newsletter.validation.option'),
|
||||
'level_ids.*.integer' => __('newsletter.validation.option'),
|
||||
'list_id.exists' => __('newsletter.validation.list'),
|
||||
'list_id.integer' => __('newsletter.validation.list'),
|
||||
];
|
||||
}
|
||||
|
||||
public function toFilter(): NewsletterListFilter
|
||||
{
|
||||
return NewsletterListFilter::fromArray($this->validated());
|
||||
}
|
||||
|
||||
public function listId(): ?int
|
||||
{
|
||||
$id = $this->validated('list_id');
|
||||
|
||||
return $id === null || $id === '' ? null : (int) $id;
|
||||
}
|
||||
}
|
||||
35
app/Http/Requests/Newsletter/StoreNewsletterListRequest.php
Normal file
35
app/Http/Requests/Newsletter/StoreNewsletterListRequest.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Newsletter;
|
||||
|
||||
/**
|
||||
* Speichern einer Filterkombination unter einem Namen. Erbt die Filter-Regeln.
|
||||
*/
|
||||
class StoreNewsletterListRequest extends NewsletterListFilterRequest
|
||||
{
|
||||
/**
|
||||
* @return array<string, array<int, mixed>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return parent::rules() + [
|
||||
'name' => ['required', 'string', 'max:120'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return parent::messages() + [
|
||||
'name.required' => __('newsletter.validation.name'),
|
||||
'name.max' => __('newsletter.validation.name'),
|
||||
];
|
||||
}
|
||||
|
||||
public function listName(): string
|
||||
{
|
||||
return trim((string) $this->validated('name'));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue