first commit

This commit is contained in:
2025-03-05 20:44:45 -06:00
commit 06dbf8e2a7
74 changed files with 9681 additions and 0 deletions

19
Models/Currency.php Normal file
View File

@ -0,0 +1,19 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Currency extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = ['code', 'name', 'symbol', 'exchange_rate', 'status'];
protected $casts = [
'exchange_rate' => 'decimal:6',
'status' => 'boolean'
];
}

20
Models/FixedAsset.php Normal file
View File

@ -0,0 +1,20 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class FixedAsset extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = ['name', 'description', 'acquisition_date', 'value', 'status'];
protected $casts = [
'acquisition_date' => 'date',
'value' => 'decimal:2',
'status' => 'boolean'
];
}

View File

@ -0,0 +1,84 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Koneko\VuexyStoreManager\Models\Store;
use Koneko\VuexyAdmin\Models\User;
class InventoryMovement extends Model
{
use HasFactory;
protected $table = 'inventory_movements';
protected $primaryKey = 'id';
public $incrementing = false;
protected $keyType = 'integer';
protected $fillable = [
'product_id',
'store_id',
'warehouse_id',
'movement_type',
'quantity',
'cost',
'cost_before',
'cost_after',
'cost_type',
'notes',
'transactionable_id',
'transactionable_type',
'created_by',
];
protected $casts = [
'quantity' => 'decimal:6',
'cost' => 'decimal:2',
'cost_before' => 'decimal:2',
'cost_after' => 'decimal:2',
'cost_type' => 'string',
];
/**
* Relación con el producto.
*/
public function product(): BelongsTo
{
return $this->belongsTo(Product::class, 'product_id');
}
/**
* Relación con la sucursal.
*/
public function store(): BelongsTo
{
return $this->belongsTo(Store::class, 'store_id');
}
/**
* Relación con el almacén.
*/
public function warehouse(): BelongsTo
{
return $this->belongsTo(Warehouse::class, 'warehouse_id');
}
/**
* Relación con el usuario que creó el movimiento.
*/
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
/**
* Relación polimórfica para vincular diferentes transacciones.
*/
public function transactionable(): MorphTo
{
return $this->morphTo();
}
}

View File

@ -0,0 +1,62 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Koneko\VuexyStoreManager\Models\Store;
class InventoryStockLevel extends Model
{
protected $fillable = [
'product_id', 'store_id', 'warehouse_id', 'quantity',
'pos_stock', 'ecommerce_stock', 'purchase_reserved_stock', 'asset_stock',
'last_cost', 'average_cost', 'total_last_cost', 'total_average_cost', 'total_identified_cost',
'costing_method'
];
protected $casts = [
'quantity' => 'decimal:6',
'pos_stock' => 'decimal:6',
'ecommerce_stock' => 'decimal:6',
'purchase_reserved_stock' => 'decimal:6',
'asset_stock' => 'decimal:6',
'last_cost' => 'decimal:2',
'average_cost' => 'decimal:2',
'total_last_cost' => 'decimal:2',
'total_average_cost' => 'decimal:2',
'total_identified_cost' => 'decimal:2',
'costing_method' => 'integer',
];
/**
* Verificar que el stock en áreas no supere el stock total
*/
public static function boot()
{
parent::boot();
static::saving(function ($inventory) {
$totalReserved = $inventory->pos_stock + $inventory->ecommerce_stock + $inventory->purchase_reserved_stock + $inventory->asset_stock;
if ($totalReserved > $inventory->quantity) {
throw new \Exception("Error: El stock reservado no puede ser mayor al stock total.");
}
});
}
public function product()
{
return $this->belongsTo(Product::class, 'product_id');
}
public function store(): BelongsTo
{
return $this->belongsTo(Store::class, 'store_id');
}
public function warehouse()
{
return $this->belongsTo(Warehouse::class, 'warehouse_id');
}
}

62
Models/LotNumber.php Normal file
View File

@ -0,0 +1,62 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Koneko\VuexyStoreManager\Models\Store;
class LotNumber extends Model
{
use HasFactory;
protected $table = 'lot_numbers';
protected $primaryKey = 'id';
public $incrementing = false;
protected $keyType = 'mediumint';
protected $fillable = [
'product_id',
'store_id',
'warehouse_id',
'lot_number',
'production_date',
'expiry_date',
'initial_quantity',
'remaining_quantity',
'cost',
];
protected $casts = [
'production_date' => 'date',
'expiry_date' => 'date',
'initial_quantity' => 'decimal:6',
'remaining_quantity' => 'decimal:6',
'cost' => 'decimal:2',
];
/**
* Relación con el producto.
*/
public function product(): BelongsTo
{
return $this->belongsTo(Product::class, 'product_id');
}
/**
* Relación con la sucursal.
*/
public function store(): BelongsTo
{
return $this->belongsTo(Store::class, 'store_id');
}
/**
* Relación con el almacén.
*/
public function warehouse(): BelongsTo
{
return $this->belongsTo(Warehouse::class, 'warehouse_id');
}
}

