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