Passed
Push — master ( 3061f1...999dfb )
by João
02:43
created

calcvICMSCompDif()   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
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
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
/**
52
 * @param ICMS $ICMS
53
 * @param string $ufOrigem
54
 * @param string $ufDestino
55
 * @param float $reducao
56
 * @return ICMS
57
 * @throws NotImplementedCSTException|InvalidCSTException|Exception
58
 */
59 1
function calcularICMS(ICMS $ICMS, string $ufOrigem, string $ufDestino, float $reducao = null): ICMS
60
{
61
    $notImplemented = [
62 14
        '20', '30', '40', '50', '60', '70', '101', '103',
63
        '200', '201', '202', '203', '300', '400', '500', '900'
64
    ];
65 14
    if (in_array($ICMS->CST, $notImplemented, true)) {
66 1
        throw new NotImplementedCSTException($ICMS->CST);
67
    }
68 13
    if ($reducao === null) {
69 12
        $ICMS->pICMS = pICMSFromUFs($ufOrigem, $ufDestino);
70 12
        $ICMS->pICMSST = pICMSSTFromUFs($ufOrigem, $ufDestino);
71
    } else {
72 1
        $ICMS->pICMS = $reducao;
73 1
        $ICMS->pICMSST = $reducao;
74
    }
75
    $calculosCST = [
76 13
        '00' => 'Gbbs\NfeCalculos\calcCST00',
77
        '10' => 'Gbbs\NfeCalculos\calcCST10',
78
        '41' => 'Gbbs\NfeCalculos\calcCST41',
79
        '51' => 'Gbbs\NfeCalculos\calcCST51',
80
        '90' => 'Gbbs\NfeCalculos\calcCST90',
81
        '102' => 'Gbbs\NfeCalculos\calcCSOSN102',
82
    ];
83 13
    if (array_key_exists($ICMS->CST, $calculosCST)) {
84 12
        return $calculosCST[$ICMS->CST]($ICMS);
85
    }
86 1
    throw new InvalidCSTException($ICMS->CST);
87
}
88
89
/**
90
 * Subtrai do valor da BC do ICMS ST o percentual da redução de BC do ICMS ST
91
 * @param $ICMS
92
 * @return float
93
 */
94 1
function calcularReducaoValorBCST(ICMS $ICMS): float
95
{
96 2
    return $ICMS->vBCST * (1 - $ICMS->pRedBCST / 100);
97
}
98
99
/**
100
 * Calcula o Valor do ICMS
101
 * @param $ICMS
102
 * @return float
103
 */
104 1
function calcvICMS(ICMS $ICMS): float
105
{
106 6
    return round($ICMS->vBC * $ICMS->pICMS / 100, 2);
107
}
108
109
/**
110
 * Calcula o Valor do ICMS com pICMSDif
111
 * @param ICMS $ICMS
112
 * @return float
113
 */
114 1
function calcvICMSCompDif(ICMS $ICMS): float
115
{
116 1
    $pDif = $ICMS->pICMS - ($ICMS->pICMS * $ICMS->pDif) / 100;
117
118 1
    return round($ICMS->vBC * $pDif / 100, 2);
119
}
120
121
122
/**
123
 * Calcula o valor do ICMS Diferido
124
 * @param ICMS $ICMS
125
 * @return float
126
 */
127 1
function calcvICMSDif(ICMS $ICMS): float
128
{
129 1
    $vICMS = calcvICMS($ICMS);
130
131 1
    return $vICMS - $ICMS->vBC * ($ICMS->pICMS - ($ICMS->pICMS * ($ICMS->pDif / 100))) / 100;
132
}
133
134
/**
135
 * @param $ICMS
136
 * @return ICMS
137
 * @throws Exception
138
 */
139 1
function calcCST00(ICMS $ICMS): ICMS
140
{
141 3
    if ($ICMS->modBC !== 0) {
142 1
        throw new Exception('modBC ' . $ICMS->modBC . ' not implemented');
143
    }
144 2
    $calculado = new ICMS();
145 2
    $calculado->orig = $ICMS->orig;
146 2
    $calculado->CST = $ICMS->CST;
147 2
    $calculado->modBC = $ICMS->modBC;
148 2
    $calculado->vBC = $ICMS->vBC;
149 2
    $calculado->pICMS = $ICMS->pICMS;
150 2
    $calculado->vICMS = calcvICMS($ICMS);
151
152 2
    return $calculado;
153
}
154
155
/**
156
 * @param $ICMS
157
 * @return ICMS
158
 * @throws Exception
159
 */
