Calcula dedução por dependentes.
[cascardo/declara.git] / lib / calcula.c
1 /*
2  *  Copyright (C) 2015  Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include "calcula.h"
20 #include <errno.h>
21 #include <stdio.h>
22 #include "declaracao.h"
23 #include "cmd.h"
24 #include "rendimento.h"
25 #include "dependente.h"
26 #include "totais.h"
27
28 static const long long dependente2015 = 215652;
29
30 /* Alguns totais precisam ser limitados. Portanto, um total de decuções
31  * precisa ser ajustado para tais limites. Esta função considerará tais
32  * limites no futuro. */
33 static long long total_deducao(struct declaracao *dec)
34 {
35         int i;
36         long long dependentes = 0;
37         struct dependente *dependente;
38         for (i = 0; (dependente = list_get(dec->dependentes, i)); i++) {
39                 dependentes += dependente2015;
40         }
41         return dependentes +
42                totais_get(dec, "INSS") +
43                totais_get(dec, "PAGAMENTOS");
44 }
45
46 static void total_pago(struct declaracao *dec)
47 {
48         struct rendimento *rendimento;
49         int i;
50         dec->pago = dec->retido = 0;
51         for (i = 0; rendimento = list_get(dec->rendimento, i); i++) {
52                 dec->pago += rendimento->imposto;
53                 dec->retido += rendimento->imposto;
54         }
55 }
56
57 struct taxtable {
58         long long base;
59         long long aliquota;
60         long long deducao;
61 };
62
63 static struct taxtable table2015[] = {
64         {       0,    0,      0, },
65         { 2145324,  750, 160899, },
66         { 3215148, 1500, 402035, },
67         { 4286917, 2250, 723554, },
68         { 5356572, 2750, 991383, },
69         { 9999999999999LL, 0, 0, },
70 };
71
72 static const long long simples2015 = 1588089;
73
74 static const long long obrigatoriedade2015 = 2681655;
75
76 static long long imposto(struct taxtable *tt, long long tr)
77 {
78         int i;
79         for (i = 0; tr >= tt[i].base; i++);
80         i--;
81         return tr * tt[i].aliquota / 10000 - tt[i].deducao;
82 }
83
84 static long long imposto_simples(struct declaracao *dec)
85 {
86         struct taxtable *tt;
87         long long tr, td;
88         tt = table2015;
89         tr = totais_get(dec, "RENDPJ");
90         if (tr / 5 < simples2015)
91                 td = tr / 5;
92         else
93                 td = simples2015;
94         totais_add(dec, "DESCONTO", td);
95         tr -= td;
96         totais_add(dec, "BASE", tr);
97         return imposto(tt, tr);
98 }
99
100 static long long imposto_completa(struct declaracao *dec)
101 {
102         struct taxtable *tt;
103         long long tr, td;
104         if (dec->ano != 2015) {
105                 return -EINVAL;
106         }
107         tt = table2015;
108         tr = totais_get(dec, "RENDPJ");
109         td = total_deducao(dec);
110         tr -= td;
111         return imposto(tt, tr);
112 }
113
114 int calcula(struct declaracao *dec)
115 {
116         long long i_simples, i_completa;
117         if (dec->ano != 2015) {
118                 return -EINVAL;
119         }
120         if (totais_get(dec, "RENDPJ") > obrigatoriedade2015)
121                 dec->obrigatoria = 1;
122         i_simples = imposto_simples(dec);
123         i_completa = imposto_completa(dec);
124         total_pago(dec);
125         if (i_simples > i_completa) {
126                 dec->tipo = COMPLETA;
127                 dec->devido = i_completa;
128         } else {
129                 dec->tipo = SIMPLES;
130                 dec->devido = i_simples;
131         }
132         if (dec->pago > dec->devido)
133                 dec->restituicao = dec->pago - dec->devido;
134         else
135                 dec->pagar = dec->devido - dec->pago;
136         return 0;
137 }
138
139 static int run_calcula(struct declaracao *dec, char **args, int argc)
140 {
141         totais_add(dec, "EXCLUSIVOS_SEM_13o",
142                 totais_get(dec, "EXCLUSIVOS") -
143                 totais_get(dec, "DECIMOTERCEIRO"));
144         return calcula(dec);
145 }
146
147 static struct cmd cmd_calcula = {
148         .name = "calcula",
149         .run = run_calcula,
150 };
151
152 int calcula_cmd_init(void)
153 {
154         cmd_add(&cmd_calcula);
155         return 0;
156 }