pdv.backend/app/Services/CashRegisterService.php

156 lines
5.4 KiB
PHP

<?php
namespace App\Services;
use App\Models\CashRegister;
use App\Models\Sale;
use App\Models\Returns;
class CashRegisterService
{
/**
* Abrir caja
*/
public function openRegister(array $data)
{
// Verificar que el usuario no tenga una caja abierta
$openRegister = CashRegister::where('user_id', $data['user_id'])
->where('status', 'open')
->first();
if ($openRegister) {
throw new \Exception('Ya tienes una caja abierta. Debes cerrarla antes de abrir una nueva.');
}
return CashRegister::create([
'user_id' => $data['user_id'],
'opened_at' => now(),
'initial_cash' => $data['initial_cash'] ?? 0,
'status' => 'open',
]);
}
/**
* Cerrar caja
*/
public function closeRegister(CashRegister $register, array $data)
{
$sales = Sale::where('cash_register_id', $register->id)
->where('status', 'completed')
->get();
// Calcular devoluciones
$returns = Returns::where('cash_register_id', $register->id)->get();
// Calcular efectivo real (recibido - devuelto)
$cashSales = $sales->where('payment_method', 'cash')
->sum(function ($sale) {
return ($sale->cash_received ?? 0) - ($sale->change ?? 0);
});
// Efectivo de devoluciones
$cashReturns = $returns->where('refund_method', 'cash')->sum('total');
// Devoluciones por tarjeta
$cardReturns = $returns->whereIn('refund_method', ['credit_card', 'debit_card'])->sum('total');
$totalCashReceived = $sales->where('payment_method', 'cash')->sum('cash_received');
$totalChangeGiven = $sales->where('payment_method', 'cash')->sum('change');
$cardSales = $sales->whereIn('payment_method', ['credit_card', 'debit_card'])->sum('total');
$totalSales = $sales->sum('total');
$totalReturns = $returns->sum('total');
// Efectivo esperado (ajustado por devoluciones)
$expectedCash = $register->initial_cash + $cashSales - $cashReturns;
// Diferencia (sobrante o faltante)
$difference = $data['final_cash'] - $expectedCash;
// Cerrar caja
$register->update([
'closed_at' => now(),
'final_cash' => $data['final_cash'],
'expected_cash' => $expectedCash,
'difference' => $difference,
'total_sales' => $totalSales,
'cash_sales' => $cashSales,
'card_sales' => $cardSales,
'total_cash_received' => $totalCashReceived,
'total_change_given' => $totalChangeGiven,
// Campos nuevos de devoluciones
'total_returns' => $totalReturns,
'cash_returns' => $cashReturns,
'card_returns' => $cardReturns,
'returns_count' => $returns->count(),
'notes' => $data['notes'] ?? null,
'status' => 'closed',
]);
return $register;
}
/**
* Obtener resumen de caja actual
*/
public function getCurrentSummary(CashRegister $register)
{
$sales = Sale::where('cash_register_id', $register->id)
->where('status', 'completed')
->get();
$returns = Returns::where('cash_register_id', $register->id)->get();
// Calcular efectivo real en caja (recibido - devuelto)
$cashSales = $sales->where('payment_method', 'cash')
->sum(function ($sale) {
return ($sale->cash_received ?? 0) - ($sale->change ?? 0);
});
// Devoluciones
$cashReturns = $returns->where('refund_method', 'cash')->sum('total');
$cardReturns = $returns->whereIn('refund_method', ['credit_card', 'debit_card'])->sum('total');
$totalReturns = $returns->sum('total');
// Confirmación, envio de los totales
$totalCashReceived = $sales->where('payment_method', 'cash')->sum('cash_received');
$totalChangeGiven = $sales->where('payment_method', 'cash')->sum('change');
$cardSales = $sales->whereIn('payment_method', ['credit_card', 'debit_card'])->sum('total');
$totalSales = $sales->sum('total');
$transactionCount = $sales->count();
return [
'id' => $register->id,
'user_id' => $register->user_id,
'status' => $register->status,
'opened_at' => $register->opened_at,
'closed_at' => $register->closed_at,
'initial_cash' => (float) $register->initial_cash,
// Totales calculados
'total_sales' => (float) $totalSales,
'transaction_count' => $transactionCount,
'cash_sales' => (float) $cashSales,
'card_sales' => (float) $cardSales,
// Totales de devoluciones
'total_returns' => (float) $totalReturns,
'cash_returns' => (float) $cashReturns,
'card_returns' => (float) $cardReturns,
'returns_count' => $returns->count(),
//Desglose de efectivo
'total_cash_received' => (float) $totalCashReceived,
'total_change_given' => (float) $totalChangeGiven,
// Efectivo esperado (ajustado por devoluciones en efectivo)
'expected_cash' => (float) ($register->initial_cash + $cashSales - $cashReturns),
// Ventas netas (después de devoluciones)
'net_sales' => (float) ($totalSales - $totalReturns),
];
}
}