fix: actualizar respuestas de API para ventas con datos de facturación y ajustar seriales en inventarios
This commit is contained in:
parent
810aff1b0e
commit
c1473cdb95
@ -32,7 +32,7 @@ public function show(string $invoiceNumber)
|
|||||||
|
|
||||||
// Si ya tiene datos de facturación
|
// Si ya tiene datos de facturación
|
||||||
if ($sale->client_id) {
|
if ($sale->client_id) {
|
||||||
return ApiResponse::INTERNAL_ERROR->response([
|
return ApiResponse::NO_CONTENT->response([
|
||||||
'message' => 'Esta venta ya tiene datos de facturación registrados',
|
'message' => 'Esta venta ya tiene datos de facturación registrados',
|
||||||
'client' => $sale->client,
|
'client' => $sale->client,
|
||||||
'sale' => $this->formatSaleData($sale)
|
'sale' => $this->formatSaleData($sale)
|
||||||
@ -60,7 +60,7 @@ public function store(Request $request, string $invoiceNumber)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($sale->client_id) {
|
if ($sale->client_id) {
|
||||||
return ApiResponse::BAD_REQUEST->response([
|
return ApiResponse::NO_CONTENT->response([
|
||||||
'message' => 'Esta venta ya tiene datos de facturación registrados'
|
'message' => 'Esta venta ya tiene datos de facturación registrados'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,7 +130,8 @@ public function downloadTemplate()
|
|||||||
'stock',
|
'stock',
|
||||||
'costo',
|
'costo',
|
||||||
'precio_venta',
|
'precio_venta',
|
||||||
'impuesto'
|
'impuesto',
|
||||||
|
'numeros_serie'
|
||||||
];
|
];
|
||||||
|
|
||||||
$exampleData = [
|
$exampleData = [
|
||||||
@ -149,10 +150,11 @@ public function downloadTemplate()
|
|||||||
'sku' => 'COCA-600',
|
'sku' => 'COCA-600',
|
||||||
'codigo_barras' => '750227686666',
|
'codigo_barras' => '750227686666',
|
||||||
'categoria' => 'Bebidas',
|
'categoria' => 'Bebidas',
|
||||||
'stock' => 100,
|
'stock' => 5,
|
||||||
'costo' => 12.50,
|
'costo' => 12.50,
|
||||||
'precio_venta' => 18.00,
|
'precio_venta' => 18.00,
|
||||||
'impuesto' => 8
|
'impuesto' => 8,
|
||||||
|
'numeros_serie' => '' // Dejar vacío si el producto no maneja seriales individuales
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'nombre' => 'Laptop HP Pavilion 15',
|
'nombre' => 'Laptop HP Pavilion 15',
|
||||||
@ -162,7 +164,8 @@ public function downloadTemplate()
|
|||||||
'stock' => 5,
|
'stock' => 5,
|
||||||
'costo' => 8500.00,
|
'costo' => 8500.00,
|
||||||
'precio_venta' => 12000.00,
|
'precio_venta' => 12000.00,
|
||||||
'impuesto' => 16
|
'impuesto' => 16,
|
||||||
|
'numeros_serie' => 'HP-LAP-15-01,HP-LAP-15-02,HP-LAP-15-03,HP-LAP-15-04,HP-LAP-15-05'
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@ -20,9 +20,9 @@ class InventorySerialController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Listar seriales de un producto
|
* Listar seriales de un producto
|
||||||
*/
|
*/
|
||||||
public function index(Inventory $inventory, Request $request)
|
public function index(Inventory $inventario, Request $request)
|
||||||
{
|
{
|
||||||
$query = $inventory->serials();
|
$query = $inventario->serials();
|
||||||
|
|
||||||
if ($request->has('status')) {
|
if ($request->has('status')) {
|
||||||
$query->where('status', $request->status);
|
$query->where('status', $request->status);
|
||||||
@ -32,22 +32,22 @@ public function index(Inventory $inventory, Request $request)
|
|||||||
$query->where('serial_number', 'like', "%{$request->q}%");
|
$query->where('serial_number', 'like', "%{$request->q}%");
|
||||||
}
|
}
|
||||||
|
|
||||||
$serials = $query->orderBy('created_at', 'desc')
|
$serials = $query->orderBy('serial_number', 'ASC')
|
||||||
->paginate(config('app.pagination'));
|
->paginate(config('app.pagination'));
|
||||||
|
|
||||||
return ApiResponse::OK->response([
|
return ApiResponse::OK->response([
|
||||||
'serials' => $serials,
|
'serials' => $serials,
|
||||||
'inventory' => $inventory->load('category'),
|
'inventory' => $inventario->load('category'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mostrar un serial específico
|
* Mostrar un serial específico
|
||||||
*/
|
*/
|
||||||
public function show(Inventory $inventory, InventorySerial $serial)
|
public function show(Inventory $inventario, InventorySerial $serial)
|
||||||
{
|
{
|
||||||
// Verificar que el serial pertenece al inventario
|
// Verificar que el serial pertenece al inventario
|
||||||
if ($serial->inventory_id !== $inventory->id) {
|
if ($serial->inventory_id !== $inventario->id) {
|
||||||
return ApiResponse::NOT_FOUND->response([
|
return ApiResponse::NOT_FOUND->response([
|
||||||
'message' => 'Serial no encontrado para este inventario'
|
'message' => 'Serial no encontrado para este inventario'
|
||||||
]);
|
]);
|
||||||
@ -55,14 +55,14 @@ public function show(Inventory $inventory, InventorySerial $serial)
|
|||||||
|
|
||||||
return ApiResponse::OK->response([
|
return ApiResponse::OK->response([
|
||||||
'serial' => $serial->load('saleDetail'),
|
'serial' => $serial->load('saleDetail'),
|
||||||
'inventory' => $inventory->load('category'),
|
'inventory' => $inventario->load('category'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crear un nuevo serial
|
* Crear un nuevo serial
|
||||||
*/
|
*/
|
||||||
public function store(Inventory $inventory, Request $request)
|
public function store(Inventory $inventario, Request $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'serial_number' => ['required', 'string', 'unique:inventory_serials,serial_number'],
|
'serial_number' => ['required', 'string', 'unique:inventory_serials,serial_number'],
|
||||||
@ -70,28 +70,28 @@ public function store(Inventory $inventory, Request $request)
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$serial = InventorySerial::create([
|
$serial = InventorySerial::create([
|
||||||
'inventory_id' => $inventory->id,
|
'inventory_id' => $inventario->id,
|
||||||
'serial_number' => $request->serial_number,
|
'serial_number' => $request->serial_number,
|
||||||
'status' => 'disponible',
|
'status' => 'disponible',
|
||||||
'notes' => $request->notes,
|
'notes' => $request->notes,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Sincronizar stock
|
// Sincronizar stock
|
||||||
$inventory->syncStock();
|
$inventario->syncStock();
|
||||||
|
|
||||||
return ApiResponse::CREATED->response([
|
return ApiResponse::CREATED->response([
|
||||||
'serial' => $serial,
|
'serial' => $serial,
|
||||||
'inventory' => $inventory->fresh(),
|
'inventory' => $inventario->fresh(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actualizar un serial
|
* Actualizar un serial
|
||||||
*/
|
*/
|
||||||
public function update(Inventory $inventory, InventorySerial $serial, Request $request)
|
public function update(Inventory $inventario , InventorySerial $serial, Request $request)
|
||||||
{
|
{
|
||||||
// Verificar que el serial pertenece al inventario
|
// Verificar que el serial pertenece al inventario
|
||||||
if ($serial->inventory_id !== $inventory->id) {
|
if ($serial->inventory_id !== $inventario->id) {
|
||||||
return ApiResponse::NOT_FOUND->response([
|
return ApiResponse::NOT_FOUND->response([
|
||||||
'message' => 'Serial no encontrado para este inventario'
|
'message' => 'Serial no encontrado para este inventario'
|
||||||
]);
|
]);
|
||||||
@ -99,28 +99,28 @@ public function update(Inventory $inventory, InventorySerial $serial, Request $r
|
|||||||
|
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'serial_number' => ['sometimes', 'string', 'unique:inventory_serials,serial_number,' . $serial->id],
|
'serial_number' => ['sometimes', 'string', 'unique:inventory_serials,serial_number,' . $serial->id],
|
||||||
'status' => ['sometimes', 'in:disponible,vendido,dañado,reservado'],
|
'status' => ['sometimes', 'in:disponible,vendido'],
|
||||||
'notes' => ['nullable', 'string'],
|
'notes' => ['nullable', 'string'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$serial->update($request->only(['serial_number', 'status', 'notes']));
|
$serial->update($request->only(['serial_number', 'status', 'notes']));
|
||||||
|
|
||||||
// Sincronizar stock del inventario
|
// Sincronizar stock del inventario
|
||||||
$inventory->syncStock();
|
$inventario->syncStock();
|
||||||
|
|
||||||
return ApiResponse::OK->response([
|
return ApiResponse::OK->response([
|
||||||
'serial' => $serial->fresh(),
|
'serial' => $serial->fresh(),
|
||||||
'inventory' => $inventory->fresh(),
|
'inventory' => $inventario->fresh(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Eliminar un serial
|
* Eliminar un serial
|
||||||
*/
|
*/
|
||||||
public function destroy(Inventory $inventory, InventorySerial $serial)
|
public function destroy(Inventory $inventario, InventorySerial $serial)
|
||||||
{
|
{
|
||||||
// Verificar que el serial pertenece al inventario
|
// Verificar que el serial pertenece al inventario
|
||||||
if ($serial->inventory_id !== $inventory->id) {
|
if ($serial->inventory_id !== $inventario->id) {
|
||||||
return ApiResponse::NOT_FOUND->response([
|
return ApiResponse::NOT_FOUND->response([
|
||||||
'message' => 'Serial no encontrado para este inventario'
|
'message' => 'Serial no encontrado para este inventario'
|
||||||
]);
|
]);
|
||||||
@ -129,18 +129,18 @@ public function destroy(Inventory $inventory, InventorySerial $serial)
|
|||||||
$serial->delete();
|
$serial->delete();
|
||||||
|
|
||||||
// Sincronizar stock
|
// Sincronizar stock
|
||||||
$inventory->syncStock();
|
$inventario->syncStock();
|
||||||
|
|
||||||
return ApiResponse::OK->response([
|
return ApiResponse::OK->response([
|
||||||
'message' => 'Serial eliminado exitosamente',
|
'message' => 'Serial eliminado exitosamente',
|
||||||
'inventory' => $inventory->fresh(),
|
'inventory' => $inventario->fresh(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Importar múltiples seriales
|
* Importar múltiples seriales
|
||||||
*/
|
*/
|
||||||
public function bulkStore(Inventory $inventory, Request $request)
|
public function bulkStore(Inventory $inventario, Request $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'serial_numbers' => ['required', 'array', 'min:1'],
|
'serial_numbers' => ['required', 'array', 'min:1'],
|
||||||
@ -151,7 +151,7 @@ public function bulkStore(Inventory $inventory, Request $request)
|
|||||||
|
|
||||||
foreach ($request->serial_numbers as $serialNumber) {
|
foreach ($request->serial_numbers as $serialNumber) {
|
||||||
$serial = InventorySerial::create([
|
$serial = InventorySerial::create([
|
||||||
'inventory_id' => $inventory->id,
|
'inventory_id' => $inventario->id,
|
||||||
'serial_number' => $serialNumber,
|
'serial_number' => $serialNumber,
|
||||||
'status' => 'disponible',
|
'status' => 'disponible',
|
||||||
]);
|
]);
|
||||||
@ -160,12 +160,12 @@ public function bulkStore(Inventory $inventory, Request $request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sincronizar stock
|
// Sincronizar stock
|
||||||
$inventory->syncStock();
|
$inventario->syncStock();
|
||||||
|
|
||||||
return ApiResponse::CREATED->response([
|
return ApiResponse::CREATED->response([
|
||||||
'serials' => $created,
|
'serials' => $created,
|
||||||
'count' => count($created),
|
'count' => count($created),
|
||||||
'inventory' => $inventory->fresh(),
|
'inventory' => $inventario->fresh(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,7 +49,7 @@ public function map($row): array
|
|||||||
'costo' => $row['costo'] ?? null,
|
'costo' => $row['costo'] ?? null,
|
||||||
'precio_venta' => $row['precio_venta'] ?? null,
|
'precio_venta' => $row['precio_venta'] ?? null,
|
||||||
'impuesto' => $row['impuesto'] ?? null,
|
'impuesto' => $row['impuesto'] ?? null,
|
||||||
'numeros_serie' => $row['numeros_serie'] ?? null, // Nueva columna: separados por comas
|
'numeros_serie' => $row['numeros_serie'] ?? null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,22 +117,15 @@ public function model(array $row)
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Sincronizar stock basado en los seriales
|
||||||
|
$inventory->syncStock();
|
||||||
} else {
|
} else {
|
||||||
// Si no se proporcionan seriales, generar automáticamente
|
// Si no se proporcionan seriales, es un producto no serializado.
|
||||||
$stockQuantity = (int) $row['stock'];
|
// Asignar el stock directamente desde la columna 'stock'.
|
||||||
|
$inventory->stock = (int) ($row['stock'] ?? 0);
|
||||||
for ($i = 1; $i <= $stockQuantity; $i++) {
|
$inventory->save();
|
||||||
InventorySerial::create([
|
|
||||||
'inventory_id' => $inventory->id,
|
|
||||||
'serial_number' => $inventory->sku . '-' . str_pad($i, 4, '0', STR_PAD_LEFT),
|
|
||||||
'status' => 'disponible',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sincronizar stock
|
|
||||||
$inventory->syncStock();
|
|
||||||
|
|
||||||
$this->imported++;
|
$this->imported++;
|
||||||
|
|
||||||
return $inventory;
|
return $inventory;
|
||||||
|
|||||||
@ -19,7 +19,6 @@ public function up(): void
|
|||||||
$table->integer('quantity');
|
$table->integer('quantity');
|
||||||
$table->decimal('unit_price', 10, 2);
|
$table->decimal('unit_price', 10, 2);
|
||||||
$table->decimal('subtotal', 10, 2);
|
$table->decimal('subtotal', 10, 2);
|
||||||
$table->json('serial_numbers')->nullable();
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user