ICMS::calcCSOSN102()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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