feat: actualizar validaciones de SKU y código de barras en solicitudes de bundles y categorías, y ajustar cálculo de impuestos en el servicio de bundles

This commit is contained in:
Juan Felipe Zapata Moreno 2026-03-04 10:13:15 -06:00
parent 3d5198a65a
commit ec33cf2c0e
8 changed files with 24 additions and 10 deletions

View File

@ -6,6 +6,7 @@
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Inventory; use App\Models\Inventory;
use App\Models\InventorySerial; use App\Models\InventorySerial;
use App\Models\Warehouse;
use App\Services\InventoryMovementService; use App\Services\InventoryMovementService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Notsoweb\ApiResponse\Enums\ApiResponse; use Notsoweb\ApiResponse\Enums\ApiResponse;
@ -31,6 +32,11 @@ public function index(Inventory $inventario, Request $request)
if ($request->has('warehouse_id')) { if ($request->has('warehouse_id')) {
$query->where('warehouse_id', $request->warehouse_id); $query->where('warehouse_id', $request->warehouse_id);
} else {
$mainWarehouse = Warehouse::where('is_main', true)->first();
if ($mainWarehouse) {
$query->where('warehouse_id', $mainWarehouse->id);
}
} }
if ($request->has('q')) { if ($request->has('q')) {

View File

@ -22,7 +22,7 @@ public function rules(): array
return [ return [
'name' => ['required', 'string', 'max:255'], 'name' => ['required', 'string', 'max:255'],
'sku' => ['required', 'string', 'max:50', 'unique:bundles,sku'], 'sku' => ['required', 'string', 'max:50', 'unique:bundles,sku'],
'barcode' => ['nullable', 'string', 'max:50'], 'barcode' => ['nullable', 'string', 'unique:bundles,barcode'],
// Componentes del kit (mínimo 2 productos) // Componentes del kit (mínimo 2 productos)
'items' => ['required', 'array', 'min:2'], 'items' => ['required', 'array', 'min:2'],

View File

@ -24,7 +24,7 @@ public function rules(): array
return [ return [
'name' => ['nullable', 'string', 'max:255'], 'name' => ['nullable', 'string', 'max:255'],
'sku' => ['nullable', 'string', 'max:50', 'unique:bundles,sku,' . $bundleId], 'sku' => ['nullable', 'string', 'max:50', 'unique:bundles,sku,' . $bundleId],
'barcode' => ['nullable', 'string', 'max:50'], 'barcode' => ['nullable', 'string', 'unique:bundles,barcode,' . $bundleId],
// Componentes del kit (opcional en update) // Componentes del kit (opcional en update)
'items' => ['nullable', 'array', 'min:2'], 'items' => ['nullable', 'array', 'min:2'],

View File

@ -1,6 +1,7 @@
<?php namespace App\Http\Requests\App; <?php namespace App\Http\Requests\App;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class CategoryStoreRequest extends FormRequest class CategoryStoreRequest extends FormRequest
{ {
@ -19,7 +20,7 @@ public function authorize(): bool
public function rules(): array public function rules(): array
{ {
return [ return [
'name' => ['required', 'string', 'max:100'], 'name' => ['required', 'string', 'max:100', Rule::unique('categories', 'name')->withoutTrashed()],
'description' => ['nullable', 'string', 'max:225'], 'description' => ['nullable', 'string', 'max:225'],
'is_active' => ['nullable', 'boolean'], 'is_active' => ['nullable', 'boolean'],
]; ];

View File

@ -1,6 +1,7 @@
<?php namespace App\Http\Requests\App; <?php namespace App\Http\Requests\App;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class CategoryUpdateRequest extends FormRequest class CategoryUpdateRequest extends FormRequest
{ {
@ -19,7 +20,7 @@ public function authorize(): bool
public function rules(): array public function rules(): array
{ {
return [ return [
'name' => ['nullable', 'string', 'max:100'], 'name' => ['nullable', 'string', 'max:100', Rule::unique('categories', 'name')->ignore($this->route('categoria'))->withoutTrashed()],
'description' => ['nullable', 'string', 'max:225'], 'description' => ['nullable', 'string', 'max:225'],
'is_active' => ['nullable', 'boolean'], 'is_active' => ['nullable', 'boolean'],
]; ];

View File

@ -1,6 +1,7 @@
<?php namespace App\Http\Requests\App; <?php namespace App\Http\Requests\App;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class SubcategoryStoreRequest extends FormRequest class SubcategoryStoreRequest extends FormRequest
{ {
@ -11,15 +12,19 @@ public function authorize(): bool
public function rules(): array public function rules(): array
{ {
$uniqueRule = Rule::unique('subcategories', 'name')
->where('category_id', $this->route('category')->id)
->withoutTrashed();
if($this->isBulk()) { if($this->isBulk()) {
return [ return [
'*.name' => ['required', 'string', 'max:100'], '*.name' => ['required', 'string', 'max:100', $uniqueRule],
'*.description' => ['nullable', 'string', 'max:255'], '*.description' => ['nullable', 'string', 'max:255'],
'*.is_active' => ['nullable', 'boolean'], '*.is_active' => ['nullable', 'boolean'],
]; ];
} }
return [ return [
'name' => ['required', 'string', 'max:100'], 'name' => ['required', 'string', 'max:100', $uniqueRule],
'description' => ['nullable', 'string', 'max:255'], 'description' => ['nullable', 'string', 'max:255'],
'is_active' => ['nullable', 'boolean'], 'is_active' => ['nullable', 'boolean'],
]; ];

View File

@ -1,6 +1,7 @@
<?php namespace App\Http\Requests\App; <?php namespace App\Http\Requests\App;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class SubcategoryUpdateRequest extends FormRequest class SubcategoryUpdateRequest extends FormRequest
{ {
@ -12,7 +13,7 @@ public function authorize(): bool
public function rules(): array public function rules(): array
{ {
return [ return [
'name' => ['nullable', 'string', 'max:100'], 'name' => ['nullable', 'string', 'max:100', Rule::unique('subcategories', 'name')->where('category_id', $this->route('category')->id)->ignore($this->route('subcategory'))->withoutTrashed()],
'description' => ['nullable', 'string', 'max:255'], 'description' => ['nullable', 'string', 'max:255'],
'is_active' => ['nullable', 'boolean'], 'is_active' => ['nullable', 'boolean'],
]; ];

View File

@ -44,7 +44,7 @@ public function createBundle(array $data): Bundle
// Permitir override de precio (para promociones) // Permitir override de precio (para promociones)
$finalRetailPrice = $data['retail_price'] ?? $totalRetailPrice; $finalRetailPrice = $data['retail_price'] ?? $totalRetailPrice;
$tax = $data['tax'] ?? ($finalRetailPrice * 0.16); // 16% por defecto $tax = $data['tax'] ?? 16.00;
BundlePrice::create([ BundlePrice::create([
'bundle_id' => $bundle->id, 'bundle_id' => $bundle->id,
@ -99,7 +99,7 @@ public function updateBundle(Bundle $bundle, array $data): Bundle
} }
$finalRetailPrice = $data['retail_price'] ?? $totalRetailPrice; $finalRetailPrice = $data['retail_price'] ?? $totalRetailPrice;
$tax = $data['tax'] ?? ($finalRetailPrice * 0.16); $tax = $data['tax'] ?? 16.00;
$bundle->price->update([ $bundle->price->update([
'cost' => $totalCost, 'cost' => $totalCost,
@ -110,7 +110,7 @@ public function updateBundle(Bundle $bundle, array $data): Bundle
// Solo actualizar precio sin recalcular componentes // Solo actualizar precio sin recalcular componentes
$bundle->price->update([ $bundle->price->update([
'retail_price' => $data['retail_price'], 'retail_price' => $data['retail_price'],
'tax' => $data['tax'] ?? ($data['retail_price'] * 0.16), 'tax' => $data['tax'] ?? 16.00,
]); ]);
} }