first commit
This commit is contained in:
221
Livewire/Warehouses/WarehouseIndex.php
Normal file
221
Livewire/Warehouses/WarehouseIndex.php
Normal file
@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
namespace Koneko\VuexyWarehouse\Livewire\Warehouses;
|
||||
|
||||
use Koneko\VuexyAdmin\Livewire\Table\AbstractIndexComponent;
|
||||
use Koneko\VuexyWarehouse\Models\Warehouse;
|
||||
use Koneko\VuexyStoreManager\Services\StoreCatalogService;
|
||||
|
||||
class WarehouseIndex extends AbstractIndexComponent
|
||||
{
|
||||
public $store_id;
|
||||
public $storeOptions = [];
|
||||
|
||||
/**
|
||||
* Retorna la clase del modelo asociado.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function model(): string
|
||||
{
|
||||
return Warehouse::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configura el encabezado (header) de la tabla (las columnas).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function columns(): array
|
||||
{
|
||||
return [
|
||||
'action' => 'Acciones',
|
||||
'store_code' => 'Código de Tienda',
|
||||
'store_name' => 'Nombre de la Tienda',
|
||||
'work_center_code' => 'Código del Centro de Trabajo',
|
||||
'work_center_name' => 'Nombre del Centro de Trabajo',
|
||||
'code' => 'Código de Almacén',
|
||||
'name' => 'Nombre del Almacén',
|
||||
'description' => 'Descripción',
|
||||
'manager_name' => 'Encargado',
|
||||
'pais' => 'País',
|
||||
'estado' => 'Estado',
|
||||
'localidad' => 'Localidad',
|
||||
'municipio' => 'Municipio',
|
||||
'codigo_postal' => 'Código Postal',
|
||||
'colonia' => 'Colonia',
|
||||
'direccion' => 'Dirección',
|
||||
'tel' => 'Teléfono',
|
||||
'tel2' => 'Teléfono Alternativo',
|
||||
'priority' => 'Prioridad',
|
||||
'status' => 'Estatus',
|
||||
'created_at' => 'Fecha de Creación',
|
||||
'updated_at' => 'Última Actualización',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Define los formatos de cada columna (se inyectará en $bt_datatable['format']).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function format(): array
|
||||
{
|
||||
return [
|
||||
'action' => [
|
||||
'formatter' => 'warehouseActionFormatter',
|
||||
'onlyFormatter' => true,
|
||||
],
|
||||
'store_code' => [
|
||||
'formatter' => [
|
||||
'name' => 'dynamicBadgeFormatter',
|
||||
'params' => ['color' => 'secondary']
|
||||
],
|
||||
'align' => 'center',
|
||||
'visible' => false,
|
||||
],
|
||||
'work_center_code' => [
|
||||
'formatter' => [
|
||||
'name' => 'dynamicBadgeFormatter',
|
||||
'params' => ['color' => 'secondary']
|
||||
],
|
||||
'align' => 'center',
|
||||
'visible' => false,
|
||||
],
|
||||
'work_center_name' => [
|
||||
'visible' => false,
|
||||
],
|
||||
'code' => [
|
||||
'formatter' => [
|
||||
'name' => 'dynamicBadgeFormatter',
|
||||
'params' => ['color' => 'secondary'],
|
||||
],
|
||||
'align' => 'center',
|
||||
'switchable' => false,
|
||||
],
|
||||
'name' => [
|
||||
'switchable' => false,
|
||||
],
|
||||
'description' => [
|
||||
'visible' => false,
|
||||
],
|
||||
'manager_name' => [
|
||||
'formatter' => 'managerFormatter',
|
||||
],
|
||||
'tel' => [
|
||||
'formatter' => 'telFormatter',
|
||||
'align' => 'center',
|
||||
],
|
||||
'tel2' => [
|
||||
'formatter' => 'telFormatter',
|
||||
'align' => 'center',
|
||||
'visible' => false,
|
||||
],
|
||||
'pais' => [
|
||||
'align' => 'center',
|
||||
'visible' => false,
|
||||
],
|
||||
'estado' => [
|
||||
'formatter' => 'textNowrapFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
'localidad' => [
|
||||
'formatter' => 'textNowrapFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
'municipio' => [
|
||||
'formatter' => 'textNowrapFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
'codigo_postal' => [
|
||||
'align' => 'center',
|
||||
'visible' => false,
|
||||
],
|
||||
'colonia' => [
|
||||
'formatter' => 'textNowrapFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
'direccion' => [
|
||||
'formatter' => 'direccionFormatter',
|
||||
'visible' => false,
|
||||
],
|
||||
'priority' => [
|
||||
'formatter' => 'numberFormatter',
|
||||
'align' => 'center',
|
||||
],
|
||||
'status' => [
|
||||
'formatter' => [
|
||||
'name' => 'dynamicBooleanFormatter',
|
||||
'params' => ['tag' => 'activo']
|
||||
],
|
||||
'align' => 'center',
|
||||
],
|
||||
'created_at' => [
|
||||
'formatter' => 'textNowrapFormatter',
|
||||
'align' => 'center',
|
||||
'visible' => false,
|
||||
],
|
||||
'updated_at' => [
|
||||
'formatter' => 'textNowrapFormatter',
|
||||
'align' => 'center',
|
||||
'visible' => false,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retorna la configuración base (común) para la tabla Bootstrap Table.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function bootstraptableConfig(): array
|
||||
{
|
||||
return [
|
||||
'sortName' => 'code',
|
||||
'exportFileName' => 'Almacenes',
|
||||
'showFullscreen' => false,
|
||||
'showPaginationSwitch' => false,
|
||||
'showRefresh' => false,
|
||||
'pagination' => false,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retorna la ruta de la vista Blade.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function viewPath(): string
|
||||
{
|
||||
// La vista que ya tienes creada para WarehouseIndex
|
||||
return 'vuexy-warehouse::livewire.warehouses.index';
|
||||
}
|
||||
|
||||
/**
|
||||
* Métodos que necesites sobreescribir o extender.
|
||||
*/
|
||||
public function mount(): void
|
||||
{
|
||||
parent::mount();
|
||||
|
||||
// Cargar opciones de tienda, por ejemplo:
|
||||
$storeCatalogService = app(StoreCatalogService::class);
|
||||
$this->storeOptions = $storeCatalogService->searchCatalog('stores', '', ['limit' => -1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puedes agregar lógica de filtrado específica para warehouses,
|
||||
* si lo requieres, sobrescribiendo el método applyFilters del padre.
|
||||
*/
|
||||
protected function applyFilters($criteria = [])
|
||||
{
|
||||
$query = parent::applyFilters($criteria);
|
||||
|
||||
// Ejemplo de aplicar filtro por store_id
|
||||
if ($this->store_id) {
|
||||
$query->where('store_id', $this->store_id);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
219
Livewire/Warehouses/WarehouseOffcanvasForm.php
Normal file
219
Livewire/Warehouses/WarehouseOffcanvasForm.php
Normal file
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
namespace Koneko\VuexyWarehouse\Livewire\Warehouses;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Koneko\VuexyAdmin\Livewire\Form\AbstractFormOffCanvasComponent;
|
||||
use Koneko\VuexyContacts\Services\ContactCatalogService;
|
||||
use Koneko\VuexyStoreManager\Services\StoreCatalogService;
|
||||
use Koneko\VuexyWarehouse\Models\Warehouse;
|
||||
|
||||
/**
|
||||
* Class WarehouseOffcanvasForm
|
||||
*
|
||||
* Componente Livewire para gestionar almacenes.
|
||||
* Extiende la clase AbstractFormOffCanvasComponent e implementa validaciones dinámicas,
|
||||
* manejo de formularios, eventos y actualizaciones en tiempo real.
|
||||
*
|
||||
* @package Koneko\VuexyWarehouse\Livewire\Warehouses
|
||||
*/
|
||||
class WarehouseOffcanvasForm extends AbstractFormOffCanvasComponent
|
||||
{
|
||||
/**
|
||||
* Propiedades del formulario relacionadas con el almacén.
|
||||
*/
|
||||
public $id, $store_id, $work_center_id, $code, $name, $description,
|
||||
$manager_id, $tel, $tel2, $priority, $status, $confirmDeletion;
|
||||
|
||||
/**
|
||||
* Listas de opciones para selects en el formulario.
|
||||
*/
|
||||
public $store_options = [],
|
||||
$work_center_options = [],
|
||||
$manager_options = [];
|
||||
|
||||
/**
|
||||
* Eventos de escucha de Livewire.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $listeners = [
|
||||
'editWarehouse' => 'loadFormModel',
|
||||
'confirmDeletionWarehouse' => 'loadFormModelForDeletion',
|
||||
];
|
||||
|
||||
/**
|
||||
* Definición de tipos de datos que se deben castear.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'status' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Define el modelo Eloquent asociado con el formulario.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function model(): string
|
||||
{
|
||||
return Warehouse::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define los campos del formulario.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
protected function fields(): array
|
||||
{
|
||||
return (new Warehouse())->getFillable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Valores por defecto para el formulario.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function defaults(): array
|
||||
{
|
||||
return [
|
||||
'priority' => 0,
|
||||
'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'],
|
||||
'work_center_id' => ['nullable', 'integer', 'exists:store_work_centers,id'],
|
||||
'code' => ['required', 'string', 'max:16', Rule::unique('warehouses', 'code')->ignore($this->id)],
|
||||
'name' => ['required', 'string', 'max:96'],
|
||||
'description' => ['nullable', 'string', 'max:1024'],
|
||||
'manager_id' => ['nullable', 'integer', 'exists:users,id'],
|
||||
'tel' => ['nullable', 'regex:/^[0-9+\-\s]+$/', 'max:20'],
|
||||
'tel2' => ['nullable', 'regex:/^[0-9+\-\s]+$/', 'max:20'],
|
||||
'priority' => ['nullable', 'numeric', 'between:0,99'],
|
||||
'status' => ['nullable', 'boolean'],
|
||||
];
|
||||
|
||||
case 'delete':
|
||||
return [
|
||||
'confirmDeletion' => 'accepted', // Asegura que el usuario confirme la eliminación
|
||||
];
|
||||
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// ===================== VALIDACIONES =====================
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function attributes(): array
|
||||
{
|
||||
return [
|
||||
'code' => 'código de almacén',
|
||||
'name' => 'nombre del almacén',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error messages for the defined validation rules.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function messages(): array
|
||||
{
|
||||
return [
|
||||
'store_id.required' => 'El almacén debe estar asociado a un negocio.',
|
||||
'code.required' => 'El código del almacén es obligatorio.',
|
||||
'code.unique' => 'Este código ya está en uso por otro almacén.',
|
||||
'name.required' => 'El nombre del almacén es obligatorio.',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Carga el formulario con datos del almacén y actualiza las opciones dinámicas.
|
||||
*
|
||||
* @param int $id
|
||||
*/
|
||||
public function loadFormModel($id): void
|
||||
{
|
||||
parent::loadFormModel($id);
|
||||
|
||||
$this->work_center_options = $this->store_id
|
||||
? DB::table('store_work_centers')
|
||||
->where('store_id', $this->store_id)
|
||||
->pluck('name', 'id')
|
||||
->toArray()
|
||||
: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Carga el formulario para eliminar un almacén, actualizando las opciones necesarias.
|
||||
*
|
||||
* @param int $id
|
||||
*/
|
||||
public function loadFormModelForDeletion($id): void
|
||||
{
|
||||
parent::loadFormModelForDeletion($id);
|
||||
|
||||
$this->work_center_options = DB::table('store_work_centers')
|
||||
->where('store_id', $this->store_id)
|
||||
->pluck('name', 'id')
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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-warehouse::livewire.warehouses.form-offcanvas';
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user