]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs_gui/articulos.c
c042bfbe7c8843630b739441456c2e3eef59afa5
[z.facultad/75.06/emufs.git] / emufs_gui / articulos.c
1
2 #include "articulos.h"
3 #include "idx.h"
4 #include "gui.h"
5 #include "common.h"
6 #include "lista.h"
7 #include "menu.h"
8 #include "facturas.h"
9
10 static t_LstArticulos *lst_articulos;
11
12 static t_Articulo *art_form_buscar(WINDOW *win, EMUFS_REG_ID *id);
13
14 static void *procesar_guardar_articulo(t_Articulo *src, EMUFS_REG_SIZE *size, t_LstArticulos *lst);
15 static int procesar_leer_articulo(t_Articulo *dst, void *src, EMUFS_REG_SIZE size, t_LstArticulos *lst);
16
17 #ifdef TP_PRIMER_ENTREGA
18 /* Manejo de la lista doble */
19 static t_Reg_Articulo *crear_nodo_articulo(EMUFS_REG_ID reg, unsigned int num);
20 static int agregar_nodo_articulo(t_LstArticulos *lst, t_Reg_Articulo *nodo);
21 static int eliminar_nodo_articulo(t_LstArticulos *lst, t_Reg_Articulo *nodo);
22
23 int eliminar_nodo_articulo(t_LstArticulos *lst, t_Reg_Articulo *nodo)
24 {
25         if (nodo == NULL) return 0;
26         if (nodo->ant == NULL) {
27                 /* Me piden borrar el primer nodo */
28                 if (nodo->sig) {
29                         nodo->sig->ant = NULL;
30                 }
31                 lst->primero = nodo->sig;
32         } else {
33                 if (nodo->sig) {
34                         nodo->sig->ant = nodo->ant;
35                 }
36                 nodo->ant->sig = nodo->sig;
37         }
38         free(nodo);
39         return 1;
40 }
41
42 t_Reg_Articulo *crear_nodo_articulo(EMUFS_REG_ID reg, unsigned int num)
43 {
44         t_Reg_Articulo *tmp;
45         if (reg == EMUFS_NOT_FOUND) return NULL;
46         tmp = malloc(sizeof(t_Reg_Articulo));
47         if (tmp == NULL) return NULL;
48         tmp->sig = tmp->ant = NULL;
49         tmp->num_reg = reg;
50         tmp->numero = num;
51
52         return tmp;
53 }
54
55 int agregar_nodo_articulo(t_LstArticulos *lst, t_Reg_Articulo *nodo)
56 {
57         if (nodo == NULL) return 0;
58
59         if (lst->primero) {
60                 lst->primero->ant = nodo;
61                 nodo->sig = lst->primero;
62                 lst->primero = nodo;
63         } else {
64                 lst->primero = nodo;
65         }
66         return 1;
67 }
68 #endif /* TP_PRIMER_ENTREGA */
69
70 t_LstArticulos *art_get_lst()
71 {
72         return lst_articulos;
73 }
74
75 t_LstArticulos *art_cargar(t_Parametros *param)
76 {
77         xmlDocPtr document;
78         xmlNode *node, *inicio;
79         int error = 0;
80         char *prop;
81         EMUFS_REG_SIZE size;
82         t_LstArticulos *tmp;
83         t_Articulo *un_articulo;
84         lst_articulos = NULL;
85
86         tmp = (t_LstArticulos *)malloc(sizeof(t_LstArticulos));
87         if (tmp == NULL) return NULL;
88         lst_articulos = tmp;
89         tmp->primero = NULL;
90
91         if (param != NULL) {
92                 PERR("Voy a crear desde un XML");
93                 document = xmlReadFile(param->xml_art, "ISO-8859-1",0);
94                 if (document == NULL) {
95                         free(tmp);
96                         lst_articulos = NULL;
97                         return NULL;
98                 }
99
100                 inicio = NULL;
101                 node = xmlDocGetRootElement(document);
102                 /* Busco el TAG principal "ARTICULOS" */
103                 while (node) {
104                         if (node->type == XML_ELEMENT_NODE) {
105                                 if (strcmp(node->name, "ARTICULOS") == 0) {
106                                         inicio = node->children;
107                                         break;
108                                 }
109                         }
110                         node = node->next;
111                 }
112                 /* Creo el FS */
113                 tmp->fp = emufs_crear("articulos", param->tipo_arch_art, param->tam_bloque_art, sizeof(t_Articulo));
114                 /* Agrego los indices */
115                 PERR("Voy a agregar un indice");
116                 emufs_agregar_indice(tmp->fp, "presentacion", IND_EXAHUSTIVO, param->ind_art[2].tipo_arbol, IDX_STRING, STRUCT_OFFSET(un_articulo, desc), param->ind_art[2].tam_bloque, 1);
117                 emufs_agregar_indice(tmp->fp, "desc", IND_EXAHUSTIVO, param->ind_art[1].tipo_arbol, IDX_STRING, STRUCT_OFFSET(un_articulo, desc), param->ind_art[1].tam_bloque, 0);
118                 emufs_agregar_indice(tmp->fp, "codigo", IND_PRIMARIO, param->ind_art[0].tipo_arbol, IDX_INT, 0, param->ind_art[0].tam_bloque, 0);
119                 if (!tmp->fp) {
120                         PERR("NO SE PUDO CREAR ARCHIVO ARTICULOS");
121                         free(tmp);
122                         xmlFreeDoc(document);
123                         xmlCleanupParser();
124                         lst_articulos = NULL;
125                         return NULL;
126                 }
127                 for (node=inicio ; node ; node = node->next) {
128                         if (node->type == XML_ELEMENT_NODE) {
129                                 if (strcmp(node->name, "ARTICULO") == 0) {
130                                         t_Articulo art;
131                                         void *save;
132                                         memset(&art, 0, sizeof(t_Articulo));
133                                         prop = xml_get_prop(node, "NroArtículo");
134                                         art.numero = atoi(prop);
135                                         xmlFree(prop);
136                                         strncpy(art.desc, prop = xml_get_prop(node, "Descripción"), 50); xmlFree(prop);
137                                         art.desc[50] = '\0'; /* Me aseguro de que este */
138                                         strncpy(art.presentacion, prop = xml_get_prop(node, "Presentación"), 30); xmlFree(prop);
139                                         art.presentacion[30] = '\0'; /* Me aseguro de que este */
140                                         strncpy(art.existencia, prop = xml_get_prop(node, "Existencia"), 8); xmlFree(prop);
141                                         art.existencia[8] = '\0'; /* Me aseguro de que este */
142                                         strncpy(art.ubicacion, prop = xml_get_prop(node, "Ubicación"), 30); xmlFree(prop);
143                                         strncpy(art.pvu, prop = xml_get_prop(node, "PVU"), 8); xmlFree(prop);
144                                         art.pvu[8] = '\0'; /* Me aseguro de que este */
145                                         strncpy(art.emin, prop = xml_get_prop(node, "Emín"), 8); xmlFree(prop);
146                                         art.emin[8] = '\0'; /* Me aseguro de que este */
147                                         /* Ya leido el articulo ahora paso a guardarlo en el archivo y agregarlo a la lista */
148                                         save = procesar_guardar_articulo(&art, &size, lst_articulos);
149                                         if (save != NULL) {
150                                                 error = 0;
151                                                 tmp->fp->grabar_registro(tmp->fp, save, size, &error);
152                                                 free(save);
153                                         }
154                                 }
155                         }
156                 }
157                 xmlFreeDoc(document);
158                 xmlCleanupParser();
159         } else {
160 /*      XXX Ahora no necesito leer nada del archivo cuando lo cargo
161  *      pues tengo todo en los indices
162  *
163  *      PERR("Voy a recuperar desde un archivo");
164                 tmp->fp = emufs_abrir("articulos");
165                 if (tmp->fp == NULL) {
166                         PERR("No se pudo cargar archivo de articulos.");
167                         free(tmp);
168                         lst_articulos = NULL;
169                         return NULL;
170                 }
171                  Ahora trato de recuperar la info
172                 indices = emufs_idx_get(tmp->fp, &indices_cant);
173                 for(i=0; i<indices_cant; i++) {
174                         t_Articulo art;
175                         void *save;
176                          Leo el registro
177                         error = 0;
178                         save = tmp->fp->leer_registro(tmp->fp, indices[i], &size, &error);
179                         if (procesar_leer_articulo(&art, save, size, tmp) == 1) {
180                                 agregar_nodo_articulo(tmp, crear_nodo_articulo(indices[i], art.numero));
181                                 free(save);
182                         }
183                 }
184                 free(indices);
185 */
186         }
187
188         return tmp;
189 }
190
191 int art_liberar(t_LstArticulos *l)
192 {
193         t_Reg_Articulo *del;
194         if (l == NULL) l = lst_articulos;
195         if (l == NULL) return 1;
196
197         emufs_destruir(l->fp);
198         while (l->primero) {
199                 del = l->primero;
200                 l->primero = l->primero->sig;
201                 free(del);
202         }
203         free(l);
204
205         lst_articulos = NULL;
206         return 0;
207 }
208
209 t_Articulo *art_obtener(t_LstArticulos *lst, int numero, EMUFS_REG_ID *id)
210 {
211         t_Articulo *art;
212         void *tmp;
213         int error = 0;
214         EMUFS_REG_SIZE size;
215         CLAVE k;
216
217         if (lst == NULL) lst = lst_articulos;
218         if (lst == NULL) return NULL;
219
220         (*id) = -1; /* XXX Ver que se hacia con esto */
221         art = (t_Articulo *)malloc(sizeof(t_Articulo));
222         /* Ya se cual tengo que retornar. Ahora veo si lo cargo desde el archivo */
223         error = 0;
224         k = emufs_indice_generar_clave_desde_valor(lst->fp->indices, (char *)&numero);
225         tmp = lst->fp->leer_registro(lst->fp, k, &size, &error);
226         if (error) {
227                 free(art);
228                 return NULL;
229         }
230
231         if (procesar_leer_articulo(art, tmp, size, lst_articulos) != 1) {
232                 free(art);
233                 free(tmp);
234                 return NULL;
235         }
236
237         free(tmp);
238         return art;
239 }
240
241 t_Articulo *art_form_buscar(WINDOW *win, EMUFS_REG_ID *id)
242 {
243         t_Form *form;
244         t_Articulo *articulo;
245
246         form = form_crear(win);
247         form_agregar_widget(form, INPUT, "Numero de Artículo", 8, "");
248         form_ejecutar(form, 1,1);
249         articulo = art_obtener(NULL, form_obtener_valor_int(form, "Numero de Artículo"), id);
250         form_destruir(form);
251
252         return articulo;
253 }
254
255 void art_modificar(char *s)
256 {
257         WINDOW *win;
258         t_Form *form;
259         t_Articulo *articulo;
260         char num[11];
261         void *tmp;
262         int error;
263         EMUFS_REG_SIZE size;
264         EMUFS_REG_ID codigo;
265
266         win = newwin(9, COLS-2, 13, 1);
267         box(win, 0, 0);
268         wrefresh(win);
269
270         if (s == NULL) {
271                 PERR("Voy a buscar con el formulario");
272                 articulo = art_form_buscar(win, &codigo);
273                 PERR("Ya lo tengo!!!!!!");
274         } else {
275                 codigo = atoi(s);
276                 /* Leo el registro directamente */
277                 articulo = (t_Articulo *)malloc(sizeof(t_Articulo));
278                 /* Ya se cual tengo que retornar. Ahora veo si lo cargo desde el archivo */
279                 error = 0;
280                 tmp = lst_articulos->fp->leer_registro(lst_articulos->fp,
281                                                 emufs_indice_generar_clave_desde_valor(lst_articulos->fp->indices, (char *)&codigo), &size, &error);
282                 if (error) {
283                         free(articulo);
284                         articulo = NULL;
285                 } else {
286                         if (procesar_leer_articulo(articulo, tmp, size, lst_articulos) != 1) {
287                                 free(articulo);
288                                 articulo = NULL;
289                         }
290                         free(tmp);
291                 }
292         }
293
294         if (articulo != NULL) {
295                 form = form_crear(win);
296                 sprintf(num, "%08d", articulo->numero);
297                 form_agregar_widget(form, INPUT, "Numero de Artículo", 8, num);
298                 form_es_modificable(form, "Numero de Artículo" , 0);
299                 form_agregar_widget(form, INPUT, "Descripción", 50, articulo->desc);
300                 form_agregar_widget(form, INPUT, "Presentación", 30, articulo->presentacion);
301                 form_agregar_widget(form, INPUT, "Stock Actual", 8, articulo->existencia);
302                 form_agregar_widget(form, INPUT, "Ubicacion", 30, articulo->ubicacion);
303                 form_agregar_widget(form, INPUT, "PVU", 8, articulo->pvu);
304                 form_agregar_widget(form, INPUT, "Stock Mínimo", 8, articulo->emin);
305                 form_ejecutar(form, 1,1);
306
307                 /* Actualizar registro */
308                 articulo->numero = form_obtener_valor_int(form, "Numero de Artículo");
309                 strcpy(articulo->desc, form_obtener_valor_char(form, "Descripción"));
310                 strcpy(articulo->presentacion, form_obtener_valor_char(form, "Presentación"));
311                 strcpy(articulo->existencia, form_obtener_valor_char(form, "Stock Actual"));
312                 strcpy(articulo->ubicacion, form_obtener_valor_char(form, "Ubicacion"));
313                 strcpy(articulo->pvu, form_obtener_valor_char(form, "PVU"));
314                 strcpy(articulo->emin, form_obtener_valor_char(form, "Stock Mínimo"));
315                 /* Ya actualice los datos, ahora veo de grabarlos */
316                 tmp = procesar_guardar_articulo(articulo, &size, lst_articulos);
317                 if (tmp) {
318                         CLAVE k;
319                         INDICE_DATO dummy1;
320                         error = 0;
321                         k = emufs_indice_generar_clave_desde_valor(lst_articulos->fp->indices, (char *)&articulo->numero);
322                         /* dummy se pasa porque esto se hace por clave primaria, y el INDICE_DATO que se
323                          * pasa solo es requerido cuando son claves multiples
324                          */
325                         lst_articulos->fp->modificar_registro(lst_articulos->fp, k, tmp, size, &error, dummy1);
326                         free(tmp);
327                 }
328                 
329                 form_destruir(form);
330                 free(articulo);
331         } else {        
332                 wattron(win, COLOR_PAIR(COLOR_YELLOW));
333                 mvwaddstr(win, 6, 4, "No existe artículo con ese código. Abortando!");
334                 wattroff(win, COLOR_PAIR(COLOR_YELLOW));
335                 wrefresh(win);
336                 getch();
337         }
338         werase(win);
339         wrefresh(win);
340         delwin(win);
341 }
342
343 void art_eliminar(char *s)
344 {
345         WINDOW *win;
346         t_Articulo *articulo;
347         EMUFS_REG_ID id;
348         CLAVE k;
349
350         win = newwin(8, COLS-2, 13, 1);
351         box(win, 0, 0);
352         wrefresh(win);
353
354         articulo = art_form_buscar(win, &id);
355
356         if (articulo == NULL) {
357                 wattron(win, COLOR_PAIR(COLOR_YELLOW));
358                 mvwaddstr(win, 6, 4, "No existe artículo con ese código. Abortando!");
359                 wattroff(win, COLOR_PAIR(COLOR_YELLOW));
360                 wrefresh(win);
361                 getch();
362         } else {
363                 INDICE_DATO dummy;
364
365                 /* Antes de borrar veo si existe alguna factura que contenga este articulo */
366                 if (fact_hay_con_item(articulo->numero) == 0) {
367                         k = emufs_indice_generar_clave_desde_valor(lst_articulos->fp->indices, (char *)&(articulo->numero));
368                         PERR("Borrando ARTICULO")
369                         lst_articulos->fp->borrar_registro(lst_articulos->fp, k, dummy);
370                         PERR("LISTO BORRADO");
371                 } else {
372                         wattron(win, COLOR_PAIR(COLOR_YELLOW));
373                         mvwaddstr(win, 6, 4, "No se pudo eliminar Articulo porque hay una factura que lo referencia.");
374                         wattroff(win, COLOR_PAIR(COLOR_YELLOW));
375                         wrefresh(win);
376                         getch();
377                 }
378                 free(articulo);
379         }
380
381         werase(win);
382         wrefresh(win);
383         delwin(win);
384 }
385
386 void art_agregar(char *s)
387 {
388         WINDOW *win;
389         t_Form *form;
390         t_Articulo art;
391         void *save;
392         int error = 0, existe;
393         EMUFS_REG_SIZE size;
394         EMUFS_REG_ID id;
395         INDICE_DATO dato;
396         CLAVE k;
397
398         win = newwin(9, COLS-2, 13, 1);
399         box(win, 0, 0);
400         wrefresh(win);
401
402         form = form_crear(win);
403         form_agregar_widget(form, INPUT, "Numero de Artículo", 8, "");
404         form_agregar_widget(form, INPUT, "Descripción", 50, "");
405         form_agregar_widget(form, INPUT, "Presentación", 30, "");
406         form_agregar_widget(form, INPUT, "Stock Actual", 8, "");
407         form_agregar_widget(form, INPUT, "Ubicacion", 30, "");
408         form_agregar_widget(form, INPUT, "PVU", 8, "");
409         form_agregar_widget(form, INPUT, "Stock Mínimo", 8, "");
410         form_ejecutar(form, 1,1);
411         
412         art.numero = atoi(form_obtener_valor_char(form, "Numero de Artículo"));
413         existe = 0;
414         /* Me dijo que no existe el codigo */
415         k = emufs_indice_generar_clave_desde_valor(lst_articulos->fp->indices, (char *)&art.numero);
416         dato = lst_articulos->fp->indices->existe_entrada(lst_articulos->fp->indices, k);
417         if (dato.id != -1) existe = 1;
418
419         if (!existe) {
420                 strcpy(art.desc, form_obtener_valor_char(form, "Descripción"));
421                 strcpy(art.presentacion, form_obtener_valor_char(form, "Presentación"));
422                 strcpy(art.existencia, form_obtener_valor_char(form, "Stock Actual"));
423                 strcpy(art.ubicacion, form_obtener_valor_char(form, "Ubicacion"));
424                 strcpy(art.pvu, form_obtener_valor_char(form, "PVU"));
425                 strcpy(art.emin, form_obtener_valor_char(form, "Stock Mínimo"));
426
427                 /* Ya leido el articulo ahora paso a guardarlo en el archivo y agregarlo a la lista */
428                 save = procesar_guardar_articulo(&art, &size, lst_articulos);
429                 if (save != NULL) {
430                         error = 0;
431                         id = lst_articulos->fp->grabar_registro(lst_articulos->fp, save, size, &error);
432                         if (error) {
433                                 wattron(win, COLOR_PAIR(COLOR_YELLOW));
434                                 mvwaddstr(win, 6, 4, "Error al tratar de agregar el nuevo registro");
435                                 wattroff(win, COLOR_PAIR(COLOR_YELLOW));
436                                 wrefresh(win);
437                                 getch();
438                         }
439                         free(save);
440                 }
441         } else {
442                 wattron(win, COLOR_PAIR(COLOR_YELLOW));
443                 mvwaddstr(win, 7, 1, "El código ya existe!. Abortando.");
444                 wattroff(win, COLOR_PAIR(COLOR_YELLOW));
445                 wrefresh(win);
446                 getch();
447         }
448         form_destruir(form);
449
450         werase(win);
451         wrefresh(win);
452         delwin(win);
453 }
454
455 int procesar_leer_articulo(t_Articulo *dst, void *src, EMUFS_REG_SIZE size, t_LstArticulos *lst)
456 {
457         char *fin, *ini;
458         switch (lst->fp->tipo) {
459                 case T1:
460                 case T4:
461                 case T2:
462                         ini = (char *)src;
463                         /* Copio el primer campo, esto es facil :-) */
464                         memset(dst, 0, sizeof(t_Articulo));
465                         memcpy(&dst->numero, ini, sizeof(unsigned int));
466                         ini+=sizeof(unsigned int);
467                         /* Ahora empieza el juego */
468                         /* Los \0 son los delimitadores de campo! */
469                         fin = ini;
470                         while (*fin!='\0') fin++;
471                         memcpy(dst->desc, ini, fin-ini+1);
472                         
473                         ini = fin+1;
474                         fin = ini;
475                         while (*fin!='\0') fin++;
476                         memcpy(dst->presentacion, ini, fin-ini+1);
477                         
478                         ini = fin+1;
479                         fin = ini;
480                         while (*fin!='\0') fin++;
481                         memcpy(dst->existencia, ini, fin-ini+1);
482                         
483                         ini = fin+1;
484                         fin = ini;
485                         while (*fin!='\0') fin++;
486                         memcpy(dst->ubicacion, ini, fin-ini+1);
487                         
488                         ini = fin+1;
489                         fin = ini;
490                         while (*fin!='\0') fin++;
491                         memcpy(dst->pvu, ini, fin-ini+1);
492                         
493                         ini = fin+1;
494                         fin = (char *)src+size;
495                         memcpy(dst->emin, ini, fin-ini);
496
497                         break;
498                 case T5:
499                 case T3:
500                         memcpy(dst, src, sizeof(t_Articulo));
501         }
502
503         return 1; /* Todo ok */
504 }
505
506 void *procesar_guardar_articulo(t_Articulo *src, EMUFS_REG_SIZE *size, t_LstArticulos *lst)
507 {
508         char *tmp=NULL;
509         int i[7];
510         char *from = (char *)src;
511         switch(lst->fp->tipo) {
512                 case T1:
513                 case T2:
514                 case T4:
515                         /* Calculo el tamaño que voy a necesitar */
516                         i[0] = sizeof(unsigned int);
517                         i[1] = sizeof(char)*(strlen(src->desc)+1);
518                         i[2] = sizeof(char)*(strlen(src->presentacion)+1);
519                         i[3] = sizeof(char)*(strlen(src->existencia)+1);
520                         i[4] = sizeof(char)*(strlen(src->ubicacion)+1); 
521                         i[5] = sizeof(char)*(strlen(src->pvu)+1);
522                         i[6] = sizeof(char)*(strlen(src->emin)+1);
523                         (*size) = i[0]+i[1]+i[2]+i[3]+i[4]+i[5]+i[6];
524                         tmp = (char *)malloc((*size));
525                         if (tmp == NULL) return NULL;
526                         memset(tmp, 0, *size);
527                         memcpy(tmp, &src->numero, i[0]);
528                         memcpy(tmp+i[0], src->desc, i[1]);
529                         memcpy(tmp+i[0]+i[1], src->presentacion, i[2]);
530                         memcpy(tmp+i[0]+i[1]+i[2], src->existencia, i[3]);
531                         memcpy(tmp+i[0]+i[1]+i[2]+i[3], src->ubicacion, i[4]);
532                         memcpy(tmp+i[0]+i[1]+i[2]+i[3]+i[4], src->pvu, i[5]);
533                         memcpy(tmp+i[0]+i[1]+i[2]+i[3]+i[4]+i[5], src->emin, i[6]);
534                 break;
535                 case T5:
536                 case T3:
537                         /* Lleno el lugar no ocupado de los strings con *, para que el ver
538                          * registro se vea bien 
539                          */
540                         tmp = (char *)malloc(sizeof(t_Articulo));
541                         memset(tmp, '*', sizeof(t_Articulo));
542                         memcpy(tmp, from, sizeof(t_Articulo));
543                         (*size) = sizeof(t_Articulo);
544         }
545         return tmp;
546 }
547
548 void art_reformatear(int tipo, int tam_bloque, int tam_reg)
549 {
550 #ifdef NO_SE_PUEDE_USAR
551         EMUFS *nuevo, *old;
552         EMUFS_REG_ID *indices, id;
553         EMUFS_REG_SIZE indices_total, i, size;
554         t_Articulo art;
555         t_LstArticulos *lst_nueva;
556         int error;
557         char *save;
558
559         PERR("==== EMPIEZO ====\n");
560         old = lst_articulos->fp;
561
562         /* Creo el nuevo file */
563         PERR("Creo el archivo\n");
564         nuevo = emufs_crear("emufs_tmp", tipo, tam_bloque, sizeof(t_Articulo));
565         if (nuevo == NULL) {
566                 PERR("ARCHIVO NUEVO NO CREADO");
567                 return;
568         }
569
570         /* Creo la nueva lista */
571         lst_nueva = (t_LstArticulos *)malloc(sizeof(t_LstArticulos));
572         lst_nueva->primero = NULL;
573         lst_nueva->fp = nuevo;
574
575         /* Leo los indices del archivo viejo */
576         PERR("Obtengo Indices\n");
577         indices = emufs_idx_get(old, &indices_total);
578         if (indices == NULL) {
579                 art_liberar(lst_nueva);
580                 return;
581         }
582
583         PERR("Proceso datos\n");
584         for(i=0; i<indices_total; i++) {
585                 error = 0;
586                 save = old->leer_registro(old, indices[i], &size, &error);
587                 if (procesar_leer_articulo(&art, save, size, lst_articulos) == 1) {
588                         free(save);
589                         /* Lei un registro Ok. Lo salvo en el archivo nuevo */
590                         save = procesar_guardar_articulo(&art, &size, lst_nueva);
591                         if (save) {
592                                 error = 0;
593                                 id = nuevo->grabar_registro(nuevo, save, size, &error);
594                                 agregar_nodo_articulo(lst_nueva, crear_nodo_articulo(id, art.numero));
595                                 free(save);
596                         }
597                 }
598         }
599
600         free(indices);
601
602         PERR("Libero lo viejo\n");
603         art_liberar(lst_articulos);
604
605         PERR("Ahora tengo lo nuevo\n");
606         lst_articulos = lst_nueva;
607
608         /* El nuevo tiene como nombre emufs_tmp, lo cambio a mano! */
609         free(lst_articulos->fp->nombre);
610         lst_articulos->fp->nombre = (char *)malloc(sizeof(char)*(strlen("articulos")+1));
611         strcpy(lst_articulos->fp->nombre, "articulos");
612         
613         /* Muevo los archivos! */
614         /* TODO : Poner en otro lugar mas generico! */
615         PERR("Renombre!!\n");
616         rename("emufs_tmp.dat", "articulos.dat");
617         rename("emufs_tmp.idx", "articulos.idx");
618         rename("emufs_tmp.fsc", "articulos.fsc");
619         rename("emufs_tmp.did", "articulos.did");
620         PERR("==== TERMINE ====\n");
621 #endif
622 }
623
624 int art_exportar_xml(const char *filename)
625 {
626         t_Articulo *art;
627         EMUFS_REG_ID id;
628         FILE *fp;
629         CLAVE k;
630         INDICE *idx;
631
632         idx = lst_articulos->fp->indices;
633
634         k = idx->obtener_menor_clave(idx);
635
636         if (!(fp = fopen(filename, "wt"))) return 0;
637         
638         fprintf(fp, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n\n");
639         fprintf(fp, "<ARTICULOS>\n");
640         while (k.i_clave != -1) {
641                 art = art_obtener(lst_articulos, k.i_clave, &id);
642                 if (art != NULL) {
643                         fprintf(fp, "\t<ARTICULO ");
644                         fprintf(fp, "NroArtículo=\"%d\" ", art->numero);
645                         fprintf(fp, "Descripción=\"%s\" ", art->desc);
646                         fprintf(fp, "Presentación=\"%s\" ", art->presentacion);
647                         fprintf(fp, "Ubicación=\"%s\" ", art->ubicacion);
648                         fprintf(fp, "Existencia=\"%s\" ", art->existencia);
649                         fprintf(fp, "PVU=\"%s\" ", art->pvu);
650                         fprintf(fp, "Emín=\"%s\" />\n", art->emin);
651                         free(art);
652                 }
653                 k = idx->obtener_sig_clave(idx, k);
654         }
655         fprintf(fp, "</ARTICULOS>\n");
656
657         fclose(fp);
658         return 1;
659 }
660
661 /* Dejo el test para que no se pierda */
662 void art_consultas_old(char *s)
663 {
664         /* TEST DE LISTA! */
665         char txt[80];
666         int i;
667         t_Lista *lista;
668         WINDOW *win, *win1;
669
670         win = newwin(LINES-4, COLS-2, 2, 1);
671         win1 = derwin(win, LINES-6, COLS-4, 1, 1);
672         werase(win);
673         box(win, 0, 0);
674         wrefresh(win);
675         
676         /* Creo la lista */
677         lista = lista_crear(3, win1, COLS-4, LINES-6);
678
679         /* Creo las columnas */
680         lista_agregar_columna(lista, "Col1", DATO_INT, 0, 8);
681         lista_agregar_columna(lista, "Col2", DATO_STR, 10, 45);
682         lista_agregar_columna(lista, "Col3", DATO_FLOAT, 60, 10);
683
684         /* Agrego unos datos a ver que pasa */
685         /* Pongo 100 y rezo */
686         for(i=0; i<100; i++) {
687                 sprintf(txt, "Texto del item %d", i);
688                 lista_agregar_fila(lista, i, txt, (rand()%100)/100.0f);
689         }
690         curs_set(0);
691         lista_ejecutar(lista);
692         curs_set(1);
693         wrefresh(win1);
694         wrefresh(win);
695         werase(win1);
696         werase(win);
697         wrefresh(win);
698         delwin(win);
699 }
700
701 void art_consultas_codigos(char *s, t_Lista *lista)
702 {
703         EMUFS_REG_ID dummy;
704         int desde_codigo, hasta_codigo;
705         CLAVE k, menor, mayor;
706         t_Articulo *articulo;
707         t_Form *form;
708         INDICE *idx;
709
710         idx = lst_articulos->fp->indices;
711
712         /* El usuario ingresa rango a listar */
713         form = form_crear(lista->win);
714         form_agregar_widget(form, INPUT, "Desde Codigo", 8, "0");
715         form_agregar_widget(form, INPUT, "Hasta Codigo", 8, "99999999");
716
717         form_ejecutar(form, 2, 2);
718
719         desde_codigo = form_obtener_valor_int(form, "Desde Codigo");
720         hasta_codigo = form_obtener_valor_int(form, "Hasta Codigo");
721
722         form_destruir(form);
723         werase(lista->win);
724         wrefresh(lista->win);
725
726         /* Leo los datos desde el archivo */
727         k = emufs_indice_generar_clave_desde_valor(idx, (char *)&desde_codigo);
728
729         menor = idx->obtener_menor_clave(idx);
730         mayor = idx->obtener_mayor_clave(idx);
731
732         if (k.i_clave < menor.i_clave)
733                 k = menor;
734         if (k.i_clave > mayor.i_clave)
735                 hasta_codigo = mayor.i_clave;
736         fprintf(stderr, "k.i_clave = %d  -- hasta_codigo = %d\n", k.i_clave, hasta_codigo);
737         while ((k.i_clave != -1) && (k.i_clave <= hasta_codigo)) {
738                 PERR("BUSCO ARTICULO");
739                 articulo = art_obtener(lst_articulos, k.i_clave, &dummy);
740                 PERR("LO TENGO");
741                 if (articulo != NULL) {
742                         PERR("AGREGO A LA LISTA");
743                         fprintf(stderr, "%d - %s\n", articulo->numero, articulo->desc);
744                         lista_agregar_fila(lista,
745                                                                 articulo->numero,
746                                                                 articulo->desc,
747                                                                 articulo->existencia,
748                                                                 articulo->emin
749                                                 );
750                         free(articulo);
751                 }
752                 PERR("OBTENGO SIGUIENTE CLAVE");
753                 k = idx->obtener_sig_clave(idx, k); 
754                 fprintf(stderr, "k.i_clave = %d  -- hasta_codigo = %d\n", k.i_clave, hasta_codigo);
755         }
756
757         curs_set(0);
758         lista_ejecutar(lista);
759         curs_set(1);
760 }
761
762 void art_consultas_stock(char *s, t_Lista *lista)
763 {
764         CLAVE k, menor;
765         t_Articulo articulo;
766         t_Form *form;
767         INDICE *idx;
768         float por;
769
770         idx = emufs_buscar_indice_por_nombre(lst_articulos->fp, "desc");
771         if (idx == NULL) PERR("NO SE ENCUENTRA INDICE DESC!!!");
772
773         /* El usuario ingresa rango a listar */
774         form = form_crear(lista->win);
775         form_agregar_widget(form, INPUT, "Ingrese %", 8, "0");
776
777         form_ejecutar(form, 2, 2);
778
779         por = form_obtener_valor_float(form, "Ingrese %");
780
781         form_destruir(form);
782         werase(lista->win);
783         wrefresh(lista->win);
784
785         menor = idx->obtener_menor_clave(idx);
786
787         k = menor;
788         while (k.i_clave != -1) {
789                 char *tmp;
790                 EMUFS_REG_SIZE size;
791                 int error, cant, i;
792                 INDICE_DATO *datos;
793                 CLAVE k1;
794                 datos = idx->buscar_entradas(idx, k, &cant);
795                 for(i=0; i<cant; i++) {
796                         error = 1;
797                         k1.i_clave = datos[i].id;
798                         tmp = lst_articulos->fp->leer_registro(lst_articulos->fp, k1, &size, &error);
799
800                         if (tmp != NULL) {
801                                 procesar_leer_articulo(&articulo, tmp, size, lst_articulos);
802                         
803                                 if (atof(articulo.existencia) <= (1.0f+por)*atof(articulo.emin)) {
804                                         lista_agregar_fila(lista,
805                                                 articulo.numero,
806                                                 articulo.desc,
807                                                 articulo.existencia,
808                                                 articulo.emin
809                                         );
810                                 }
811                                 free(tmp);
812                         }
813                 }
814                 if (datos) free(datos);
815                 k = idx->obtener_sig_clave(idx, k); 
816         }
817
818         curs_set(0);
819         lista_ejecutar(lista);
820         curs_set(1);
821 }
822
823 void art_consultas_cambiar_precio(char *s, t_Lista *lista)
824 {
825         CLAVE k, menor;
826         t_Articulo articulo;
827         t_Form *form;
828         INDICE *idx;
829         float por, pvu;
830         char desc[51], uno_solo;
831
832         idx = emufs_buscar_indice_por_nombre(lst_articulos->fp, "desc");
833         if (idx == NULL) PERR("NO SE ENCUENTRA INDICE DESC!!!");
834
835         /* El usuario ingresa rango a listar */
836         form = form_crear(lista->win);
837         form_agregar_widget(form, INPUT, "Desc. Articulo (nulo==Todos)", 50, "");
838         form_agregar_widget(form, INPUT, "Ingrese %", 8, "0");
839
840         werase(lista->win);
841         wrefresh(lista->win);
842         form_ejecutar(form, 2, 2);
843
844         por = form_obtener_valor_float(form, "Ingrese %");
845         strcpy(desc, form_obtener_valor_char(form, "Desc. Articulo (nulo==Todos)"));
846
847         form_destruir(form);
848         werase(lista->win);
849         wrefresh(lista->win);
850
851         uno_solo = 1;
852         if (strlen(desc) == 0) {
853                 uno_solo = 0;
854                 k = menor = idx->obtener_menor_clave(idx);
855         } else {
856                 k.i_clave = 1;
857         }
858
859         while (k.i_clave != -1) {
860                 char *tmp;
861                 EMUFS_REG_SIZE size;
862                 int error, cant, i;
863                 INDICE_DATO *datos;
864                 CLAVE k1;
865                 if (uno_solo == 0)
866                         datos = idx->buscar_entradas(idx, k, &cant);
867                 else
868                         datos = emufs_buscar_registros(lst_articulos->fp, "desc", desc, &cant);
869                 fprintf(stderr, "obtuve %d claves para %s\n", cant, desc);
870                 for(i=0; i<cant; i++) {
871                         error = 1;
872                         k1.i_clave = datos[i].id;
873                         tmp = lst_articulos->fp->leer_registro(lst_articulos->fp, k1, &size, &error);
874
875                         if (tmp != NULL) {
876                                 procesar_leer_articulo(&articulo, tmp, size, lst_articulos);
877                                 free(tmp);
878                         
879                                 /* XXX */
880                                 pvu = atof(articulo.pvu);
881                                 pvu += pvu*por;
882
883                                 sprintf(articulo.pvu, "%.2f", pvu);
884                                 tmp = procesar_guardar_articulo(&articulo, &size, lst_articulos);
885                                 error = 0;
886                                 /* README : Aca si tengo que pasar el INDICE_DATO correcto, para que la funcion
887                                  * borrar sea capaz de eliminar solo el item que corresponde en las
888                                  * claves con repeticion
889                                  */
890                                 PERR("=== MODIFICANDO ===");
891                                 fprintf(stderr, "Desc=%s , PVU=%s, Codigo=%d\n", articulo.desc, articulo.pvu, articulo.numero);
892                                 lst_articulos->fp->modificar_registro(lst_articulos->fp, k1, tmp, size, &error, datos[i]);
893                                 PERR("===     FIN     ===");
894                         }
895                 }
896                 if (datos) free(datos);
897                 if (uno_solo == 0)
898                         k = idx->obtener_sig_clave(idx, k); 
899                 else
900                         k.i_clave = -1;
901         }
902 }
903
904 void art_consultas_varias(char *nombre_indice, char *titulo, t_Lista *lista)
905 {
906         int i, cant, error;
907         char desc[51], *tmp;
908         t_Articulo articulo;
909         t_Form *form;
910         INDICE_DATO *datos;
911         CLAVE k;
912         EMUFS *fs;
913         EMUFS_REG_SIZE size;
914
915         fs = lst_articulos->fp;
916
917         /* El usuario ingresa rango a listar */
918         form = form_crear(lista->win);
919         form_agregar_widget(form, INPUT, titulo, 50, "");
920
921         werase(lista->win);
922         form_ejecutar(form, 2, 2);
923
924         tmp = form_obtener_valor_char(form, titulo);
925         strcpy(desc, tmp);
926
927         form_destruir(form);
928         werase(lista->win);
929         wrefresh(lista->win);
930
931         /* Leo los datos desde el archivo */
932         datos = emufs_buscar_registros(fs, nombre_indice, desc, &cant);
933         for(i=0; i<cant; i++) {
934                 k.i_clave = datos[i].id;
935                 error = 1;
936                 tmp = (char *)fs->leer_registro(fs, k, &size, &error);
937                 if (tmp != NULL) {
938                         procesar_leer_articulo(&articulo, tmp, size, lst_articulos);
939                         lista_agregar_fila(lista,
940                                                         articulo.numero,
941                                                         articulo.desc,
942                                                         articulo.existencia,
943                                                         articulo.emin
944                                         );
945                         free(tmp);
946                 } else {
947                         PERR("NO SE PUDO RECUPERAR EL REGISTRO DE DATOS");
948                 }
949         }
950         if (datos) free(datos);
951         curs_set(0);
952         lista_ejecutar(lista);
953         curs_set(1);
954         
955 }
956
957 void art_consultas(char *s)
958 {
959         t_Lista *lista;
960         WINDOW *win1, *win;
961         MENU(mi_menu) {
962                 MENU_OPCION("por Codigos", "Consulta de Articulos por rango de codigo."),
963                 MENU_OPCION("por Descripcion", "Consulta por descripcion"),
964                 MENU_OPCION("por Presentacion", "Consulta por Presentacion"),
965                 MENU_OPCION("por Sock Faltante", "Consulta de articulos por stock"),
966                 MENU_OPCION("Modificar Precios", "Permite Modificar los PVU"),
967                 MENU_OPCION("Volver", "Volver al menu anterior.")
968         };
969         int opt;
970         
971         win = newwin(LINES-4, COLS-2, 2, 1);
972         win1 = derwin(win, LINES-6, COLS-4, 1, 1);
973         werase(win);
974         box(win, 0, 0);
975         wrefresh(win);
976         
977         /* Creo la lista donde mostrar la consulta*/
978         /* Muestro solo info relevante */
979         lista = lista_crear(4, win1, COLS-4, LINES-6);
980
981         /* Creo las columnas */
982         lista_agregar_columna(lista, "Numero", DATO_INT, 0, 8);    /* numero     */
983         lista_agregar_columna(lista, "Descripcion", DATO_STR, 10, 51);  /* desc       */
984         lista_agregar_columna(lista, "Existencia", DATO_STR, 55, 9);   /* existencia */
985         lista_agregar_columna(lista, "S. Minimo", DATO_STR, 66, 9);   /* enim       */
986
987         while ((opt = menu_ejecutar(mi_menu, 6, "Consulta de Articulos")) != 5) {
988                 switch (opt) {
989                         case 0:
990                                 art_consultas_codigos(s, lista);
991                         break;
992                         case 1:
993                                 art_consultas_varias("desc", "Descripcion", lista);
994                         break;
995                         case 2:
996                                 art_consultas_varias("presentacion", "Presentacion", lista);
997                         break;
998                         case 3:
999                                 art_consultas_stock(s, lista);
1000                         break;
1001                         case 4:
1002                                 art_consultas_cambiar_precio(s, lista);
1003                 }
1004                 lista_clear(lista);
1005                 werase(win1);
1006                 werase(win);
1007                 wrefresh(win1);
1008                 box(win, 0, 0);
1009                 wrefresh(win);
1010         }
1011         werase(win1);
1012         werase(win);
1013         wrefresh(win);
1014         delwin(win);
1015 }
1016
1017
1018 void imprimir(WINDOW *win, int y, int x, char *s, char *b)
1019 {
1020         wmove(win, y, x);
1021         waddstr(win, s);
1022         waddstr(win, b);
1023 }
1024
1025 void mostrar_art(WINDOW *win, CLAVE k, char *s, INDICE *idx)
1026 {
1027         t_Articulo *art;
1028         EMUFS_REG_ID dummy;
1029         int y = 3;
1030         char numero[10];
1031         /* XXX SOLO PARA CODIGO XXX */
1032         
1033         wattron(win, COLOR_PAIR(COLOR_RED));
1034         mvwaddstr(win, 1, 5, "Recorriendo Articulos por indice ");
1035         waddstr(win, s);
1036         wattroff(win, COLOR_PAIR(COLOR_RED));
1037
1038         wattron(win, A_BOLD);
1039         mvwaddstr(win, 18, 5, "Teclas:");
1040         wattroff(win, A_BOLD);
1041         mvwaddstr(win, 19, 5, " L = Siguiente");
1042         mvwaddstr(win, 20, 5, " K = Anterior");
1043
1044         if (strcmp(s, "codigo") == 0) {
1045                 art = art_obtener(lst_articulos, k.i_clave, &dummy);
1046         } else {
1047                 INDICE_DATO *datos;
1048                 EMUFS_REG_SIZE size;
1049                 int cant, error;
1050                 char *tmp;
1051
1052                 art = (t_Articulo *)malloc(sizeof(t_Articulo));
1053                 /* Ya se cual tengo que retornar. Ahora veo si lo cargo desde el archivo */
1054                 PERR("Busco todos los datos que tengan esta clave");
1055                 datos = idx->buscar_entradas(idx, k, &cant);
1056                 if (datos == NULL) {
1057                         free(art);
1058                         art = NULL;
1059                 } else {
1060                         fprintf(stderr, "Tengo %d datos\n", cant);
1061                         error = 1;
1062                         k.i_clave = datos[0].id;
1063                         PERR("Leo el primer dato");
1064                         tmp = lst_articulos->fp->leer_registro(lst_articulos->fp, k, &size, &error);
1065                         if (tmp == NULL) {
1066                                 free(art);
1067                                 art = NULL;
1068                         } else {
1069                                 if (procesar_leer_articulo(art, tmp, size, lst_articulos) != 1) {
1070                                         free(art);
1071                                         free(tmp);
1072                                         art = NULL;
1073                                 }
1074                         }
1075                         free(datos);
1076                 }
1077         }
1078
1079         
1080         if (art != NULL) {
1081                 sprintf(numero, "%08d", art->numero);
1082
1083                 imprimir(win, y++, 5, "Numero      : ", numero);
1084                 imprimir(win, y++, 5, "Descripcion : ", art->desc);
1085                 imprimir(win, y++, 5, "Presentacion: ", art->presentacion);
1086                 imprimir(win, y++, 5, "Existencia  : ", art->existencia);
1087                 imprimir(win, y++, 5, "Ubicacion   : ", art->ubicacion);
1088                 imprimir(win, y++, 5, "P. Unitario : ", art->pvu);
1089                 imprimir(win, y++, 5, "Stock Minimo: ", art->emin);
1090                 
1091                 free(art);
1092         } else {
1093                 PERR("NO EXISTE EL ARTICULO");
1094         }
1095         
1096 }
1097
1098 void art_recorrer_con_indice(char *s)
1099 {
1100         WINDOW *win, *win1;
1101         INDICE *idx;
1102         CLAVE stack[1000]; /* shhhh */
1103         CLAVE k;
1104         int stack_pos=0, c;
1105                 
1106         PERR("Busco indice");
1107         idx = emufs_buscar_indice_por_nombre(lst_articulos->fp, s);
1108
1109         win = newwin(LINES-4, COLS-2, 2, 1);
1110         win1 = derwin(win, LINES-6, COLS-4, 1, 1);
1111         werase(win);
1112         box(win, 0, 0);
1113         wrefresh(win);
1114
1115         PERR("Obtengo clave menor");
1116         k = idx->obtener_menor_clave(idx);
1117         
1118         PERR("Muestro el primer elemento");
1119
1120
1121         mostrar_art(win1, k, s, idx);
1122         wrefresh(win1);
1123         PERR("Sigue el usuario");
1124         curs_set(0);
1125         stack[0] = k;
1126         while ((c=wgetch(win)) != 13) {
1127                 switch (c) {
1128                         case 'L':
1129                         case 'l':
1130                                 stack[stack_pos++] = k; /* Guardo la clave para poder volver */
1131                                 k = idx->obtener_sig_clave(idx, k);
1132                                 /* TODO Verificar que no me pase del fin */
1133                                 break;
1134                         case 'K':
1135                         case 'k':
1136                                 /* recupero la anterior */
1137                                 stack_pos--;
1138                                 if (stack_pos < 0) stack_pos = 0;
1139                                 k = stack[stack_pos];
1140                                 break;
1141                         default:
1142                                 continue;
1143                 }
1144                 werase(win1);
1145                 mostrar_art(win1, k, s, idx);
1146                 wrefresh(win1);
1147         }
1148         curs_set(1);
1149
1150         werase(win1);
1151         werase(win);
1152         wrefresh(win);
1153         delwin(win);
1154 }
1155
1156 void art_recorrer()
1157 {
1158         char *ind[3] = {"codigo", "desc", "presentacion"};
1159         MENU(mi_menu) {
1160                 MENU_OPCION("Codigos", "Recorrer por Indice Codigo"),
1161                 MENU_OPCION("Descripcion", "Recorrer por Indice Descripcionn"),
1162                 MENU_OPCION("Presentacion", "Recorrer por Indice Presentacion"),
1163                 MENU_OPCION("Volver", "Volver al menu anterior.")
1164         };
1165         int opt;
1166         while ((opt = menu_ejecutar(mi_menu, 4, "Recorrer Articulos")) != 3) {
1167                 art_recorrer_con_indice(ind[opt]);
1168         }
1169 }
1170