]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs_gui/facturas.c
76c042f5c76ee9d877053765e8a4edae7564bc71
[z.facultad/75.06/emufs.git] / emufs_gui / facturas.c
1
2 #include "facturas.h"
3 #include "idx.h"
4 #include "common.h"
5 #include "menu.h"
6 #include "lista.h"
7
8 static t_LstFacturas *lst_facturas;
9
10 /* Procesa una factura antes de enviarla al archivo para guardarla */
11 static void *procesar_guardar_factura(t_Factura *f, t_LstFacturas *lst, EMUFS_REG_SIZE *size);
12 static int procesar_leer_factura(t_Factura *dst, void *src, EMUFS_REG_SIZE size, t_LstFacturas *lst);
13
14 #ifdef TP_PRIMER_ENTREGA
15 /* Manejo de la lista en memoria */
16 static t_Reg_Factura *crear_nodo_factura(EMUFS_REG_ID reg, EMUFS_REG_ID texto, unsigned int num);
17 static int agregar_nodo_factura(t_LstFacturas *lst, t_Reg_Factura *nodo);
18 int eliminar_nodo_factura(t_LstFacturas *lst, t_Reg_Factura *nodo);
19 #endif
20
21 /* Funciones para carga desde el XML */
22 static t_Item *leer_items(xmlNode *, int *cant, int size);
23 static char *leer_nota(xmlNode *, int max);
24
25 t_LstFacturas *fact_get_lst()
26 {
27         return lst_facturas;
28 }
29
30 /* Hack! ... Si no existe propiedad retorna "" */
31 char *xml_get_prop(xmlNode *node, char *nombre)
32 {
33         char *s;
34         s = xmlGetProp(node, nombre);
35         if (s == NULL) {
36                 s = malloc(1);
37                 s[0] = '\0';
38                 return s;
39         }
40         return s;
41 }
42
43 #ifdef TP_PRIMER_ENTREGA
44 int eliminar_nodo_factura(t_LstFacturas *lst, t_Reg_Factura *nodo)
45 {
46         if (nodo == NULL) return 0;
47         if (nodo->ant == NULL) {
48                 /* Me piden borrar el primer nodo */
49                 if (nodo->sig) {
50                         nodo->sig->ant = NULL;
51                 }
52                 lst->primero = nodo->sig;
53         } else {
54                 if (nodo->sig) {
55                         nodo->sig->ant = nodo->ant;
56                 }
57                 nodo->ant->sig = nodo->sig;
58         }
59         free(nodo);
60         return 1;
61 }
62
63 t_Reg_Factura *crear_nodo_factura(EMUFS_REG_ID reg, EMUFS_REG_ID texto, unsigned int num)
64 {
65         t_Reg_Factura *tmp;
66         if (reg == EMUFS_NOT_FOUND) return NULL;
67         tmp = malloc(sizeof(t_Reg_Factura));
68         if (tmp == NULL) return NULL;
69         tmp->sig = tmp->ant = NULL;
70         tmp->num_reg = reg;
71         tmp->texto_reg = texto;
72         tmp->numero = num;
73
74         return tmp;
75 }
76
77 int agregar_nodo_factura(t_LstFacturas *lst, t_Reg_Factura *nodo)
78 {
79         if (nodo == NULL) return 0;
80
81         if (lst->primero) {
82                 lst->primero->ant = nodo;
83                 nodo->sig = lst->primero;
84                 lst->primero = nodo;
85         } else {
86                 lst->primero = nodo;
87         }
88         return 1;
89 }
90 #endif /*TP_PRIMER_ENTREGA*/
91
92 t_Item *leer_items(xmlNode *node, int *cant, int size)
93 {
94         t_Item *tmp;
95         int count;
96         char *prop;
97         if (size == -1) {
98                 tmp = NULL;
99                 count = 0;
100                 node = node->children;
101                 while (node) {
102                         if (node->type == XML_ELEMENT_NODE) {
103                                 if (strcmp(node->name, "ITEMVENTA") == 0) {
104                                         count++;
105                                         tmp = realloc(tmp, sizeof(t_Item)*count);
106                                         memset(&tmp[count-1], 0, sizeof(t_Item));
107                                         prop = xml_get_prop(node, "NroArtículo");
108                                         tmp[count-1].numero = atoi(prop);
109                                         xmlFree(prop);
110                                         strncpy(tmp[count-1].cv, prop = xml_get_prop(node, "CV"), 8); xmlFree(prop);
111                                         tmp[count-1].cv[8] = '\0';
112                                         strncpy(tmp[count-1].pvu, prop = xml_get_prop(node, "PVU"), 8); xmlFree(prop);
113                                         tmp[count-1].pvu[8] = '\0';
114                                 }
115                         }
116                         node = node->next;
117                 }
118                 *cant = count;
119         } else {
120                 (*cant) = size;
121                 tmp = (t_Item *)malloc(sizeof(t_Item)*size);
122                 memset(tmp, 0, sizeof(t_Item)*size);
123
124                 count = 0;
125                 node = node->children;
126                 while (node) {
127                         if (node->type == XML_ELEMENT_NODE) {
128                                 if (strcmp(node->name, "ITEMVENTA") == 0) {
129                                         memset(&tmp[count], 0, sizeof(t_Item));
130                                         prop = xml_get_prop(node, "NroArtículo");
131                                         tmp[count].numero = atoi(prop);
132                                         xmlFree(prop);
133                                         strncpy(tmp[count].cv, prop = xml_get_prop(node, "CV"), 8); xmlFree(prop);
134                                         tmp[count].cv[8] = '\0';
135                                         strncpy(tmp[count].pvu, prop = xml_get_prop(node, "PVU"), 8); xmlFree(prop);
136                                         tmp[count].pvu[8] = '\0';
137                                         count++;
138                                 }
139                         }
140                         if (count == 10) break; /* No me entran mas items! */
141                         node = node->next;
142                 }
143         }
144         return tmp;
145 }
146
147 char *leer_nota(xmlNode *node, int max)
148 {
149         xmlNode *tmp;
150         char *salida;
151         tmp = node->children;
152         while (tmp) {
153                 if (tmp->type == XML_ELEMENT_NODE) {
154                         if (strcmp(tmp->name, "NOTA") == 0) {
155                                 break;
156                         }
157                 }
158                 tmp = tmp->next;
159         }
160
161         if (tmp) {
162                 if (max == -1) {
163                         salida = (char *)malloc(sizeof(char)*(strlen(XML_GET_CONTENT(tmp->children))+1));
164                         strcpy(salida, XML_GET_CONTENT(tmp->children));
165                 } else {
166                         salida = (char *)malloc(sizeof(char)*max);
167                         strncpy(salida, XML_GET_CONTENT(tmp->children), max-1);
168                         salida[max-1] = '\0';
169                 }
170         } else {
171                 if (max == -1) {
172                         salida = (char *)malloc(sizeof(char));
173                         salida[0] = '\0';
174                 } else {
175                         salida = (char *)malloc(sizeof(char)*max);
176                         memset(salida, 0, max);
177                 }
178         }
179         return salida;
180 }
181
182
183 t_LstFacturas *fact_cargar(const char *filename, int tipo, int tam_bloque, int tipo_nota, int bloque_nota)
184 {
185         xmlDocPtr document;
186         xmlNode *node, *inicio;
187         int error = 0, cant_items;
188         char *prop;
189         EMUFS_REG_SIZE size;
190         t_LstFacturas *tmp;
191         t_Factura *factura;
192         EMUFS_REG_ID id;
193         
194         lst_facturas = NULL;
195
196         tmp = (t_LstFacturas *)malloc(sizeof(t_LstFacturas));
197         if (tmp == NULL) return NULL;
198         lst_facturas = tmp;
199         tmp->primero = NULL;
200
201         if (filename != NULL) {
202                 PERR("Voy a cargar de un XML");
203                 document = xmlReadFile(filename, "ISO-8859-1",0);
204                 if (document == NULL) {
205                         PERR("Error al leer documento!!");
206                         free(tmp);
207                         lst_facturas = NULL;
208                         return NULL;
209                 }
210
211                 inicio = NULL;
212                 node = xmlDocGetRootElement(document);
213                 /* Busco el TAG principal "ARTICULOS" */
214                 while (node) {
215                         if (node->type == XML_ELEMENT_NODE) {
216                                 if (strcmp(node->name, "FACTURAS") == 0) {
217                                         inicio = node->children;
218                                         break;
219                                 }
220                         }
221                         node = node->next;
222                 }
223
224                 /* En el registro no guardo los punteros de nota ni items. Si guardo la cantidad de items
225                  * y los items al final del registro.
226                  */
227                 if ((tipo-1) == T3) {
228                         /* Limito a 10 items en el caso de registro constante! */
229                         cant_items = 10;
230                 } else {
231                         cant_items = 0;
232                 }
233                 tmp->fp = emufs_crear("facturas", tipo-1, tam_bloque, sizeof(t_Factura)-sizeof(char *)-sizeof(t_Item*)+cant_items*sizeof(t_Item));
234                 emufs_agregar_indice(tmp->fp, "emision", IND_EXAHUSTIVO, IND_B, IDX_STRING, STRUCT_OFFSET(factura, emision), 512);
235                 emufs_agregar_indice(tmp->fp, "numero", IND_PRIMARIO, IND_B, IDX_INT, 0, 512);
236                 tmp->fp_texto = emufs_crear("notas", tipo_nota-1, bloque_nota, 100);
237                 for (node=inicio ; node ; node = node->next) {
238                         if (node->type == XML_ELEMENT_NODE) {
239                                 if (strcmp(node->name, "FACTURA") == 0) {
240                                         t_Factura fact;
241                                         void *save;
242                                         memset(&fact, 0, sizeof(t_Factura));
243                                         prop = xml_get_prop(node, "NroFac");
244                                         PERR(prop);
245                                         fact.numero = atoi(prop); xmlFree(prop);
246                                         prop = xml_get_prop(node, "PorcDoI");
247                                         fact.procdoi = atof(prop); xmlFree(prop);
248                                         prop = xml_get_prop(node, "NroRemito");
249                                         fact.numero_remito = atoi(prop); xmlFree(prop);
250                                         strncpy(fact.emision, prop = xml_get_prop(node, "FechaEmisión"), 8); xmlFree(prop);
251                                         fact.emision[8] = '\0';
252                                         strncpy(fact.vencimiento, prop = xml_get_prop(node, "FechaVto"), 8); xmlFree(prop);
253                                         fact.vencimiento[8] = '\0';
254                                         strncpy(fact.estado, prop = xml_get_prop(node, "Estado"), 2); xmlFree(prop);
255                                         fact.estado[2] = '\0';
256                                         strncpy(fact.fp, prop = xml_get_prop(node, "FP"), 2); xmlFree(prop);
257                                         fact.fp[2] = '\0';
258                                         strncpy(fact.ctacte, prop = xml_get_prop(node, "NroCtaCte"), 5); xmlFree(prop);
259                                         fact.ctacte[5] = '\0';
260                                         strncpy(fact.cheque, prop = xml_get_prop(node, "NroCheque"), 18); xmlFree(prop);
261                                         fact.cheque[18] = '\0';
262
263                                         fact.nota = leer_nota(node, (((tipo-1)==T3)?100:-1));
264                                         fact.items = leer_items(node, &fact.cant_items, ((tipo-1)==T3)?10:-1);
265
266                                         error = 0;
267                                         id = tmp->fp_texto->grabar_registro(tmp->fp_texto, fact.nota, ((tipo-1)==T3)?100:(strlen(fact.nota)+1), &error);
268                                         fact.reg_nota = id;
269                                         save = procesar_guardar_factura(&fact, lst_facturas, &size);
270                                         if (save != NULL) {
271                                                 error = 0;
272                                                 tmp->fp->grabar_registro(tmp->fp, save, size, &error);
273                                                 if (fact.items) {
274                                                         free(fact.items);
275                                                         fact.items = NULL;
276                                                 }
277                                                 if (fact.nota) {
278                                                         free(fact.nota);
279                                                         fact.nota = NULL;
280                                                 }
281                                                 free(save);
282                                         }
283                                 }
284                         }
285                 }
286                 xmlFreeDoc(document);
287                 xmlCleanupParser();
288         } else {
289 #ifdef NO_SE_USA_MAS
290                 /* TODO RECUPERAR INDICES DESDE EL ARCHIVO */
291                 PERR("Voy a recuperar desde un archivo");
292                 tmp->fp = emufs_abrir("facturas");
293                 if (tmp->fp == NULL) {
294                         PERR("No se pudo cargar archivo de facturas!");
295                         free(tmp);
296                         lst_facturas = NULL;
297                         return NULL;
298                 }
299                 tmp->fp_texto = emufs_abrir("notas");
300                 if (tmp->fp_texto == NULL) {
301                         PERR("No se pudo cargar archivo de notas!");
302                         emufs_destruir(tmp->fp);
303                         free(tmp);
304                         lst_facturas = NULL;
305                         return NULL;
306                 }
307
308                 /* Ahora trato de recuperar la info */
309                 indices = emufs_idx_get(tmp->fp, &indices_cant);
310                 for(i=0; i<indices_cant; i++) {
311                         t_Factura art;
312                         void *save;
313                         /* Leo el registro */
314                         save = tmp->fp->leer_registro(tmp->fp, indices[i], &size, &error);
315                         if (procesar_leer_factura(&art, save, size, tmp) == 1) {
316                                 agregar_nodo_factura(tmp, crear_nodo_factura(indices[i], art.reg_nota, art.numero));
317                                 free(save);
318                         }
319                 }
320                 free(indices);
321 #endif
322         }
323
324         PERR("Facturas todo Ok");
325         return lst_facturas;
326 }
327
328 int fact_liberar(t_LstFacturas *l)
329 {
330         t_Reg_Factura *del;
331         if (l == NULL) l = lst_facturas;
332         if (l == NULL) return 1;
333
334         emufs_destruir(l->fp);
335         emufs_destruir(l->fp_texto);
336         while (l->primero) {
337                 del = l->primero;
338                 l->primero = l->primero->sig;
339                 free(del);
340         }
341         free(l);
342
343         lst_facturas = NULL;
344         return 0;
345 }
346
347 t_Factura *fact_buscar(t_LstFacturas *lst, int numero, EMUFS_REG_ID *id, EMUFS_REG_ID *id_texto)
348 {
349         t_Factura *fact;
350         char *leo;
351         EMUFS_REG_SIZE size;
352         int error;
353         CLAVE k;
354         if (lst == NULL) return NULL;
355
356         fact = NULL;
357         k = emufs_indice_generar_clave_desde_valor(lst->fp->indices, (char*)&numero);
358         error = 0;
359         leo = lst->fp->leer_registro(lst->fp, k, &size, &error);
360         if (leo != NULL) {
361                 fact = (t_Factura *)malloc(sizeof(t_Factura));
362                 if (fact == NULL) {
363                         free(leo);
364                         return NULL;
365                 }
366                 procesar_leer_factura(fact, leo, size, lst);
367                 /* y esto ??!
368                 (*id) = reg->num_reg;
369                 (*id_texto) = reg->texto_reg;
370                 */
371                 free(leo);
372                 k.i_clave = fact->reg_nota;
373                 error = 0;
374                 fact->nota = lst->fp_texto->leer_registro(lst->fp_texto, k, &size, &error);
375         }
376         
377         return fact;
378 }
379
380 t_Factura *fact_form_buscar(WINDOW *win, EMUFS_REG_ID *id, EMUFS_REG_ID *id_texto)
381 {
382         t_Form *form;
383         t_Factura *fact;
384
385         form = form_crear(win);
386         form_agregar_widget(form, INPUT, "Numero de Factura", 8, "");
387         form_ejecutar(form, 1,1);
388         fact = fact_buscar(lst_facturas, form_obtener_valor_int(form, "Numero de Factura"), id, id_texto);
389         form_destruir(form);
390
391         return fact;
392 }
393
394 void fact_eliminar(char *s)
395 {
396         WINDOW *win;
397         t_Factura *fact;
398         EMUFS_REG_ID id;
399         CLAVE k;
400                                                                         
401         win = newwin(LINES-4, COLS-2, 2, 1);
402         box(win, 0, 0);
403         
404         fact = fact_form_buscar(win, &id, &id);
405
406         if (fact == NULL) {
407                 wattron(win, COLOR_PAIR(COLOR_YELLOW));
408                 mvwaddstr(win, 2, 1, "No existe artículo con ese código. Abortando!");
409                 wattroff(win, COLOR_PAIR(COLOR_YELLOW));
410                 wrefresh(win);
411                 getch();
412                 werase(win);
413                 wrefresh(win);
414                 delwin(win);
415                 return;
416         }
417
418         k = emufs_indice_generar_clave_desde_valor(lst_facturas->fp->indices, (char *)(&fact->numero));
419         lst_facturas->fp->borrar_registro(lst_facturas->fp, k);
420         k.i_clave = fact->reg_nota;
421         lst_facturas->fp_texto->borrar_registro(lst_facturas->fp_texto, k);
422
423         if (fact->items) free(fact->items);
424         if (fact->nota) free(fact->nota);
425         free(fact);
426 }
427
428 void fact_modificar(char *s)
429 {
430         WINDOW *win, *items, *nota, *subnota;
431         t_Form *form, *form_nota;
432         t_Factura *fact;
433         EMUFS_REG_SIZE size;
434         EMUFS_REG_ID id, id_texto;
435         int error;
436         char tmp_str[10];
437         void *entrada;
438
439         win = newwin(LINES-4, COLS-2, 2, 1);
440         box(win, 0, 0);
441         
442         if (s == NULL) {
443                 fact = fact_form_buscar(win, &id, &id_texto);
444         } else {
445                 fact = fact_buscar(lst_facturas, atoi(s), &id, &id_texto);
446         }
447
448         if (fact == NULL) {
449                 wattron(win, COLOR_PAIR(COLOR_YELLOW));
450                 mvwaddstr(win, 2, 1, "No existe factura con ese código. Abortando!");
451                 wattroff(win, COLOR_PAIR(COLOR_YELLOW));
452                 wrefresh(win);
453                 getch();
454                 werase(win);
455                 wrefresh(win);
456                 delwin(win);
457                 return;
458         }
459
460         mvwaddch(win, 10, 0, ACS_LTEE);
461         mvwhline(win, 10, 1, ACS_HLINE, COLS-3);
462         mvwaddch(win, 10, COLS-3, ACS_RTEE);
463         wrefresh(win);
464
465         items = derwin(win, LINES-20, COLS-4, 15, 1);
466         nota = derwin(win, 9, COLS-62, 1, 56);
467         subnota = derwin(nota, 7, COLS-64, 1, 1);
468         box(nota, 0, 0);
469         mvwaddstr(nota, 0, 1, "Nota :");
470         wrefresh(nota);
471         wrefresh(items);
472
473         form = form_crear(win);
474         sprintf(tmp_str, "%08d", fact->numero);
475         form_agregar_widget(form, INPUT, "Numero de Factura", 8, tmp_str);
476         form_agregar_widget(form, INPUT, "Fecha Emision", 8, fact->emision);
477         form_agregar_widget(form, INPUT, "Fecha Vto", 8, fact->vencimiento);
478         sprintf(tmp_str, "%08d", fact->numero_remito);
479         form_agregar_widget(form, INPUT, "Nro Remito", 8, tmp_str);
480         form_agregar_widget(form, RADIO, "Estado", 6, "PN,CD,CM,SF,PM,NC");
481         form_agregar_widget(form, RADIO, "Forma de pago", 3, "CO,CR,CH");
482         sprintf(tmp_str, "%02.2f", fact->procdoi);
483         form_agregar_widget(form, INPUT, "%% Descuento", 5, tmp_str);
484         form_agregar_widget(form, INPUT, "Cuenta Cte", 5, fact->ctacte);
485         form_agregar_widget(form, INPUT, "Cheque Nro", 18, fact->cheque);
486
487         mvwaddstr(subnota, 0, 0, fact->nota);
488         wrefresh(subnota);
489         form_ejecutar(form, 1,1);
490
491         form_nota = form_crear(subnota);
492         form_agregar_widget(form_nota, INPUT, "", 255, fact->nota);
493         form_ejecutar(form_nota, 0, 0);
494
495         fact->numero = form_obtener_valor_int(form, "Numero de Factura");
496         strcpy(fact->emision, form_obtener_valor_char(form, "Fecha Emision"));
497         strcpy(fact->vencimiento, form_obtener_valor_char(form, "Fecha Vto"));
498         fact->numero_remito = form_obtener_valor_int(form, "Nro Remito");
499         strcpy(fact->estado, form_obtener_valor_char(form, "Estado"));
500         strcpy(fact->fp, form_obtener_valor_char(form, "Forma de pago"));
501         fact->procdoi = form_obtener_valor_float(form, "%% Descuento");
502         strcpy(fact->ctacte, form_obtener_valor_char(form, "Cuenta Cte"));
503         strcpy(fact->cheque, form_obtener_valor_char(form, "Cheque Nro"));
504
505         form_destruir(form);
506
507         free(fact->nota);
508         fact->nota = form_obtener_valor_char(form_nota, "");
509
510         form_destruir(form_nota);
511
512         entrada = procesar_guardar_factura(fact, lst_facturas, &size);
513         if (entrada) {
514                 CLAVE k;
515                 k = emufs_indice_generar_clave_desde_valor(lst_facturas->fp->indices, (char *)&fact->numero);
516                 lst_facturas->fp->modificar_registro(lst_facturas->fp, k, entrada, size, &error);
517                 k.i_clave = id_texto;
518                 id_texto = lst_facturas->fp_texto->modificar_registro(lst_facturas->fp_texto, k, fact->nota, strlen(fact->nota)+1, &error);
519                 free(entrada);
520         }
521
522         free(fact->items);
523         free(fact);
524
525         werase(win);
526         wrefresh(win);
527         delwin(subnota);
528         delwin(nota);
529         delwin(items);
530         delwin(win);
531 }
532
533 void fact_agregar(char *s)
534 {
535         WINDOW *win, *items, *nota, *subnota;
536         t_Form *form, *form_nota;
537         t_Item *its = NULL;
538         t_Factura fact;
539         EMUFS_REG_SIZE size;
540         EMUFS_REG_ID id_texto;
541         int y_actual, cant, error;
542         char *entrada;
543
544         win = newwin(LINES-4, COLS-2, 2, 1);
545         box(win, 0, 0);
546         mvwaddch(win, 10, 0, ACS_LTEE);
547         mvwhline(win, 10, 1, ACS_HLINE, COLS-3);
548         mvwaddch(win, 10, COLS-3, ACS_RTEE);
549         wrefresh(win);
550
551         items = derwin(win, LINES-20, COLS-4, 15, 1);
552         nota = derwin(win, 9, COLS-62, 1, 56);
553         subnota = derwin(nota, 7, COLS-64, 1, 1);
554         box(nota, 0, 0);
555         mvwaddstr(nota, 0, 1, "Nota :");
556         wrefresh(nota);
557         wrefresh(items);
558
559         form = form_crear(win);
560         form_agregar_widget(form, INPUT, "Numero de Factura", 8, "");
561         form_agregar_widget(form, INPUT, "Fecha Emision", 8, "");
562         form_agregar_widget(form, INPUT, "Fecha Vto", 8, "");
563         form_agregar_widget(form, INPUT, "Nro Remito", 8, "");
564         form_agregar_widget(form, RADIO, "Estado", 6, "PN,CD,CM,SF,PM,NC");
565         form_agregar_widget(form, RADIO, "Forma de pago", 3, "CO,CR,CH");
566         form_agregar_widget(form, INPUT, "%% Descuento", 5, "");
567         form_agregar_widget(form, INPUT, "Cuenta Cte", 5, "");
568         form_agregar_widget(form, INPUT, "Cheque Nro", 18, "");
569
570         form_ejecutar(form, 1,1);
571
572         form_nota = form_crear(subnota);
573         form_agregar_widget(form_nota, INPUT, "", 255, "");
574         form_ejecutar(form_nota, 0, 0);
575
576         /* XXX No destruir form_nota hasta el final !!!!! XXX */
577
578         fact.numero = form_obtener_valor_int(form, "Numero de Factura");
579         strcpy(fact.emision, form_obtener_valor_char(form, "Fecha Emision"));
580         strcpy(fact.vencimiento, form_obtener_valor_char(form, "Fecha Vto"));
581         fact.numero_remito = form_obtener_valor_int(form, "Nro Remito");
582         strcpy(fact.estado, form_obtener_valor_char(form, "Estado"));
583         strcpy(fact.fp, form_obtener_valor_char(form, "Forma de pago"));
584         fact.procdoi = form_obtener_valor_float(form, "%% Descuento");
585         strcpy(fact.ctacte, form_obtener_valor_char(form, "Cuenta Cte"));
586         strcpy(fact.cheque, form_obtener_valor_char(form, "Cheque Nro"));
587
588         form_destruir(form);
589
590         form = form_crear(win);
591         form_agregar_widget(form, INPUT, "Nro de Articulo (* == fin)", 8, "");
592         form_agregar_widget(form, INPUT, "CV", 8, "");
593         form_agregar_widget(form, INPUT, "PVU", 8, "");
594         y_actual = 0;
595         scrollok(items, 1);
596         mvwaddstr(win, 15, 2, "Numero");
597         mvwaddstr(win, 15, 11, "CV");
598         mvwaddstr(win, 15, 21, "PVU");
599         cant = 0;
600         do {
601                 form_set_valor(form, "Nro de Articulo (* == fin)", "");
602                 form_set_valor(form, "CV", "");
603                 form_set_valor(form, "PVU", "");
604                 form_ejecutar(form, 2, 11);
605
606                 entrada = form_obtener_valor_char(form, "Nro de Articulo (* == fin)");
607
608                 if ((entrada[0] != '\0') && (entrada[0] != '*')){
609                         y_actual++;
610                         if (y_actual > LINES-22) {
611                                 y_actual = LINES-22;
612                                 wscrl(items, 1);
613                         }
614                         mvwaddstr(items, y_actual, 1, entrada);
615                         mvwaddstr(items, y_actual, 10, form_obtener_valor_char(form, "CV"));
616                         mvwaddstr(items, y_actual, 20, form_obtener_valor_char(form, "PVU"));
617                         wrefresh(items);
618                         /* Agrego el Item */
619                         cant++;
620                         its = (t_Item *)realloc(its, cant*sizeof(t_Item));
621                         if (its != NULL) {
622                                 its[cant-1].numero = atoi(entrada);
623                                 strcpy(its[cant-1].cv, form_obtener_valor_char(form, "CV"));
624                                 strcpy(its[cant-1].pvu, form_obtener_valor_char(form, "PVU"));
625                         }
626                 }
627         } while (entrada[0] != '*');
628
629         if (lst_facturas->fp->tipo == T3) {
630                 if (cant != 10) {
631                         /* TODO Limitar en la GUI en lugar de truncar! */
632                         its = (t_Item *)realloc(its, 10*sizeof(t_Item));
633                         if (its == NULL) {
634                                 cant = 0;
635                         } else {
636                                 memset(its+sizeof(t_Item)*cant, 0, (10-cant)*sizeof(t_Item));
637                                 cant = 10;
638                         }
639                 }
640         }
641         fact.items = its;
642         fact.cant_items = cant;
643         fact.nota = form_obtener_valor_char(form_nota, "");
644
645         id_texto = lst_facturas->fp_texto->grabar_registro(lst_facturas->fp_texto, fact.nota, strlen(fact.nota)+1, &error);
646         fact.reg_nota = id_texto;
647
648         entrada = procesar_guardar_factura(&fact,lst_facturas, &size);
649         if (entrada) {
650                 error = 0;
651                 lst_facturas->fp->grabar_registro(lst_facturas->fp, entrada, size, &error);
652                 free(entrada);
653         }
654                                                                         
655         if (its) free(its);
656         form_destruir(form);
657         form_destruir(form_nota);
658
659         werase(win);
660         wrefresh(win);
661         delwin(items);
662         delwin(subnota);
663         delwin(nota);
664         delwin(win);
665 }
666
667 void *procesar_guardar_factura(t_Factura *f, t_LstFacturas *lst, EMUFS_REG_SIZE *size)
668 {
669         char *tmp=NULL;
670         int i[12];
671
672         switch (lst->fp->tipo) {
673                 case T1:
674                 case T2:
675                         /* Calculo el tamaño que voy a necesitar */
676                         i[0] = sizeof(int);
677                         i[1] = sizeof(float);
678                         i[2] = sizeof(int);
679                         i[3] = sizeof(int);
680                         i[4] = sizeof(EMUFS_BLOCK_ID);
681                         i[5] = sizeof(char)*(strlen(f->emision)+1); /* +1 por el \0 para separar */
682                         i[6] = sizeof(char)*(strlen(f->vencimiento)+1); /* +1 por el \0 para separar */
683                         i[7] = sizeof(char)*(strlen(f->estado)+1); /* +1 por el \0 para separar */
684                         i[8] = sizeof(char)*(strlen(f->fp)+1); /* +1 por el \0 para separar */
685                         i[9] = sizeof(char)*(strlen(f->ctacte)+1); /* +1 por el \0 para separar */
686                         i[10] = sizeof(char)*(strlen(f->cheque)+1); /* +1 por el \0 para separar */
687                         i[11] = sizeof(t_Item)*f->cant_items;
688                         (*size) = i[0]+i[1]+i[2]+i[3]+i[4]+i[5]+i[6]+i[7]+i[8]+i[9]+i[10]+i[11];
689                         tmp = (char *)malloc(*size);
690                         if (tmp == NULL) return NULL;
691                         memset(tmp, 0, *size);
692                         /* Ahora copio la info */
693                         memcpy(tmp, &f->numero, i[0]);
694                         memcpy(tmp+i[0], &f->procdoi, i[1]);
695                         memcpy(tmp+i[0]+i[1], &f->numero_remito, i[2]);
696                         memcpy(tmp+i[0]+i[1]+i[2], &f->cant_items, i[3]);
697                         memcpy(tmp+i[0]+i[1]+i[2]+i[3], &f->reg_nota, i[4]);
698                         memcpy(tmp+i[0]+i[1]+i[2]+i[3]+i[4], f->emision, i[5]);
699                         memcpy(tmp+i[0]+i[1]+i[2]+i[3]+i[4]+i[5], f->vencimiento, i[6]);
700                         memcpy(tmp+i[0]+i[1]+i[2]+i[3]+i[4]+i[5]+i[6], f->estado, i[7]);
701                         memcpy(tmp+i[0]+i[1]+i[2]+i[3]+i[4]+i[5]+i[6]+i[7], f->fp, i[8]);
702                         memcpy(tmp+i[0]+i[1]+i[2]+i[3]+i[4]+i[5]+i[6]+i[7]+i[8], f->ctacte, i[9]);
703                         memcpy(tmp+i[0]+i[1]+i[2]+i[3]+i[4]+i[5]+i[6]+i[7]+i[8]+i[9], f->cheque, i[10]);
704                         if (i[11] != 0)
705                                 memcpy(tmp+i[0]+i[1]+i[2]+i[3]+i[4]+i[5]+i[6]+i[7]+i[8]+i[9]+i[10], f->items, i[11]);
706                 break;
707                 case T3:
708                         (*size) = sizeof(t_Factura)-sizeof(char *)-sizeof(t_Item *) + f->cant_items*sizeof(t_Item);
709                         tmp = (char *)malloc(*size);
710                         if (tmp == NULL) return NULL;
711                         memcpy(tmp, f, sizeof(t_Factura)-sizeof(char *)-sizeof(t_Item *));
712                         memcpy(tmp+sizeof(t_Factura)-sizeof(char *)-sizeof(t_Item *), f->items, f->cant_items*sizeof(t_Item));
713         }
714         return tmp;
715 }
716
717 static int procesar_leer_factura(t_Factura *dst, void *src, EMUFS_REG_SIZE size, t_LstFacturas *lst)
718 {
719         char *ini, *fin;
720         /*int dummy;*/
721
722         if (lst == NULL) {
723                 PERR("Puntero a lista NULO");
724                 return 0;
725         }
726         if (lst->fp == NULL) {
727                 PERR("EMUFS No creado!");
728                 return 0;
729         }
730
731         switch (lst->fp->tipo) {
732                 case T1:
733                 case T2:
734                         ini = (char *)src;
735                         /* Copio los campos numericos, muy facil:-) */
736                         memcpy(&dst->numero, ini, sizeof(int));
737                         ini+=sizeof(int);
738                         
739                         memcpy(&dst->procdoi, ini, sizeof(float));
740                         ini+=sizeof(float);
741
742                         memcpy(&dst->numero_remito, ini, sizeof(int));
743                         ini+=sizeof(int);
744                         
745                         memcpy(&dst->cant_items, ini, sizeof(int));
746                         ini+=sizeof(int);
747                         
748                         memcpy(&dst->reg_nota, ini, sizeof(EMUFS_BLOCK_ID));
749                         ini+=sizeof(EMUFS_BLOCK_ID);
750
751                         /* Ahora empieza el juego */
752                         /* Los \0 son los delimitadores de campo! */
753                         fin = ini;
754                         while (*fin!='\0') fin++;
755                         memcpy(dst->emision, ini, fin-ini+1);
756                         
757                         ini = fin+1;
758                         fin = ini;
759                         while (*fin!='\0') fin++;
760                         memcpy(dst->vencimiento, ini, fin-ini+1);
761                         
762                         ini = fin+1;
763                         fin = ini;
764                         while (*fin!='\0') fin++;
765                         memcpy(dst->estado, ini, fin-ini+1);
766                         
767                         ini = fin+1;
768                         fin = ini;
769                         while (*fin!='\0') fin++;
770                         memcpy(dst->fp, ini, fin-ini+1);
771                         
772                         ini = fin+1;
773                         fin = ini;
774                         while (*fin!='\0') fin++;
775                         memcpy(dst->ctacte, ini, fin-ini+1);
776                         
777                         ini = fin+1;
778                         fin = ini;
779                         while (*fin!='\0') fin++;
780                         memcpy(dst->cheque, ini, fin-ini+1);
781
782                         if (dst->cant_items > 0) {
783                                 /* Ahora tengo que cargar los items */
784                                 dst->items = (t_Item *)malloc(sizeof(t_Item)*dst->cant_items);
785
786                                 ini = fin+1;
787                                 fin = (char *)src+size;
788                                 memcpy(dst->items, ini, fin-ini);
789
790                         } else {
791                                 dst->items = NULL;
792                         }
793                         /*dst->nota = lst->fp_texto->leer_registro(lst->fp_texto, dst->reg_nota, (EMUFS_REG_SIZE *)&dummy, &dummy);*/
794                         return 0;
795                 break;
796                 case T3:
797                         /* Se que tengo 10 items */
798                         /* TODO : Ver porque leer_registro_tipo3 tira mal el size */
799                         size = lst->fp->tam_reg;
800                         memcpy(dst, src, size-sizeof(t_Item)*10);
801                         dst->items = (t_Item *)malloc(10*sizeof(t_Item));
802                         memcpy(dst->items, src+size-sizeof(t_Item)*10, 10*sizeof(t_Item));
803                         /*dst->nota = lst->fp_texto->leer_registro(lst->fp_texto, dst->reg_nota, (EMUFS_REG_SIZE *)&dummy, &dummy);*/
804         }
805         return 0;
806 }
807
808 void fact_reformatear(int tipo, int tam_bloque, int tam_reg, int nota_tipo, int nota_tam_bloque, int nota_tam_registro)
809 {
810 #ifdef NO_ANDA_AUN
811         EMUFS *nuevo, *old;
812         EMUFS_REG_ID *indices, id;
813         EMUFS_REG_SIZE indices_total, i, size, tam_reg1;
814         t_Factura fact;
815         t_LstFacturas *lst_nueva;
816         int error;
817         char *save;
818
819         PERR("==== EMPIEZO ====\n");
820         old = lst_facturas->fp;
821
822         /* Creo el nuevo file */
823         PERR("Creo el archivo\n");
824         if (tipo == T3) {
825                 /* Me aseguro de que entren n items completos */
826                 tam_reg1 = sizeof(t_Factura)-sizeof(char *)-sizeof(t_Item*)+10*sizeof(t_Item);
827         }
828         nuevo = emufs_crear("emufs_tmp", tipo, tam_bloque, tam_reg1);
829         if (nuevo == NULL) {
830                 PERR("ARCHIVO NUEVO NO CREADO");
831                 return;
832         }
833
834         /* Creo la nueva lista */
835         lst_nueva = (t_LstFacturas *)malloc(sizeof(t_LstFacturas));
836         lst_nueva->primero = NULL;
837         lst_nueva->fp = nuevo;
838         lst_nueva->fp_texto = emufs_crear("nota_tmp", nota_tipo, nota_tam_bloque, nota_tam_registro);
839
840         /* Leo los indices del archivo viejo */
841         PERR("Obtengo Indices\n");
842         indices = emufs_idx_get(old, &indices_total);
843         if (indices == NULL) {
844                 fact_liberar(lst_nueva);
845                 return;
846         }
847
848         PERR("Proceso datos");
849         for(i=0; i<indices_total; i++) {
850                 error = 0;
851                 PERR("Leo");
852                 save = old->leer_registro(old, indices[i], &size, &error);
853                 if (procesar_leer_factura(&fact, save, size, lst_facturas) == 0) {
854                         PERR("Procese Leer Ok");
855                         free(save);
856                         /* Lei un registro Ok. Lo salvo en el archivo nuevo */
857
858                         /* Actualizo el ID de la nota asociada */
859                         fact.reg_nota = lst_nueva->fp_texto->grabar_registro(lst_nueva->fp_texto, fact.nota, strlen(fact.nota)+1, &error);
860                         save = procesar_guardar_factura(&fact, lst_nueva, &size);
861                         PERR("Procese Grabar Ok");
862                         if (save) {
863                                 error = 0;
864                                 PERR("Grabo el Registro");
865                                 id = nuevo->grabar_registro(nuevo, save, size, &error);
866                                 PERR("Lo agrego");
867                                 agregar_nodo_factura(lst_nueva, crear_nodo_factura(id, fact.reg_nota, fact.numero));
868                                 PERR("Libero Memoria");
869                                 free(save);
870                                 if (fact.items) free(fact.items);
871                                 if (fact.nota) free(fact.nota);
872                                 PERR("Termine con este Item");
873                         }
874                 }
875         }
876
877         free(indices);
878
879         PERR("Libero lo viejo\n");
880         fact_liberar(lst_facturas);
881
882         PERR("Ahora tengo lo nuevo\n");
883         lst_facturas = lst_nueva;
884
885         /* El nuevo tiene como nombre emufs_tmp, lo cambio a mano! */
886         free(lst_facturas->fp->nombre);
887         lst_facturas->fp->nombre = (char *)malloc(sizeof(char)*(strlen("facturas")+1));
888         strcpy(lst_facturas->fp->nombre, "facturas");
889         
890         /* Tambien actualizo el nombre para notas */
891         free(lst_facturas->fp_texto->nombre);
892         lst_facturas->fp_texto->nombre = (char *)malloc(sizeof(char)*(strlen("notas")+1));
893         strcpy(lst_facturas->fp_texto->nombre, "notas");
894         
895         /* Muevo los archivos! */
896         /* TODO : Poner en otro lugar mas generico! */
897         PERR("Renombre!!\n");
898         rename("emufs_tmp.dat", "facturas.dat");
899         rename("emufs_tmp.idx", "facturas.idx");
900         rename("emufs_tmp.fsc", "facturas.fsc");
901         rename("emufs_tmp.did", "facturas.did");
902         rename("nota_tmp.dat", "notas.dat");
903         rename("nota_tmp.idx", "notas.idx");
904         rename("nota_tmp.fsc", "notas.fsc");
905         rename("nota_tmp.did", "notas.did");
906         PERR("==== TERMINE ====\n");
907 #endif
908 }
909
910 int fact_exportar_xml(const char *filename)
911 {
912         int j;
913         t_Reg_Factura *nodo;
914         t_Factura *fact;
915         EMUFS_REG_ID id, id1;
916         FILE *fp;
917
918         if (lst_facturas->primero == NULL) return 0;
919
920         nodo = lst_facturas->primero;
921
922         if (!(fp = fopen(filename, "wt"))) return 0;
923         
924         fprintf(fp, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n");
925         fprintf(fp, "<FACTURAS>\n");
926         while (nodo) {
927                 fact = fact_buscar(lst_facturas, nodo->numero, &id, &id1);
928                 fprintf(fp, "\t<FACTURA NroFac=\"%08d\" ", nodo->numero);
929                 fprintf(fp, "FechaEmisión=\"%s\" ", fact->emision);
930                 fprintf(fp, "FechaVto=\"%s\" ", fact->vencimiento);
931                 fprintf(fp, "NroRemito=\"%08d\" ", fact->numero_remito);
932                 fprintf(fp, "FP=\"%s\" ", fact->fp);
933                 fprintf(fp, "Estado=\"%s\" ", fact->estado);
934                 fprintf(fp, "NroCheque=\"%s\" ", fact->cheque);
935                 fprintf(fp, "PorcDoI=\"%.2f\" ", fact->procdoi);
936                 fprintf(fp, "NroCtaCte=\"%s\" ", fact->ctacte);
937                 fprintf(fp, ">\n");
938                 fprintf(fp, "\t\t<NOTA>%s</NOTA>\n", fact->nota);
939                 for(j=0; j<fact->cant_items; j++) {
940                         if (fact->items[j].numero != 0)
941                                 fprintf(fp, "\t\t<ITEMVENTA NroArtículo=\"%08d\" CV=\"%s\" PVU=\"%s\" />\n", fact->items[j].numero, fact->items[j].cv, fact->items[j].pvu);
942                 }
943                 fprintf(fp, "\t</FACTURA>\n");
944                 nodo = nodo->sig;
945         }
946         fprintf(fp, "\t</FACTURAS>\n");
947
948         fclose(fp);
949         return 1;
950 }
951
952 char *get_estado(char *s)
953 {
954         if (strcmp(s, "PN")==0) return "Pago Normal";
955         if (strcmp(s, "CD")==0) return "Credito al dia";
956         if (strcmp(s, "CM")==0) return "Credito en mora";
957         if (strcmp(s, "SF")==0) return "Cheque sin fondos";
958         if (strcmp(s, "PM")==0) return "Pagada con Mora";
959         if (strcmp(s, "NC")==0) return "No Cobrada";
960
961         return s;
962 }
963
964 char *get_forma_pago(char *s)
965 {
966         if (strcmp(s, "CO") == 0) return "Contado";
967         if (strcmp(s, "CR") == 0) return "Credito";
968         if (strcmp(s, "CH") == 0) return "Cheque";
969
970         return s;
971 }
972
973 void fact_consultas_codigos(char *s)
974 {
975         EMUFS_REG_ID dummy;
976         int desde_codigo, hasta_codigo;
977         int i;
978         t_Factura *factura;
979         t_Lista *lista;
980         t_Form *form;
981         WINDOW *win, *win1;
982
983         win = newwin(LINES-4, COLS-2, 2, 1);
984         win1 = derwin(win, LINES-6, COLS-4, 1, 1);
985         werase(win);
986         box(win, 0, 0);
987         wrefresh(win);
988         
989         /* El usuario ingresa rango a listar */
990         form = form_crear(win1);
991         form_agregar_widget(form, INPUT, "Desde Codigo", 8, "0");
992         form_agregar_widget(form, INPUT, "Hasta Codigo", 8, "99999999");
993
994         form_ejecutar(form, 2, 2);
995
996         desde_codigo = form_obtener_valor_int(form, "Desde Codigo");
997         hasta_codigo = form_obtener_valor_int(form, "Hasta Codigo");
998
999         form_destruir(form);
1000         werase(win1);
1001         wrefresh(win1);
1002
1003         /* Creo la lista donde mostrar la consulta*/
1004         /* Muestro solo info relevante */
1005         lista = lista_crear(4, win1, COLS-4, LINES-6);
1006
1007         /* Creo las columnas */
1008         lista_agregar_columna(lista, DATO_INT, 0, 8);    /* numero     */
1009         lista_agregar_columna(lista, DATO_STR, 10, 9);   /* emision    */
1010         lista_agregar_columna(lista, DATO_STR, 20, 19);  /* estado     */
1011         lista_agregar_columna(lista, DATO_STR, 40, 9);   /* fp         */
1012
1013         /* Leo los datos desde el archivo */
1014         for(i=desde_codigo; i<=hasta_codigo; i++) {
1015                 factura = fact_buscar(lst_facturas, i, &dummy, &dummy);
1016                 if (factura != NULL) {
1017                         lista_agregar_fila(lista,
1018                                 factura->numero,
1019                                 factura->emision,
1020                                 get_estado(factura->estado),
1021                                 get_forma_pago(factura->fp)
1022                         );
1023                 }
1024         }
1025
1026         curs_set(0);
1027         lista_ejecutar(lista);
1028         curs_set(1);
1029         
1030         wrefresh(win1);
1031         wrefresh(win);
1032         werase(win1);
1033         werase(win);
1034         wrefresh(win);
1035         delwin(win);
1036 }
1037
1038 void fact_consultas_varias(char *nombre_indice, char *titulo)
1039 {
1040         int i, cant, error;
1041         char *desc, *tmp;
1042         t_Factura factura;
1043         t_Lista *lista;
1044         t_Form *form;
1045         INDICE_DATO *datos;
1046         WINDOW *win, *win1;
1047         CLAVE k;
1048         EMUFS *fs;
1049         EMUFS_REG_SIZE size;
1050
1051         fs = lst_facturas->fp;
1052
1053         win = newwin(LINES-4, COLS-2, 2, 1);
1054         win1 = derwin(win, LINES-6, COLS-4, 1, 1);
1055         werase(win);
1056         box(win, 0, 0);
1057         wrefresh(win);
1058         
1059         /* El usuario ingresa rango a listar */
1060         form = form_crear(win1);
1061         form_agregar_widget(form, INPUT, titulo, 50, "");
1062
1063         form_ejecutar(form, 2, 2);
1064
1065         tmp = form_obtener_valor_char(form, titulo);
1066         desc = malloc(sizeof(char)*(strlen(tmp)+1));
1067         strcpy(desc, tmp);
1068
1069         form_destruir(form);
1070         werase(win1);
1071         wrefresh(win1);
1072
1073         /* Creo la lista donde mostrar la consulta*/
1074         /* Muestro solo info relevante */
1075         lista = lista_crear(4, win1, COLS-4, LINES-6);
1076
1077         /* Creo las columnas */
1078         lista_agregar_columna(lista, DATO_INT, 0, 8);    /* numero     */
1079         lista_agregar_columna(lista, DATO_STR, 10, 9);   /* emision    */
1080         lista_agregar_columna(lista, DATO_STR, 20, 19);  /* estado     */
1081         lista_agregar_columna(lista, DATO_STR, 40, 9);   /* fp         */
1082
1083         /* Leo los datos desde el archivo */
1084         datos = emufs_buscar_registros(fs, nombre_indice, desc, &cant);
1085         for(i=0; i<cant; i++) {
1086                 k.i_clave = datos[i].id;
1087                 error = 1;
1088                 tmp = (char *)fs->leer_registro(fs, k, &size, &error);
1089                 if (tmp != NULL) {
1090                         procesar_leer_factura(&factura, tmp, size, lst_facturas);
1091                         lista_agregar_fila(lista,
1092                                                         factura.numero,
1093                                                         factura.emision,
1094                                                         get_estado(factura.estado),
1095                                                         get_forma_pago(factura.fp)
1096                                         );
1097                         free(tmp);
1098                 } else {
1099                         PERR("NO SE PUDO RECUPERAR EL REGISTRO DE DATOS");
1100                 }
1101         }
1102
1103         curs_set(0);
1104         lista_ejecutar(lista);
1105         curs_set(1);
1106         
1107         wrefresh(win1);
1108         wrefresh(win);
1109         werase(win1);
1110         werase(win);
1111         wrefresh(win);
1112         delwin(win);
1113 }
1114
1115 void fact_consultas(char *s)
1116 {
1117         MENU(mi_menu) {
1118                 MENU_OPCION("por Codigos", "Consulta de Articulos por rango de codigo."),
1119                 MENU_OPCION("por Fecha de Emision", "Consulta por fecha unica"),
1120                 MENU_OPCION("por Presentacion", "Consulta por Presentacion"),
1121                 MENU_OPCION("Volver", "Volver al menu anterior.")
1122         };
1123         int opt;
1124         
1125         while ((opt = menu_ejecutar(mi_menu, 4, "Consulta de Articulos")) != 3) {
1126                 switch (opt) {
1127                         case 0:
1128                                 fact_consultas_codigos(s);
1129                         break;
1130                         case 1:
1131                                 fact_consultas_varias("emision", "Fecha");
1132                         break;
1133                         case 2:
1134                                 fact_consultas_varias("presentacion", "Presentacion");
1135                 }
1136         }
1137 }
1138