add: reportes por rango de fecha

This commit is contained in:
Juan Felipe Zapata Moreno 2026-01-05 15:52:08 -06:00
parent d5665f0448
commit 40bc2b5735
2 changed files with 15 additions and 14 deletions

View File

@ -15,22 +15,22 @@ public function __construct(
/**
* Obtener el producto más vendido
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function topSellingProduct(Request $request)
{
$request->validate([
'include_stock_value' => ['nullable', 'boolean'],
'from_date' => ['nullable', 'date_format:Y-m-d'],
'to_date' => ['nullable', 'date_format:Y-m-d', 'after_or_equal:from_date', 'required_with:from_date'],
], [
'include_stock_value.boolean' => 'El parámetro de valor de stock debe ser verdadero o falso.',
'from_date.date_format' => 'La fecha inicial debe tener el formato Y-m-d (ejemplo: 2025-01-01).',
'to_date.date_format' => 'La fecha final debe tener el formato Y-m-d (ejemplo: 2025-01-31).',
'to_date.after_or_equal' => 'La fecha final debe ser igual o posterior a la fecha inicial.',
'to_date.required_with' => 'La fecha final es obligatoria cuando se proporciona fecha inicial.',
]);
try {
$product = $this->reportService->getTopSellingProduct(
fromDate: $request->input('from_date'),
@ -57,25 +57,27 @@ public function topSellingProduct(Request $request)
/**
* Obtener productos sin movimiento
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function productsWithoutMovement(Request $request)
{
$request->validate([
'days_threshold' => ['nullable', 'integer', 'min:1'],
'include_stock_value' => ['nullable', 'boolean'],
'from_date' => ['required', 'date_format:Y-m-d'],
'to_date' => ['required', 'date_format:Y-m-d', 'after_or_equal:from_date'],
], [
'days_threshold.integer' => 'El umbral de días debe ser un número entero.',
'days_threshold.min' => 'El umbral de días debe ser al menos 1.',
'include_stock_value.boolean' => 'El parámetro de valor de stock debe ser verdadero o falso.',
'from_date.required' => 'La fecha inicial es obligatoria.',
'from_date.date_format' => 'La fecha inicial debe tener el formato Y-m-d (ejemplo: 2025-01-01).',
'to_date.required' => 'La fecha final es obligatoria.',
'to_date.date_format' => 'La fecha final debe tener el formato Y-m-d (ejemplo: 2025-01-31).',
'to_date.after_or_equal' => 'La fecha final debe ser igual o posterior a la fecha inicial.',
]);
try {
$products = $this->reportService->getProductsWithoutMovement(
daysThreshold: (int)($request->input('days_threshold', 30)),
includeStockValue: (bool)($request->input('include_stock_value', true))
includeStockValue: (bool)($request->input('include_stock_value', true)),
fromDate: $request->input('from_date'),
toDate: $request->input('to_date')
);
return ApiResponse::OK->response([

View File

@ -56,13 +56,14 @@ public function getTopSellingProduct(?string $fromDate = null, ?string $toDate =
* @param bool $includeStockValue Incluir valor del inventario (default: true)
* @return array Lista de productos sin ventas
*/
public function getProductsWithoutMovement(int $daysThreshold = 30, bool $includeStockValue = true): array
public function getProductsWithoutMovement(bool $includeStockValue = true, ?string $fromDate = null, ?string $toDate = null): array
{
// Obtener IDs de productos que SÍ tienen ventas
$inventoriesWithSales = SaleDetail::query()
->join('sales', 'sale_details.sale_id', '=', 'sales.id')
->where('sales.status', 'completed')
->whereNull('sales.deleted_at')
->whereBetween(DB::raw('DATE(sales.created_at)'), [$fromDate, $toDate])
->distinct()
->pluck('sale_details.inventory_id')
->toArray();
@ -76,7 +77,6 @@ public function getProductsWithoutMovement(int $daysThreshold = 30, bool $includ
inventories.stock,
categories.name as category_name,
inventories.created_at as date_added,
DATEDIFF(NOW(), inventories.created_at) as days_without_movement,
prices.retail_price
');
@ -93,7 +93,6 @@ public function getProductsWithoutMovement(int $daysThreshold = 30, bool $includ
->where('inventories.is_active', true)
->whereNull('inventories.deleted_at')
->whereNotIn('inventories.id', $inventoriesWithSales)
->havingRaw('DATEDIFF(NOW(), inventories.created_at) >= ?', [$daysThreshold])
->orderBy('inventories.created_at')
->get()
->toArray();