Test Failed
Push — master ( 52345e...14a46a )
by Esteban De La Fuente
04:31
created

Utils   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Test Coverage

Coverage 90.91%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
dl 0
loc 55
ccs 10
cts 11
cp 0.9091
rs 10
c 1
b 0
f 0
wmc 6

2 Methods

Rating   Name   Duplication   Size   Complexity  
A calcularNetoIVA() 0 13 3
A round() 0 8 3
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * LibreDTE: Biblioteca PHP (Núcleo).
7
 * Copyright (C) LibreDTE <https://www.libredte.cl>
8
 *
9
 * Este programa es software libre: usted puede redistribuirlo y/o modificarlo
10
 * bajo los términos de la Licencia Pública General Affero de GNU publicada por
11
 * la Fundación para el Software Libre, ya sea la versión 3 de la Licencia, o
12
 * (a su elección) cualquier versión posterior de la misma.
13
 *
14
 * Este programa se distribuye con la esperanza de que sea útil, pero SIN
15
 * GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
16
 * PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
17
 * General Affero de GNU para obtener una información más detallada.
18
 *
19
 * Debería haber recibido una copia de la Licencia Pública General Affero de
20
 * GNU junto a este programa.
21
 *
22
 * En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
23
 */
24
25
namespace libredte\lib\Core\Package\Billing\Component\Document\Worker\Normalizer\Helper;
26
27
/**
28
 * Utilidades que pueden ser usadas en diferentes procesos de normalización y
29
 * son independientes del resto del documento.
30
 */
31
class Utils
32
{
33
    /**
34
     * Redondea valores asociados a un tipo de moneda.
35
     *
36
     * Si los valores son en pesos chilenos se redondea sin decimales. Si los
37
     * valores están en otro tipo de moneda se mantienen los decimales, por
38
     * defecto se mantienen 4 decimales.
39
     *
40
     * @param int|float $amount Valor que se desea redondear.
41
     * @param string|null|false $currency La moneda en la que está el valor.
42
     * @param int $decimals Cantidad de decimales a mantener cuando la moneda
43
     * no es peso chileno.
44
     * @return int|float Valor redondeado según la moneda y decimales a usar.
45
     */
46 56
    public static function round(
47
        int|float $amount,
48
        string|null|false $currency = null,
49
        int $decimals = 4
50
    ): int|float {
51 56
        return (!$currency || $currency === 'PESO CL')
52 47
            ? (int) round($amount)
53 56
            : (float) round($amount, $decimals)
54 56
        ;
55
    }
56
57
    /**
58
     * Obtiene el monto neto y el IVA de ese neto a partir de un monto total.
59
     *
60
     * NOTE: El IVA obtenido puede no ser el NETO * (TASA / 100). Se calcula el
61
     * monto neto y luego se obtiene el IVA haciendo la resta entre el total y
62
     * el neto. Hay casos de borde que generan problemas como:
63
     *
64
     *   - BRUTO:   680 => NETO:   571 e IVA:   108 => TOTAL:   679
65
     *   - BRUTO: 86710 => NETO: 72866 e IVA: 13845 => TOTAL: 86711
66
     *
67
     * Estos casos son "normales", pues por aproximaciones "no da".
68
     *
69
     * @param int $total Total que representa el monto neto más el IVA.
70
     * @param int|float|false $tasa Tasa del IVA o `false` si no corresponde.
71
     * @return array Arreglo con el neto y el IVA en índices 0 y 1.
72
     */
73 2
    public static function calcularNetoIVA($total, int|float|false $tasa): array
74
    {
75
        // Si no existe tasa es porque no hay Neto ni IVA (doc exento).
76 2
        if ($tasa === 0 || $tasa === false) {
77
            return [0, 0];
78
        }
79
80
        // Obtener el neto e IVA a partir del total.
81 2
        $neto = round($total / (1 + ($tasa / 100)));
82 2
        $iva = $total - $neto;
83
84
        // Entregar el neto e IVA.
85 2
        return [$neto, $iva];
86
    }
87
}
88