*/ public function rules(): array { return [ 'rows' => ['required', 'array', 'min:1', 'max:1000'], 'rows.*' => ['required', 'array:type,sector,row,max_seat,price'], 'rows.*.type' => ['required', 'string', 'max:100'], 'rows.*.sector' => ['required', 'string', 'max:100'], 'rows.*.row' => ['required', 'integer', 'between:1,5'], 'rows.*.max_seat' => ['required', 'integer', 'between:1,100'], 'rows.*.price' => ['required', 'numeric', 'min:0', 'max:99999999.99'], ]; } /** @return array */ public function after(): array { return [function (Validator $validator): void { $combinations = []; foreach ($this->input('rows', []) as $index => $row) { if (! is_array($row)) { continue; } $combination = collect(['type', 'sector', 'row']) ->map(fn (string $field): string => mb_strtolower(trim((string) ($row[$field] ?? '')))) ->implode('|'); if (isset($combinations[$combination])) { $validator->errors()->add( "rows.{$index}", 'La combinación de tipo, sector y fila no puede repetirse.', ); } $combinations[$combination] = true; } }]; } }