160 1
function calcCST10(ICMS $ICMS): ICMS
161
{
162 3
    if ($ICMS->modBCST !== 4) {
163 1
        throw new Exception('modBCST ' . $ICMS->modBCST . ' not implemented');
164
    }
165 2
    $calculado = new ICMS();
166 2
    $calculado->orig = $ICMS->orig;
167 2
    $calculado->CST = $ICMS->CST;
168 2
    $calculado->modBC = $ICMS->modBC;
169 2
    $calculado->vBC = $ICMS->vBC;
170 2
    $calculado->pICMS = $ICMS->pICMS;
171 2
    $calculado->modBCST = $ICMS->modBCST;
172 2
    $calculado->pMVAST = $ICMS->pMVAST;
173 2
    $calculado->pRedBCST = $ICMS->pRedBCST;
174 2
    $calculado->pICMSST = $ICMS->pICMSST;
175 2
    $calculado->vICMS = calcvICMS($ICMS);
176 2
    $calculado->vBCST = calcularReducaoValorBCST($ICMS) * (1 + $ICMS->pMVAST / 100);
177 2
    $calculado->vICMSST = $ICMS->pMVAST === 0.0
178 1
        ? 0.0
179 1
        : round(($calculado->vBCST * (1 - $ICMS->pRedBCST / 100)) * $ICMS->pICMSST / 100 - $calculado->vICMS, 2);
180
181 2
    return $calculado;
182
}
183
184
/**
185
 * @param $ICMS
186
 * @return ICMS
187
 * @throws Exception
188
 */
189 1
function calcCST41(ICMS $ICMS): ICMS
190
{
191 2
    $calculado = new ICMS();
192 2
    $calculado->orig = $ICMS->orig;
193 2
    $calculado->CST = $ICMS->CST;
194 2
    $calculado->vBC = 0.0;
195 2
    $calculado->vICMS = 0.0;
196 2
    $calculado->pICMS = 0.0;
197 2
    $calculado->vICMSDeson = $ICMS->vBC * ($ICMS->pICMS / 100);
198 2
    $calculado->motDesICMS = $ICMS->motDesICMS;
199
200 2
    return $calculado;
201
}
202
203
/**
204
 * @param $ICMS
205
 * @return ICMS
206
 * @throws Exception
207
 */
208 1
function calcCST51(ICMS $ICMS): ICMS
209
{
210 2
    if ($ICMS->modBC !== 3) {
211 1
        throw new Exception('modBC ' . $ICMS->modBC . ' not implemented');
212
    }
213 1
    $calculado = new ICMS();
214 1
    $calculado->orig = '0';
215 1
    $calculado->CST = $ICMS->CST;
216 1
    $calculado->modBC = $ICMS->modBC;
217 1
    $calculado->vBC = $ICMS->vBC;
218 1
    $calculado->pICMS = $ICMS->pICMS;
219 1
    $calculado->vICMS = calcvICMSCompDif($ICMS);
220 1
    $calculado->vICMSOp = calcvICMS($ICMS);
221 1
    $calculado->pDif = $ICMS->pDif;
222 1
    $calculado->vICMSDif = calcvICMSDif($ICMS);
223
224 1
    return $calculado;
225
}
226
227
/**
228
 * @param $ICMS
229
 * @return ICMS
230
 * @throws Exception
231
 */
232 1
function calcCST90(ICMS $ICMS): ICMS
233
{
234 1
    $calculado = new ICMS();
235 1
    $calculado->orig = $ICMS->orig;
236 1
    $calculado->CST = $ICMS->CST;
237 1
    $calculado->modBC = $ICMS->modBC;
238 1
    $calculado->vBC = $ICMS->vBC;
239 1
    $calculado->pICMS = $ICMS->pICMS;
240 1
    $calculado->vICMS = calcvICMS($ICMS);
241
242 1
    return $calculado;
243
}
244
245
/**
246
 * @param $ICMS
247
 * @return ICMS
248
 */
249 1
function calcCSOSN102(ICMS $ICMS): ICMS
250
{
251 1
    $calculado = new ICMS();
252 1
    $calculado->orig = $ICMS->orig;
253 1
    $calculado->CST = $ICMS->CST;
254 1
    return $calculado;
255
}
256
257
/**
258
 * @param string $ufOrigem
259
 * @param string $ufDestino
260
 * @throws Exception
261
 * @return float
262
 */
263 1
function pICMSFromUFs(string $ufOrigem, string $ufDestino): float
264
{
265 13
    $path = realpath(__DIR__ . '/../storage') . '/';
266 13
    $picmsFile = file_get_contents($path . 'picms.json');
267 13
    $picmsList = json_decode($picmsFile, true);
268 13
    if ($ufDestino === '99') {
269 1
        return 0.0;
270
    }
271 12
    foreach ($picmsList as $picms) {
272 12
        if ($picms['uf'] === $ufOrigem) {
273 11
            return (float) $picms['uf' . $ufDestino];
274
        }
275
    }
276 1
    throw new Exception('UF inexistente: ' . $ufOrigem . ' - ' . $ufDestino);
277
}
278
279
/**
280
 * @param string $ufOrigem
281
 * @param string $ufDestino
282
 * @throws Exception
283
 * @return float
284
 */
285 1
function pICMSSTFromUFs(string $ufOrigem, string $ufDestino): float
286
{
287 13
    $path = realpath(__DIR__ . '/../storage') . '/';
288 13
    $picmsstFile = file_get_contents($path . 'picmsst.json');
289 13
    $picmsstList = json_decode($picmsstFile, true);
290 13
    if ($ufDestino === '99') {
291 1
        return 0.0;
292
    }
293 12
    foreach ($picmsstList as $picmsst) {
294 12
        if ($picmsst['uf'] === $ufOrigem) {
295 11
            return (float) $picmsst['uf' . $ufDestino];
296
        }
297
    }
298 1
    throw new Exception('UF inexistente: ' . $ufOrigem . ' - ' . $ufDestino);
299
}
300