203 lines
6.2 KiB
PHP
203 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace Koneko\VuexyStoreManager\Livewire\Workcenters;
|
|
|
|
use Illuminate\Validation\Rule;
|
|
use Koneko\VuexyAdmin\Livewire\Form\AbstractFormOffCanvasComponent;
|
|
use Koneko\VuexyContacts\Services\ContactCatalogService;
|
|
use Koneko\VuexyStoreManager\Models\StoreWorkCenter;
|
|
use Koneko\VuexyStoreManager\Services\StoreCatalogService;
|
|
|
|
/**
|
|
* Class WorkCenterOffcanvasForm
|
|
*
|
|
* Componente Livewire para gestionar centros de trabajo.
|
|
* Extiende las funcionalidades generales de AbstractFormOffCanvasComponent.
|
|
*
|
|
* @package Koneko\VuexyStoreManager\Livewire\Workcenters
|
|
*/
|
|
class WorkCenterOffcanvasForm extends AbstractFormOffCanvasComponent
|
|
{
|
|
/**
|
|
* Campos específicos del centro de trabajo.
|
|
*/
|
|
public $store_id, $code, $name, $description, $manager_id, $tel, $tel2, $lat, $lng, $status;
|
|
|
|
/**
|
|
* Listas de opciones para selects en el formulario.
|
|
*/
|
|
public $store_options = [],
|
|
$manager_options = [];
|
|
|
|
/**
|
|
* Eventos de escucha de Livewire.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $listeners = [
|
|
'editWorkCenter' => '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<string, mixed>
|
|
*/
|
|
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<string, string>
|
|
*/
|
|
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<string, string>
|
|
*/
|
|
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';
|
|
}
|
|
}
|