134
Models/Product.php Normal file
View File

@ -0,0 +1,134 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Koneko\VuexyStoreManager\Models\Currency;
use Koneko\SatCatalogs\Models\ClaveUnidad;
use Koneko\SatCatalogs\Models\ClaveProdServ;
use Koneko\VuexyAdmin\Models\User;
class Product extends Model
{
use HasFactory;
protected $table = 'products';
protected $primaryKey = 'id';
public $incrementing = false;
protected $keyType = 'mediumint';
protected $fillable = [
'type',
'category_id',
'descripcion',
'descripcion_completa',
'no_identificacion',
'slug',
'available_in_pos',
'available_in_purchases',
'available_in_ecommerce',
'available_in_purchases',
'available_in_maanufacturing',
'available_in_quality',
'available_in_assets',
'c_clave_unidad',
'c_clave_prod_serv',
'ean_code',
'costo',
'c_moneda',
'c_objeto_imp',
'impuestos',
'traslados',
'retenciones',
'data_lot_enable',
'data_lot_require',
'data_series_enable',
'data_series_require',
'data_expiration_enable',
'data_expiration_require',
'data_warranty_enable',
'warranty',
'data_best_before_enable',
'data_best_before_require',
'data_observations_enable',
'minimum_unit',
'affects_inventory',
'alert_minimum_stock',
'alert_maximum_stock',
'minimum_stock',
'maximum_stock',
'status',
'created_by'
];
protected $casts = [
'available_in_pos',
'available_in_purchases' => 'boolean',
'available_in_ecommerce' => 'boolean',
'available_in_purchases' => 'boolean',
'available_in_maanufacturing' => 'boolean',
'available_in_quality' => 'boolean',
'available_in_assets' => 'boolean',
'costo' => 'decimal:2',
'traslados' => 'decimal:6',
'retenciones' => 'decimal:6',
'minimum_unit' => 'decimal:6',
'minimum_stock' => 'decimal:6',
'maximum_stock' => 'decimal:6',
'data_lot_enable' => 'boolean',
'data_lot_require' => 'boolean',
'data_series_enable' => 'boolean',
'data_series_require' => 'boolean',
'data_expiration_enable' => 'boolean',
'data_expiration_require' => 'boolean',
'data_warranty_enable' => 'boolean',
'data_best_before_enable' => 'boolean',
'data_best_before_require' => 'boolean',
'data_observations_enable' => 'boolean',
'affects_inventory' => 'boolean',
'alert_minimum_stock' => 'boolean',
'alert_maximum_stock' => 'boolean',
];
/**
* Relación con la categoría del producto.
*/
public function category(): BelongsTo
{
return $this->belongsTo(ProductCategory::class, 'category_id');
}
/**
* Relación con la moneda.
*/
public function currency(): BelongsTo
{
return $this->belongsTo(Currency::class, 'c_moneda', 'c_currency');
}
/**
* Relación con la clave unidad SAT.
*/
public function claveUnidad(): BelongsTo
{
return $this->belongsTo(ClaveUnidad::class, 'c_clave_unidad', 'c_clave_unidad');
}
/**
* Relación con la clave de producto/servicio SAT.
*/
public function claveProdServ(): BelongsTo
{
return $this->belongsTo(ClaveProdServ::class, 'c_clave_prod_serv', 'c_clave_prod_serv');
}
/**
* Relación con el usuario que creó el producto.
*/
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
}

View File

