Files
website/website/app/Http/Requests/StoreCouponRequest.php
Claude Dev d9ec414264 Add coupon management, customer services, and update TASKS.md
Phase 5 (Admin Panel):
- Admin coupon management: full CRUD with create/edit/deactivate,
  auto-generate codes, plan restrictions multi-select, usage tracking,
  redemption history on edit page
- Add active flag migration for coupons table

Phase 4 (Customer Dashboard):
- Customer services list page with plan info and status
- Customer service detail page with network info, plan details,
  control panel links (VirtFusion/SynergyCP/Enhance), important dates
- Service status/type resolver utilities

Documentation:
- Update TASKS.md with all completed Phase 3/4/5/8 items

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 10:38:12 -05:00

52 lines
1.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class StoreCouponRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/** @return array<string, array<int, mixed>> */
public function rules(): array
{
$uniqueCodeRule = Rule::unique('coupons', 'code');
if ($this->route('coupon')) {
$uniqueCodeRule->ignore($this->route('coupon'));
}
return [
'code' => ['required', 'string', 'max:50', $uniqueCodeRule],
'type' => ['required', Rule::in(['percentage', 'fixed'])],
'value' => ['required', 'numeric', 'min:0.01'],
'max_uses' => ['nullable', 'integer', 'min:1'],
'expires_at' => ['nullable', 'date', 'after:now'],
'applies_to' => ['nullable', 'array'],
'applies_to.*' => ['integer', 'exists:plans,id'],
];
}
/** @return array<string, string> */
public function messages(): array
{
return [
'code.required' => 'Coupon code is required.',
'code.unique' => 'This coupon code is already in use.',
'type.required' => 'Discount type is required.',
'type.in' => 'Discount type must be percentage or fixed.',
'value.required' => 'Discount value is required.',
'value.min' => 'Discount value must be at least 0.01.',
'expires_at.after' => 'Expiry date must be in the future.',
'applies_to.*.exists' => 'One or more selected plans do not exist.',
];
}
}