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