@ -0,0 +1,68 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ProductCategory extends Model
{
use HasFactory;
protected $table = 'product_categories';
protected $primaryKey = 'id';
public $incrementing = false;
protected $keyType = 'mediumint';
protected $fillable = [
'parent_id',
'parent_slug',
'name',
'slug',
'icon',
'description',
'show_in_pos',
'show_in_purchases',
'show_in_ecommerce',
'show_in_manufacturing',
'show_in_quality',
'show_in_assets',
'order'
];
protected $casts = [
'show_in_pos' => 'boolean',
'show_in_purchases' => 'boolean',
'show_in_ecommerce' => 'boolean',
'show_in_manufacturing' => 'boolean',
'show_in_quality' => 'boolean',
'show_in_assets' => 'boolean',
'order' => 'integer',
];
/**
* Relación con la categoría padre.
*/
public function parent(): BelongsTo
{
return $this->belongsTo(ProductCategory::class, 'parent_id');
}
/**
* Relación con categorías hijas.
*/
public function children(): HasMany
{
return $this->hasMany(ProductCategory::class, 'parent_id');
}
/**
* Relación con productos.
*/
public function products(): HasMany
{
return $this->hasMany(Product::class, 'category_id');
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class ProductProperty extends Model
{
use HasFactory;
protected $table = 'product_properties';
protected $primaryKey = 'id';
public $incrementing = false;
protected $keyType = 'smallint';
protected $fillable = [
'name',
];
/**
* Relación con los valores de propiedad asignados a productos.
*/
public function values(): HasMany
{
return $this->hasMany(ProductPropertyValue::class, 'property_id');
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ProductPropertyValue extends Model
{
use HasFactory;
protected $table = 'product_property';
protected $primaryKey = 'id';
public $incrementing = false;
protected $keyType = 'mediumint';
protected $fillable = [
'product_id',
'property_id',
'value',
];
/**
* Relación con el producto.
*/
public function product(): BelongsTo
{
return $this->belongsTo(Product::class, 'product_id');
}
/**
* Relación con la propiedad del producto.
*/
public function property(): BelongsTo
{
return $this->belongsTo(ProductProperty::class, 'property_id');
}
}

94
Models/Warehouse.php Normal file
View File

@ -0,0 +1,94 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Koneko\VuexyAdmin\Models\User;
use Koneko\VuexyStoreManager\Models\Store;
use Koneko\VuexyStoreManager\Models\StoreWorkCenter;
class Warehouse extends Model
{
use HasFactory;
protected $fillable = [
'store_id',
'work_center_id',
'code',
'name',
'description',
'manager_id',
'tel',
'tel2',
'priority',
'status',
];
protected $casts = [
'priority' => 'integer',
'status' => 'boolean',
];
/**
* Nombre de la etiqueta para generar Componentes
*
* @var string
*/
public $tagName = 'Warehouse';
/**
* Nombre de la columna que contiee el nombre del registro
*
* @var string
*/
public $columnNameLabel = 'name';
/**
* Nombre singular del registro.
*
* @var string
*/
public $singularName = 'almacén';
/**
* Nombre plural del registro.
*
* @var string
*/
public $pluralName = 'almacenes';
/**
* Relación con la sucursal a la que pertenece el almacén.
*/
public function store(): BelongsTo
{
return $this->belongsTo(Store::class, 'store_id');
}
/**
* Relación con el usuario que gestiona el centro de trabajo.
*/
public function manager(): BelongsTo
{
return $this->belongsTo(User::class, 'manager_id');
}
/**
* Relación con la sucursal a la que pertenece el almacén.
*/
public function workcenter(): BelongsTo
{
return $this->belongsTo(StoreWorkCenter::class, 'work_center_id');
}
/**
* Relación con los movimientos de inventario del almacén.
*/
public function movements(): HasMany
{
return $this->hasMany(WarehouseMovement::class, 'warehouse_id');
}
}

View File

@ -0,0 +1,80 @@
<?php
namespace Koneko\VuexyWarehouse\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Koneko\VuexyStoreManager\Models\Store;
use Koneko\VuexyAdmin\Models\User;
class WarehouseMovement extends Model
{
use HasFactory, SoftDeletes;
protected $table = 'warehouse_movements';
protected $primaryKey = 'id';
public $incrementing = false;
protected $keyType = 'mediumint';
protected $fillable = [
'store_id',
'warehouse_id',
'movement_type',
'movement_id',
'created_by',
'approved_by',
'adjusted_quantity',
'cost',
'notes',
'to_warehouse_id',
'status',
];
protected $casts = [
'adjusted_quantity' => 'decimal:6',
'cost' => 'decimal:2',
'status' => 'integer',
];
/**
* Relación con la sucursal donde ocurrió el movimiento.
*/
public function store(): BelongsTo
{
return $this->belongsTo(Store::class, 'store_id');
}
/**
* Relación con el almacén de origen del movimiento.
*/
public function warehouse(): BelongsTo
{
return $this->belongsTo(Warehouse::class, 'warehouse_id');
}
/**
* Relación con el almacén de destino (si aplica).
*/
public function toWarehouse(): BelongsTo
{
return $this->belongsTo(Warehouse::class, 'to_warehouse_id');
}
/**
* Relación con el usuario que creó el movimiento.
*/
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
/**
* Relación con el usuario que aprobó el movimiento (si aplica).
*/
public function approvedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'approved_by');
}
}