c78ca3672e2876a80dab4c40bbc1faecb7f3122d
[cascardo/declara.git] / lib / importa.c
1 /*
2  *  Copyright (C) 2015-2018  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 "importa.h"
20 #include <errno.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <zlib.h>
25 #include "declaracao.h"
26 #include "cmd.h"
27 #include "rendimento.h"
28 #include "carne.h"
29 #include "isento.h"
30 #include "pagamento.h"
31 #include "bem.h"
32 #include "dependente.h"
33 #include "totais.h"
34 #include "sistema.h"
35 #include "ano.h"
36
37 #define COPY(size) \
38         if (size > sizeof(buffer) - 2) \
39                 return -ENOSPC; \
40         if (pos + size >= len) \
41                 return pos; \
42         memcpy(buffer, line + pos, size); \
43         buffer[size] = 0; \
44         pos += size;
45
46 #define COPYI(field, size) \
47         COPY(size) \
48         field = atoi(buffer);
49
50 #define COPYL(field, size) \
51         COPY(size) \
52         field = strtoull(buffer, NULL, 10);
53
54 #define COPYS(field, size) \
55         COPY(size); \
56         field = strdup(buffer);
57
58 #define COPYDI(field, size) \
59         COPYI(dec->field, size)
60
61 #define COPYDL(field, size) \
62         COPYL(dec->field, size)
63
64 #define COPYDS(field, size) \
65         COPYS(dec->field, size)
66
67 #define COPYC(field, size) \
68         COPYS(dec->contribuinte.field, size)
69
70 static int importa_header(struct declaracao *dec, char *line, size_t len)
71 {
72         int pos = 0;
73         char buffer[256];
74
75         pos += 8;
76         COPYDI(ano, 4);
77         pos += 4;
78         pos += 4;
79         pos += 1;
80         COPYDS(cpf, 11);
81         pos += 3;
82         pos += 1;
83         pos += 3;
84         COPYDS(nome, 60);
85         COPYC(uf, 2);
86         pos += 10;
87         pos += 1;
88         COPYC(dn, 8);
89         COPY(1);
90         if (buffer[0] == 'S')
91                 dec->tipo = COMPLETA;
92         else
93                 dec->tipo = SIMPLES;
94         pos += 1;
95         pos += 1;
96         COPYDS(retifica, 10);
97         pos += 1;
98         COPYDS(sistema.so, 14);
99         COPYDS(sistema.so_versao, 7);
100         COPYDS(sistema.jvm_versao, 9);
101         pos += 10;
102         COPYDI(contribuinte.cd_municipio, 4);
103         pos += 11;
104         pos += 1;
105         pos += 13;
106         COPYDS(recibo, 10);
107
108         //fprintf(f, "%d", dec->retifica ? 0 : (dec->recibo ? 2 : 1));
109         pos += 1;
110
111         pos += 2;
112         pos += 1;
113         pos += 1;
114         COPYC(cep, 8);
115         pos += 1;
116         COPYDS(banco, 3);
117         COPYDS(agencia, 4);
118         pos += 1;
119         pos += 8;
120         pos += 13;
121         pos += 1;
122         pos += 11;
123         pos += 1;
124         pos += 11;
125         pos += 1;
126         pos += 11;
127         pos += 1;
128         pos += 11;
129         pos += 13;
130         pos += 14 * 4;
131         pos += 114;
132         pos += 14;
133         pos += 14;
134         pos += 11;
135         pos += 11;
136         COPYC(municipio, 40);
137         pos += 60;
138         pos += 11;
139         COPYDS(sistema.mac, 12);
140         pos += 8;
141         pos += 11;
142         pos += 3;
143         pos += 13;
144         pos += 14;
145         pos += 14;
146         pos += 13;
147         pos += 13;
148         pos += 13;
149         pos += 13;
150         COPYDS(dvconta, 2);
151         pos += 1;
152         COPYDI(contribuinte.natureza_ocupacao, 2);
153         pos += 66;
154         pos += 10;
155
156         /* Mudanças de 2016 */
157
158         if (dec->ano >= 2016) {
159                 pos += 7 * 14;
160         }
161
162         /* Fim das mudanças de 2016 */
163
164         pos += 3;
165
166         return pos;
167 }
168
169 static int importa_contribuinte(struct declaracao *dec, char *line, size_t len)
170 {
171         int pos = 0;
172         char buffer[256];
173
174         pos += 2;
175         pos += 11;
176
177         COPYDS(nome, 60);
178         COPYC(tipo_logradouro, 15);
179         COPYC(logradouro, 40);
180         COPYC(numero, 6);
181         COPYC(complemento, 21);
182         COPYC(bairro, 19);
183         COPYC(cep, 8);
184         pos += 1;
185         COPYDI(contribuinte.cd_municipio, 4);
186         COPYC(municipio, 40);
187         COPYC(uf, 2);
188         pos += 3;
189         pos += 3;
190
191         if (dec->ano == 2015) {
192                 pos += 112;
193         } else if (dec->ano >= 2016) {
194                 pos += 90;
195                 COPYC(nit, 11);
196                 COPYDS(conjuge.cpf, 11);
197         }
198         if (dec->ano <= 2017) {
199                 COPYC(ddd, 4);
200                 COPYC(telefone, 9);
201         } else {
202                 pos += 13;
203         }
204         COPYC(dn, 8);
205         COPYC(titulo_eleitor, 13);
206         COPYDI(contribuinte.ocupacao_principal, 3);
207         COPYDI(contribuinte.natureza_ocupacao, 2);
208         pos += 1;
209         pos += 1;
210         pos += 1;
211         pos += 1;
212         pos += 1;
213         COPYDS(retifica, 12);
214         COPYDS(banco, 3);
215         COPYDS(agencia, 4);
216         pos += 1;
217         pos += 1;
218         COPYDS(contacorrente, 13);
219         COPYDS(dvconta, 2);
220         pos += 1;
221         pos += 1;
222         pos += 14;
223         COPYDS(recibo, 10);
224         pos += 1;
225         pos += 11;
226         if (dec->ano >= 2016)
227                 pos += 20;
228         if (dec->ano >= 2017) {
229                 COPYC(celular, 11);
230                 pos += 1;
231         }
232         if (dec->ano >= 2018) {
233                 COPYC(ddd, 2);
234                 COPYC(telefone, 9);
235         }
236
237         return pos;
238 }
239
240 static int importa_conjuge(struct declaracao *dec, char *line, size_t len)
241 {
242         int pos = 0;
243         char buffer[256];
244
245         pos += 2;
246         pos += 11;
247         COPYDS(conjuge.cpf, 11);
248         COPYDL(conjuge.base, 13);
249         COPYDL(conjuge.imposto, 13);
250         COPYDL(conjuge.isento, 13);
251         COPYDL(conjuge.exclusivo, 13);
252         COPYDL(conjuge.rendpj_exigibilidade_suspensa, 13);
253         COPYDL(conjuge.total, 13);
254         COPY(1);
255         if (buffer[0] == 'S')
256                 dec->conjuge.entregou = 1;
257         else
258                 dec->conjuge.entregou = 0;
259
260         return pos;
261 }
262
263 static int ignore_line(struct declaracao *dec, char *line, size_t len)
264 {
265         return 0;
266 }
267
268 static int importa_rendimento(struct declaracao *dec, char *line, size_t len)
269 {
270         struct rendimento *rend;
271         int pos = 0;
272         char buffer[256];
273         int r;
274
275         rend = malloc(sizeof(*rend));
276         if (!rend)
277                 return -ENOMEM;
278         pos += 2;
279         pos += 11;
280         COPYS(rend->cnpj, 14);
281         COPYS(rend->nome, 60);
282         COPYL(rend->rendimento, 13);
283         COPYL(rend->previdencia, 13);
284         COPYL(rend->decimoterceiro, 13);
285         COPYL(rend->imposto, 13);
286         COPYS(rend->saida, 8);
287         COPYL(rend->imposto_13o, 13);
288         if ((r = list_add(&dec->rendimento, rend)) < 0) {
289                 rendimento_free(rend);
290                 return r;
291         }
292         return pos;
293 }
294
295 static int importa_pagamento(struct declaracao *dec, char *line, size_t len)
296 {
297         struct pagamento *p;
298         int pos = 0;
299         char buffer[256];
300         int r;
301
302         p = malloc(sizeof(*p));
303         if (!p)
304                 return -ENOMEM;
305
306         pos += 2;
307         pos += 11;
308         COPYI(p->codigo, 2);
309         COPYI(p->dependente, 5);
310         COPYS(p->cnpj, 14);
311         COPYS(p->nome, 60);
312         /* TODO: NIT */
313         pos += 11;
314         COPYL(p->pagamento, 13);
315         COPYL(p->reembolso, 13);
316         if (dec->ano >= 2016) {
317                 /* TODO: contribuição do ente público patrocinador (FUNPRESP?) */
318                 pos += 13;
319         }
320         /* PF ou PJ? */
321         pos += 1;
322         /* Titular (T), Dependente (D), Alimentando (A), FIXME Alimentando */
323         pos += 1;
324         if ((r = list_add(&dec->pagamentos, p)) < 0) {
325                 pagamento_free(p);
326                 return r;
327         }
328         return pos;
329 }
330
331 static int importa_isento(struct declaracao *dec, char *line, size_t len)
332 {
333         struct isento *i;
334         int pos = 0;
335         char buffer[256];
336         int r;
337
338         i = malloc(sizeof(*i));
339         if (!i)
340                 return -ENOMEM;
341
342         COPYI(i->codigo, 2);
343         pos += 11;
344         pos += 5;
345         /* Titular (T), Dependente (D), Alimentando (A), FIXME Alimentando */
346         pos += 1;
347         COPYS(i->cnpj, 14);
348         COPYS(i->nome, 60);
349         COPYL(i->valor, 13);
350         /* TODO: Suportar dependente */
351         pos += 11;
352         if ((r = list_add(&dec->isentos, i)) < 0) {
353                 isento_free(i);
354                 return r;
355         }
356         return pos;
357 }
358
359 static int importa_outrosisentos(struct declaracao *dec, char *line, size_t len)
360 {
361         struct isento *i;
362         int pos = 0;
363         char buffer[256];
364         int r;
365
366         r = importa_isento(dec, line, len);
367         if (r > 0)
368                 pos = r;
369         else
370                 return r;
371         i = list_get(dec->isentos, list_size(dec->isentos));
372         if (!i)
373                 return -EINVAL;
374         COPYI(i->exclusivo, 1);
375         i->exclusivo -= 1;
376         COPYS(i->descricao, 60);
377         return pos;
378 }
379
380 static int importa_isento2(struct declaracao *dec, char *line, size_t len)
381 {
382         struct isento *i;
383         int pos = 0;
384         char buffer[256];
385         int r;
386
387         i = malloc(sizeof(*i));
388         if (!i)
389                 return -ENOMEM;
390
391         pos += 2;
392         pos += 11;
393         /* TODO: Suporte a dependente */
394         pos += 1;
395         pos += 11;
396         /* Sub-código */
397         COPYI(i->codigo, 4);
398         COPYS(i->cnpj, 14);
399         COPYS(i->nome, 60);
400         COPYL(i->valor, 13);
401         if ((r = list_add(&dec->isentos, i)) < 0) {
402                 isento_free(i);
403                 return r;
404         }
405         return pos;
406 }
407
408
409 static int importa_dependente(struct declaracao *dec, char *line, size_t len)
410 {
411         struct dependente *d;
412         int pos = 0;
413         char buffer[256];
414         int r;
415
416         d = malloc(sizeof(*d));
417         if (!d)
418                 return -ENOMEM;
419
420         pos += 2;
421         pos += 11;
422         pos += 5;
423         COPYI(d->codigo, 2);
424         COPYS(d->nome, 60);
425         COPYS(d->dn, 8);
426         COPYS(d->cpf, 11);
427         pos += 1;
428         if (dec->ano >= 2016) {
429                 /* TODO: NIT/PIS/PASEP de Pessoa Física no exterior */
430                 pos += 11;
431         }
432         if ((r = list_add(&dec->dependentes, d)) < 0) {
433                 dependente_free(d);
434                 return r;
435         }
436         return pos;
437 }
438
439 static int importa_bem(struct declaracao *dec, char *line, size_t len)
440 {
441         struct bem *b;
442         int pos = 0;
443         char buffer[514];
444         int r;
445
446         b = malloc(sizeof(*b));
447         if (!b)
448                 return -ENOMEM;
449
450         pos += 2;
451         pos += 11;
452         COPYI(b->codigo, 2);
453
454         /* FIXME: exterior */
455         pos += 1;
456         pos += 3;
457
458         COPYS(b->descricao, 512);
459         COPYL(b->valor_anterior, 13);
460         COPYL(b->valor, 13);
461
462         /* Imóvel */
463         COPYS(b->logradouro, 40);
464         COPYS(b->numero, 6);
465         COPYS(b->complemento, 40);
466         COPYS(b->bairro, 40);
467         COPYS(b->cep, 9);
468         COPYS(b->uf, 2);
469         COPYI(b->cd_municipio, 4);
470         COPYS(b->municipio, 40);
471         /* FIXME: Registro de imóveis, Nao (0), Sim (1), Vazio (2) */
472         pos += 1;
473         COPYS(b->matricula, 40);
474         COPYS(b->registro, 40);
475         COPYL(b->area, 11);
476         /* FIXME: Area, M2 (0), Ha (1), Vazio (2) */
477         pos += 1;
478         COPYS(b->cartorio, 60);
479
480         /* Número de chave */
481         pos += 5;
482         if ((r = list_add(&dec->bens, b)) < 0) {
483                 bem_free(b);
484                 return r;
485         }
486         return pos;
487 }
488
489 static int importa_carne(struct declaracao *dec, char *line, size_t len)
490 {
491         struct carne *carne;
492         int pos = 0;
493         char buffer[256];
494         int r;
495
496         carne = malloc(sizeof(*carne));
497         if (!carne)
498                 return -ENOMEM;
499         pos += 2;
500         pos += 11;
501         COPY(1);
502         if (buffer[0] == 'S') {
503                 return -ENOTSUP;
504         }
505         pos += 11;
506         COPYI(carne->mes, 2);
507         COPYL(carne->rendimento, 13);
508         COPYL(carne->alugueis, 13);
509         COPYL(carne->outros, 13);
510         COPYL(carne->exterior, 13);
511         COPYL(carne->caixa, 13);
512         COPYL(carne->alimentos, 13);
513         COPYL(carne->dependentes, 13);
514         COPYL(carne->previdencia, 13);
515         COPYL(carne->base, 13);
516         COPYL(carne->imposto, 13);
517         if ((r = list_add(&dec->carne, carne)) < 0) {
518                 carne_free(carne);
519                 return r;
520         }
521         return pos;
522 }
523
524 static struct {
525         char *prefix;
526         int (*func)(struct declaracao *, char *, size_t);
527 } prefixes[] = {
528         { "IRPF", importa_header },
529         { "16", importa_contribuinte },
530         { "17", ignore_line },
531         { "18", ignore_line },
532         { "19", ignore_line },
533         { "20", ignore_line },
534         { "21", importa_rendimento },
535         { "22", importa_carne },
536         { "23", ignore_line },
537         { "24", ignore_line },
538         { "25", importa_dependente },
539         { "26", importa_pagamento },
540         { "27", importa_bem },
541         { "29", importa_conjuge },
542         { "82", importa_isento },
543         { "84", importa_isento2 },
544         { "88", importa_isento2 },
545         { "93", importa_isento },
546         { "96", importa_isento },
547         { "97", importa_outrosisentos },
548         { "98", importa_isento },
549         { "99", importa_isento },
550         { "T9", ignore_line },
551         { "HR", ignore_line },
552         { "DR", ignore_line },
553         { "R9", ignore_line },
554 };
555
556 static int importa_linha(struct declaracao *dec, char *line, size_t len)
557 {
558         int i;
559
560         for (i = 0; i < sizeof(prefixes)/sizeof(prefixes[0]); i++)
561                 if (!strncmp(prefixes[i].prefix, line, strlen(prefixes[i].prefix)))
562                         return prefixes[i].func(dec, line, len);
563
564         return -EINVAL;
565 }
566
567 static int importa(struct declaracao *dec, char *filename)
568 {
569         char *line = NULL;
570         size_t lsz = 0;
571         FILE *f;
572         int r = 0;
573         int n = 1;
574
575         f = fopen(filename, "r");
576         if (!f) {
577                 r = -errno;
578                 dec_set_error(dec, "Não foi possível abrir arquivo %s: %s.",
579                               filename, strerror(errno));
580                 goto out_file;
581         }
582         while ((r = getline(&line, &lsz, f)) > 0) {
583                 r = importa_linha(dec, line, r);
584                 if (r < 0) {
585                         fprintf(stderr, "Não foi possível importar linha %d: %s\n",
586                                 n, dec->error ?: strerror(-r));
587                 }
588                 n++;
589         }
590
591         fclose(f);
592         return 0;
593 out_file:
594         return r;
595 }
596
597 static int run_importa(struct declaracao *dec, char **args, int argc)
598 {
599         if (argc != 2) {
600                 dec_set_error(dec, "Comando %s recebe um nome de arquivo como parâmetro.",
601                               args[0]);
602                 return -EINVAL;
603         }
604         return importa(dec, args[1]);
605 }
606
607 static struct cmd cmd_importa = {
608         .name = "importa",
609         .run = run_importa,
610 };
611
612 int importa_cmd_init(void)
613 {
614         cmd_add(&cmd_importa);
615         return 0;
616 }