Passed
Push — master ( c4d08f...d0db9a )
by João
03:33
created

ICMS::calcvICMSDif()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gbbs\NfeCalculos;
6
7
use Exception;
8
use Gbbs\NfeCalculos\Exception\InvalidCSTException;
9
use Gbbs\NfeCalculos\Exception\NotImplementedCSTException;
10
11
class ICMS
12
{
13
    public $orig;  // Origem da mercadoria
14
    public $CST;  // Tributação do ICMS
15
    public $modBC;  // Modalidade de determinação da BC do ICMS
16
    public $pRedBC;  // Percentual da Redução de BC
17
    public $vBC;  // Valor da BC do ICMS
18
    public $pICMS;  // Alíquota do imposto
19
    public $vICMS;  // Valor do ICMS
20
    public $modBCST;  // Modalidade de determinação da BC do ICMS ST
21
    public $pMVAST;  // Percentual da margem de valor Adicionado do ICMS ST
22
    public $pRedBCST;  // Percentual da Redução de BC do ICMS ST
23
    public $vBCST;  // Valor da BC do ICMS ST
24
    public $pICMSST;  // Alíquota do imposto do ICMS ST
25
    public $vICMSST;  // Valor do ICMS ST
26
    public $UFST;  // UF para qual é devido o ICMS ST
27
    public $pBCop;  // Percentual da BC operação própria
28
    public $vBCSTRet;  // Valor da BC do ICMS Retido Anteriormente
29
    public $vICMSSTRet;  // Valor do ICMS Retido Anteriormente
30
    public $motDesICMS;  // Motivo da desoneração do ICMS
31
    public $vBCSTDest;  // Valor da BC do ICMS ST da UF destino
32
    public $vICMSSTDest;  // Valor do ICMS ST da UF destino
33
    public $pCredSN;  // Alíquota aplicável de cálculo do crédito (Simples Nacional)
34
    public $vCredICMSSN;  // Valor crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (SIMPLES NACIONAL)
35
    public $vICMSDeson;  // Valor do ICMS da desoneração
36
    public $vICMSOp;  // Valor do ICMS da Operação
37
    public $pDif;  // percentual do diferimento
38
    public $vICMSDif;  // Valor do ICMS Diferido
39
    public $vBCFCP;  // Valor da Base de Cálculo do FCP
40
    public $pFCP;  // Percentual do FCP
41
    public $vFCP;  // Valor do FCP
42
    public $vBCFCPST;  // Valor da Base de Cálculo do FCP retido por Substituição Tributária
43
    public $pFCPST;  // Percentual do FCP retido por Substituição Tributária.
44
    public $vFCPST;  // Valor do FCP retido por Substituição Tributária
45
    public $vBCFCPSTRet;  // Valor da BC do FCP retido anteriormente por Substituição Tributária
46
    public $pFCPSTRet;  // Alíquota do FCP retido anteriormente por Substituição Tributária
47
    public $vFCPSTRet;  // Valor do FCP retido anteriormente por Substituição Tributária
48
    public $pST;  // Alíquota suportada pelo Consumidor Final
49
50
    /**
51
     * @param ICMS $ICMS
52
     * @param string $ufOrigem
53
     * @param string $ufDestino
54
     * @param float $reducao
55
     * @return ICMS
56
     * @throws NotImplementedCSTException|InvalidCSTException|Exception
57
     */
58 16
    static function calcularICMS(ICMS $ICMS, string $ufOrigem, string $ufDestino, float $reducao = null): ICMS
59
    {
60
        $notImplemented = [
61 16
            '20', '30', '40', '50', '60', '70', '101', '103',
62
            '200', '201', '202', '203', '300', '400', '500', '900'
63
        ];
64 16
        if (in_array($ICMS->CST, $notImplemented, true)) {
65 1
            throw new NotImplementedCSTException($ICMS->CST);
66
        }
67 15
        if ($reducao === null) {
68 14
            $ICMS->pICMS = ICMS::pICMSFromUFs($ufOrigem, $ufDestino);
69 14
            $ICMS->pICMSST = ICMS::pICMSSTFromUFs($ufOrigem, $ufDestino);
70
        } else {
71 1
            $ICMS->pICMS = $reducao;
72 1
            $ICMS->pICMSST = $reducao;
73
        }
74
        $calculosCST = [
75 15
            '00' => 'Gbbs\NfeCalculos\ICMS::calcCST00',
76
            '10' => 'Gbbs\NfeCalculos\ICMS::calcCST10',
77
            '41' => 'Gbbs\NfeCalculos\ICMS::calcCST41',
78
            '51' => 'Gbbs\NfeCalculos\ICMS::calcCST51',
79
            '90' => 'Gbbs\NfeCalculos\ICMS::calcCST90',
80
            '102' => 'Gbbs\NfeCalculos\ICMS::calcCSOSN102',
81
        ];
82 15
        if (array_key_exists($ICMS->CST, $calculosCST)) {
83 14
            return $calculosCST[$ICMS->CST]($ICMS);
84
        }
85 1
        throw new InvalidCSTException($ICMS->CST);
86
    }
87
88
    /**
89
     * Subtrai do valor da BC do ICMS ST o percentual da redução de BC do ICMS ST
90
     * @param $ICMS
91
     * @return float
92
     */
93 4
    private static function calcularReducaoValorBCST(ICMS $ICMS): float
94
    {
95 4
        return $ICMS->vBCST * (1 - $ICMS->pRedBCST / 100);
96
    }
97
98
    /**
99
     * Calcula o Valor do ICMS
100
     * @param $ICMS
101
     * @return float
102
     */
103 8
    private static function calcvICMS(ICMS $ICMS): float
104
    {
105 8
        return round($ICMS->vBC * $ICMS->pICMS / 100, 2);
106
    }
107
108
    /**
109
     * Calcula o Valor do ICMS com pICMSDif
110
     * @param ICMS $ICMS
111
     * @return float
112
     */
113 1
    private static function calcvICMSCompDif(ICMS $ICMS): float
114
    {
115 1
        $pDif = $ICMS->pICMS - ($ICMS->pICMS * $ICMS->pDif) / 100;
116
117 1
        return round($ICMS->vBC * $pDif / 100, 2);
118
    }
119
120
121
    /**
122
     * Calcula o valor do ICMS Diferido
123
     * @param ICMS $ICMS
124
     * @return float
125
     */
126 1
    private static function calcvICMSDif(ICMS $ICMS): float
127
    {
128 1
        $vICMS = ICMS::calcvICMS($ICMS);
129
130 1
        return $vICMS - $ICMS->vBC * ($ICMS->pICMS - ($ICMS->pICMS * ($ICMS->pDif / 100))) / 100;
131
    }
132
133
    /**
134
     * @param $ICMS
135
     * @return ICMS
136
     * @throws Exception
137
     */
138 3
    private static function calcCST00(ICMS $ICMS): ICMS
139
    {
140 3
        if ($ICMS->modBC !== 0) {
141 1
            throw new Exception('modBC ' . $ICMS->modBC . ' not implemented');
142
        }
143 2
        $calculado = new ICMS();
144 2
        $calculado->orig = $ICMS->orig;
145 2
        $calculado->CST = $ICMS->CST;
146 2
        $calculado->modBC = $ICMS->modBC;
147 2
        $calculado->vBC = $ICMS->vBC;
148 2
        $calculado->pICMS = $ICMS->pICMS;
149 2
        $calculado->vICMS = ICMS::calcvICMS($ICMS);
150
151 2
        return $calculado;
152
    }
153
154
    /**
155
     * @param $ICMS
156
     * @return ICMS
157
     * @throws Exception
158
     */
159 5
    private static function calcCST10(ICMS $ICMS): ICMS
160
    {
161 5
        if ($ICMS->modBCST !== 4) {
162 1
            throw new Exception('modBCST ' . $ICMS->modBCST . ' not implemented');
163
        }
164 4
        $calculado = new ICMS();
165 4
        $calculado->orig = $ICMS->orig;
166 4
        $calculado->CST = $ICMS->CST;
167 4
        $calculado->modBC = $ICMS->modBC;
168 4
        $calculado->vBC = $ICMS->vBC;
169 4
        $calculado->pICMS = $ICMS->pICMS;
170 4
        $calculado->modBCST = $ICMS->modBCST;
171 4
        $calculado->pMVAST = $ICMS->pMVAST;
172 4
        $calculado->pRedBCST = $ICMS->pRedBCST;
173 4
        $calculado->pICMSST = $ICMS->pICMSST;
174 4
        $calculado->vICMS = ICMS::calcvICMS($ICMS);
175 4
        $calculado->vBCST = round(ICMS::calcularReducaoValorBCST($ICMS) * (1 + $ICMS->pMVAST / 100), 2);
176 4
        $calculado->vICMSST = $ICMS->pMVAST === 0.0
177 2
            ? 0.0
178 2
            : round(($calculado->vBCST * (1 - $ICMS->pRedBCST / 100)) * $ICMS->pICMSST / 100 - $calculado->vICMS, 2);
179
180 4
        return $calculado;
181
    }
182
183
    /**
184
     * @param $ICMS
185
     * @return ICMS
186
     * @throws Exception
187
     */
188 2
    private static function calcCST41(ICMS $ICMS): ICMS
189
    {
190 2
        $calculado = new ICMS();
191 2
        $calculado->orig = $ICMS->orig;
192 2
        $calculado->CST = $ICMS->CST;
193 2
        $calculado->vBC = 0.0;
194 2
        $calculado->vICMS = 0.0;
195 2
        $calculado->pICMS = 0.0;
196 2
        $calculado->vICMSDeson = $ICMS->vBC * ($ICMS->pICMS / 100);
197 2
        $calculado->motDesICMS = $ICMS->motDesICMS;
198
199 2
        return $calculado;
200
    }
201
202
    /**
203
     * @param $ICMS
204
     * @return ICMS
205
     * @throws Exception
206
     */
207 2
    private static function calcCST51(ICMS $ICMS): ICMS
208
    {
209 2
        if ($ICMS->modBC !== 3) {
210 1
            throw new Exception('modBC ' . $ICMS->modBC . ' not implemented');
211
        }
212 1
        $calculado = new ICMS();
213 1
        $calculado->orig = '0';
214 1
        $calculado->CST = $ICMS->CST;
215 1
        $calculado->modBC = $ICMS->modBC;
216 1
        $calculado->vBC = $ICMS->vBC;
217 1
        $calculado->pICMS = $ICMS->pICMS;
218 1
        $calculado->vICMS = ICMS::calcvICMSCompDif($ICMS);
219 1
        $calculado->vICMSOp = ICMS::calcvICMS($ICMS);
220 1
        $calculado->pDif = $ICMS->pDif;
221 1
        $calculado->vICMSDif = ICMS::calcvICMSDif($ICMS);
222
223 1
        return $calculado;
224
    }
225
226
    /**
227
     * @param $ICMS
228
     * @return ICMS
229
     * @throws Exception
230
     */
231 1
    private static function calcCST90(ICMS $ICMS): ICMS
232
    {
233 1
        $calculado = new ICMS();
234 1
        $calculado->orig = $ICMS->orig;
235 1
        $calculado->CST = $ICMS->CST;
236 1
        $calculado->modBC = $ICMS->modBC;
237 1
        $calculado->vBC = $ICMS->vBC;
238 1
        $calculado->pICMS = $ICMS->pICMS;
239 1
        $calculado->vICMS = ICMS::calcvICMS($ICMS);
240
241 1
        return $calculado;
242
    }
243
244
    /**
245
     * @param $ICMS
246
     * @return ICMS
247
     */
248 1
    private static function calcCSOSN102(ICMS $ICMS): ICMS
249
    {
250 1
        $calculado = new ICMS();
251 1
        $calculado->orig = $ICMS->orig;
252 1
        $calculado->CST = $ICMS->CST;
253 1
        return $calculado;
254
    }
255
256
    /**
257
     * @param string $ufOrigem
258
     * @param string $ufDestino
259
     * @throws Exception
260
     * @return float
261
     */
262 15
    static function pICMSFromUFs(string $ufOrigem, string $ufDestino): float
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
263
    {
264 15
        $path = realpath(__DIR__ . '/../storage') . '/';
265 15
        $picmsFile = file_get_contents($path . 'picms.json');
266 15
        $picmsList = json_decode($picmsFile, true);
267 15
        if ($ufDestino === '99') {
268 2
            return 0.0;
269
        }
270 13
        foreach ($picmsList as $picms) {
271 13
            if ($picms['uf'] === $ufOrigem) {
272 12
                return (float) $picms['uf' . $ufDestino];
273
            }
274
        }
275 1
        throw new Exception('UF inexistente: ' . $ufOrigem . ' - ' . $ufDestino);
276
    }
277
278
    /**
279
     * @param string $ufOrigem
280
     * @param string $ufDestino
281
     * @throws Exception
282
     * @return float
283
     */
284 15
    static function pICMSSTFromUFs(string $ufOrigem, string $ufDestino): float
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
285
    {
286 15
        $path = realpath(__DIR__ . '/../storage') . '/';
287 15
        $picmsstFile = file_get_contents($path . 'picmsst.json');
288 15
        $picmsstList = json_decode($picmsstFile, true);
289 15
        if ($ufDestino === '99') {
290 2
            return 0.0;
291
        }
292 13
        foreach ($picmsstList as $picmsst) {
293 13
            if ($picmsst['uf'] === $ufOrigem) {
294 12
                return (float) $picmsst['uf' . $ufDestino];
295
            }
296
        }
297 1
        throw new Exception('UF inexistente: ' . $ufOrigem . ' - ' . $ufDestino);
298
    }
299
}
300