- Agregado campo isr_table_id en tabla months para seleccionar tabla ISR por mes - Creado servicio IsrCalculator para calcular ISR mensual y quincenal - Modificado CommissionCalculator para descontar ISR del total a pagar - Agregado selector de tabla ISR en formulario de crear/editar mes - Actualizada vista de meses para mostrar tabla ISR asignada - Actualizados reportes mensual y quincenal para mostrar ISR descontado
66 lines
2.0 KiB
PHP
66 lines
2.0 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
use App\Models\IsrBracket;
|
||
use App\Models\IsrTable;
|
||
|
||
class IsrCalculator
|
||
{
|
||
/**
|
||
* Calcular ISR mensual dado un ingreso base
|
||
* Retorna: ['isr' => float, 'bracket' => array|null, 'effective_rate' => float]
|
||
*/
|
||
public static function calculateMonthly(float $baseIncome, ?IsrTable $isrTable): array
|
||
{
|
||
if (!$isrTable || $baseIncome <= 0) {
|
||
return [
|
||
'isr' => 0,
|
||
'bracket' => null,
|
||
'effective_rate' => 0,
|
||
'taxable_income' => 0,
|
||
];
|
||
}
|
||
|
||
$brackets = $isrTable->brackets()->orderBy('lower_limit')->get();
|
||
|
||
foreach ($brackets as $bracket) {
|
||
$upperLimit = $bracket->upper_limit;
|
||
|
||
// Si es el último bracket (upper_limit es null = "En adelante")
|
||
if ($upperLimit === null || $baseIncome <= $upperLimit) {
|
||
// Calcular ISR: Cuota Fija + (Excedente × Tasa)
|
||
$excedent = $baseIncome - $bracket->lower_limit;
|
||
$isr = $bracket->fixed_fee + ($excedent * $bracket->rate / 100);
|
||
|
||
return [
|
||
'isr' => round($isr, 2),
|
||
'bracket' => [
|
||
'lower_limit' => $bracket->lower_limit,
|
||
'upper_limit' => $bracket->upper_limit,
|
||
'fixed_fee' => $bracket->fixed_fee,
|
||
'rate' => $bracket->rate,
|
||
],
|
||
'effective_rate' => round(($isr / $baseIncome) * 100, 2),
|
||
'taxable_income' => round($baseIncome, 2),
|
||
];
|
||
}
|
||
}
|
||
|
||
return [
|
||
'isr' => 0,
|
||
'bracket' => null,
|
||
'effective_rate' => 0,
|
||
'taxable_income' => 0,
|
||
];
|
||
}
|
||
|
||
/**
|
||
* Calcular ISR quincenal = ISR mensual / 2
|
||
*/
|
||
public static function calculateBiweekly(float $monthlyIsr): float
|
||
{
|
||
return round($monthlyIsr / 2, 2);
|
||
}
|
||
}
|