'loadFormModel', 'confirmDeletionWorkCenter' => 'loadFormModelForDeletion', ]; /** * Definición de tipos de datos que se deben castear. * * @var array */ protected $casts = [ // 'status' => 'boolean', ]; /** * Devuelve el modelo relacionado con el formulario. * * @return string */ protected function model(): string { return StoreWorkCenter::class; } /** * Define los campos del formulario. * * @return array */ protected function fields(): array { return (new StoreWorkCenter())->getFillable(); } /** * Valores por defecto para el formulario. * * @return array */ protected function defaults(): array { return [ 'status' => true, ]; } /** * Campo que se debe enfocar cuando se abra el formulario. * * @return string */ protected function focusOnOpen(): string { return 'code'; } /** * Define reglas de validación dinámicas basadas en el modo actual. * * @param string $mode El modo actual del formulario ('create', 'edit', 'delete'). * @return array */ protected function dynamicRules(string $mode): array { switch ($mode) { case 'create': case 'edit': return [ 'store_id' => ['required', 'integer', 'exists:stores,id'], 'code' => [ 'required', 'string', 'max:16', 'regex:/^[a-zA-Z0-9_-]+$/', // Solo alfanuméricos, guiones y guiones bajos Rule::unique('store_work_centers', 'code')->ignore($this->id), ], 'name' => [ 'required', 'string', 'max:96', 'regex:/^[a-zA-ZáéíóúÁÉÍÓÚñÑ0-9\s-]+$/', // Solo letras, números y espacios Rule::unique('store_work_centers') ->where(fn ($query) => $query->where('store_id', $this->store_id)) ->ignore($this->id), ], 'description' => ['nullable', 'string', 'max:1024'], 'manager_id' => ['nullable', 'integer', 'exists:users,id'], 'tel' => ['nullable', 'regex:/^\+?[0-9()\s-]+$/', 'max:20'], // Permitir formatos internacionales 'tel2' => ['nullable', 'regex:/^\+?[0-9()\s-]+$/', 'max:20'], 'lat' => ['nullable', 'numeric', 'between:-90,90'], 'lng' => ['nullable', 'numeric', 'between:-180,180'], 'status' => ['nullable', 'boolean'] ]; case 'delete': return [ 'confirmDeletion' => 'accepted', // Confirma que el usuario acepta eliminar ]; default: return []; } } // ===================== VALIDACIONES ===================== /** * Get custom attributes for validator errors. * * @return array */ protected function attributes(): array { return [ 'store_id' => 'negocio', 'code' => 'código del centro de trabajo', 'name' => 'nombre del centro de trabajo', 'tel' => 'teléfono', 'tel2' => 'teléfono alternativo', 'lat' => 'latitud', 'lng' => 'longitud', 'status' => 'estado', ]; } /** * Get the error messages for the defined validation rules. * * @return array */ protected function messages(): array { return [ 'store_id.required' => 'El centro de trabajo debe estar asociado a un negocio.', 'code.required' => 'El código del centro de trabajo es obligatorio.', 'code.unique' => 'Este código ya está en uso por otro centro de trabajo.', 'name.required' => 'El nombre del centro de trabajo es obligatorio.', 'name.unique' => 'Ya existe un centro de trabajo con este nombre en este negocio.', 'name.regex' => 'El nombre solo puede contener letras, números, espacios y guiones.', ]; } /** * Define las opciones de los selectores desplegables. * * @return array */ protected function options(): array { $storeCatalogService = app(StoreCatalogService::class); $contactCatalogService = app(ContactCatalogService::class); return [ 'store_options' => $storeCatalogService->searchCatalog('stores', '', ['limit' => -1]), 'manager_options' => $contactCatalogService->searchCatalog('users', '', ['limit' => -1]), ]; } /** * Ruta de la vista asociada con este formulario. * * @return string */ protected function viewPath(): string { return 'vuexy-store-manager::livewire.work-center.form-offcanvas'; } }