route('id'); $isPercent = $this->input('type') === Coupon::TYPE_PERCENT; return [ 'code' => ['required', 'string', 'max:50', 'regex:/^[A-Za-z0-9_-]+$/', Rule::unique('coupons', 'code')->ignore($id)], 'name' => 'nullable|string|max:150', 'type' => ['required', Rule::in(Coupon::TYPES)], 'value' => ['required', 'integer', 'min:1', $isPercent ? 'max:99' : 'max:1000000000'], 'max_discount' => 'nullable|integer|min:1', 'min_order' => 'nullable|integer|min:0', 'applies_to' => ['required', Rule::in(Coupon::APPLIES_TO)], 'product_types' => 'nullable|array', 'product_types.*' => ['string', Rule::in(array_column(ProductTypeEnums::cases(), 'value'))], 'product_ids' => 'nullable|array', 'product_ids.*' => ['integer', Rule::exists('products', 'id')], 'billing_cycles' => 'nullable|array', 'billing_cycles.*' => ['string', Rule::in([...BillingCycleCatalog::codes(), 'onetime'])], 'usage_limit' => 'nullable|integer|min:1', 'per_customer_limit' => 'nullable|integer|min:1', 'starts_at' => 'nullable|date', 'ends_at' => 'nullable|date|after_or_equal:starts_at', 'is_active' => 'boolean', ]; } public function messages(): array { return [ 'code.unique' => 'Mã giảm giá đã tồn tại.', 'code.regex' => 'Mã chỉ gồm chữ, số, gạch ngang và gạch dưới.', 'value.max' => 'Giảm theo % tối đa 99.', ]; } public function attributes(): array { return ['ends_at' => 'ngày kết thúc']; } }