PageRenderTime 57ms CodeModel.GetById 18ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 0ms

/src/caja.c

#
C | 847 lines | 476 code | 140 blank | 231 comment | 63 complexity | b9dd486fae621de57fea52b1b1e57610 MD5 | raw file
Possible License(s): GPL-2.0
  1/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4;
  2   c-indentation-style: gnu -*- */
  3/*caja.c
  4 *
  5 *    Copyright (C) 2004,2008 Rizoma Tecnologia Limitada <info@rizoma.cl>
  6 *
  7 *    This file is part of rizoma.
  8 *
  9 *    Rizoma is free software; you can redistribute it and/or modify
 10 *    it under the terms of the GNU General Public License as published by
 11 *    the Free Software Foundation; either version 2 of the License, or
 12 *    (at your option) any later version.
 13 *
 14 *    This program is distributed in the hope that it will be useful,
 15 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 *    GNU General Public License for more details.
 18 *
 19 *    You should have received a copy of the GNU General Public License
 20 *    along with this program; if not, write to the Free Software
 21 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 */
 23
 24#include<gtk/gtk.h>
 25#include<stdlib.h>
 26#include<string.h>
 27#include"tipos.h"
 28
 29#include"postgres-functions.h"
 30
 31#include"config_file.h"
 32#include"errors.h"
 33#include"caja.h"
 34#include"utils.h"
 35#include"vale.h"
 36
 37
 38
 39GtkWidget *calendar_win;
 40guint day, month, year;
 41
 42GtkWidget *inicio_caja;
 43GtkWidget *ventas_efect;
 44GtkWidget *ventas_doc;
 45GtkWidget *pago_ventas;
 46GtkWidget *otros_ingresos;
 47GtkWidget *total_haberes;
 48
 49GtkWidget *pagos;
 50GtkWidget *retiros;
 51GtkWidget *gastos_corrientes;
 52GtkWidget *otros_egresos;
 53GtkWidget *total_debitos;
 54
 55GtkWidget *total_caja;
 56
 57GtkWidget *combo_egreso;
 58GtkWidget *combo_ingreso;
 59
 60/* FLAGS */
 61gboolean con_cierre; //Indica si se realiza un ingreso o egreso de caja con cierre
 62
 63
 64/**
 65 * Es llamada por la funcion EgresarDinero.
 66 *
 67 * Esta funcion retorna el valor de inicio de la caja
 68 *
 69 * @return caja: entero que contiene el resultado de la consulta a la caja
 70 *
 71 */
 72
 73gint
 74ReturnSaldoCaja (void)
 75{
 76  PGresult *res;
 77  gint caja;
 78
 79  res = EjecutarSQL ("select * from get_arqueo_caja(-1)");
 80
 81  if (res != NULL && PQntuples (res) > 0)
 82    caja = atoi (PQgetvalue(res, 0, 0));
 83  else
 84    caja = 0;
 85
 86  return caja;
 87}
 88
 89/**
 90 * Es llamada por la funcion IngresarDinero.
 91 *
 92 * Esta funcion cierra la ventana "wnd_caja_ingreso" y limpia la caja de
 93 * texto "entry_caja_in_amount"
 94 *
 95 */
 96
 97void
 98CloseVentanaIngreso(void)
 99{
100  GtkWidget *wid;
101
102  wid = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_in_amount"));
103  gtk_entry_set_text(GTK_ENTRY(wid), "");
104
105  wid = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_caja_ingreso"));
106  gtk_widget_hide(wid);
107
108 if (con_cierre == TRUE)
109   {
110     con_cierre = FALSE;
111   }
112}
113
114/**
115 * Es llamada cuando el boton "btn_ingresarDinero" es presionado (signal click).
116 *
117 * Esta funcion carga el valor desde la caja de texto "entry_caja_in_amount"
118 * en monto  y luego llama a la funcion Ingreso, que realiza el ingreso de
119 * dinero y su motivo, finalemente llama a la funcion CloseVentanaIngreso
120 * para cerrar la ventana.
121 *
122 * @param button the button
123 * @param user_data the user data
124 *
125 */
126
127void
128IngresarDinero (GtkWidget *widget, gpointer data)
129{
130  GtkWidget *aux_widget;
131  GtkTreeModel *model;
132  GtkTreeIter iter;
133  gint monto;
134  gint motivo;
135  gchar *motivo_texto;
136
137  /*De estar habilitada caja, se asegura que ésta se encuentre 
138    abierta al momento de vender*/
139  
140  if (rizoma_get_value_boolean ("CAJA"))
141    if (check_caja()) // Se abre la caja en caso de que está cerrada
142      open_caja (TRUE);
143
144  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "cmb_caja_in_motiv"));
145  model = gtk_combo_box_get_model(GTK_COMBO_BOX(aux_widget));
146  if (!(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(aux_widget), &iter)))
147    {
148      ErrorMSG(aux_widget, "Debe seleccionar un tipo de ingreso");
149      return;
150    }
151
152  gtk_tree_model_get (model, &iter,
153                      0, &motivo,
154		      1, &motivo_texto,
155                      -1);
156
157  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_in_amount"));
158  monto = atoi(gtk_entry_get_text(GTK_ENTRY(aux_widget)));
159
160  if (monto == 0)
161    {
162      ErrorMSG (data, "No pueden haber ingresos de $0");
163      return;
164    }
165
166  if (Ingreso (monto, motivo, user_data->user_id))
167    {            
168      print_cash_box_info (get_last_cash_box_id (), monto, 0, motivo_texto);
169
170      if (con_cierre == TRUE)
171	{
172	  if (CerrarCaja(ReturnSaldoCaja()))
173	    {
174	      con_cierre = FALSE;
175	      gtk_widget_show_all (GTK_WIDGET (builder_get (builder, "dialog_cash_box_closed")));
176	    }
177	  else
178	    ErrorMSG (aux_widget, "No se pudo cerrar la caja apropiadamente\nPor favor intente nuevamente");
179	}
180
181      CloseVentanaIngreso ();
182    }
183  else
184    {
185      ErrorMSG(aux_widget, "No fue posible registrar el ingreso de dinero en la caja");
186      return;
187    }
188}
189
190/**
191 * Es llamada por la funcion "IniciarLaCaja".
192 *
193 * Esta funcion visualiza la ventana "wnd_caja_ingreso" y  carga en la lista
194 * desplegable(combobox) los motivos del ingreso de dinero a la caja, 
195 *
196 * @param monto: entero que contiene el monto de inicio de la caja
197 *
198 */
199
200void
201VentanaIngreso (gint monto)
202{
203  GtkWidget *aux_widget;
204  PGresult *res;
205  gint tuples, i;
206  GtkListStore *store;
207  GtkTreeIter iter;
208
209  res = EjecutarSQL ("SELECT id, descrip FROM tipo_ingreso");
210  tuples = PQntuples (res);
211
212  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "cmb_caja_in_motiv"));
213  store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(aux_widget)));
214
215  if (store == NULL)
216    {
217      GtkCellRenderer *cell;
218      store = gtk_list_store_new (2,
219                                  G_TYPE_INT,
220                                  G_TYPE_STRING);
221
222      gtk_combo_box_set_model(GTK_COMBO_BOX(aux_widget), GTK_TREE_MODEL(store));
223
224      cell = gtk_cell_renderer_text_new();
225      gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(aux_widget), cell, TRUE);
226      gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(aux_widget), cell,
227                                     "text", 1,
228                                     NULL);
229    }
230
231  gtk_list_store_clear(store);
232
233  for (i=0 ; i < tuples ; i++)
234    {
235      gtk_list_store_append(store, &iter);
236      gtk_list_store_set(store, &iter,
237                         0, atoi(PQvaluebycol(res, i, "id")),
238                         1, PQvaluebycol(res, i, "descrip"),
239                         -1);
240    }
241
242  gtk_combo_box_set_active (GTK_COMBO_BOX(aux_widget), 0);
243  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_in_amount"));
244  gtk_entry_set_text(GTK_ENTRY(aux_widget), g_strdup_printf("%d", monto));
245  gtk_widget_grab_focus(aux_widget);
246
247  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_caja_ingreso"));
248  gtk_widget_show_all(aux_widget);
249}
250
251/**
252 * Es llamada cuando el boton "btn_egresar_dinero" es presionado 
253 * (signal click).
254 *
255 * Esta funcion carga el monto que de egreso y luego a llama a la funcion
256 * Egreso que realiza el egreso y el motivo
257 *
258 * @param button the button
259 * @param user_data the user data
260 *
261 */
262void
263EgresarDinero (GtkWidget *widget, gpointer data)
264{
265  GtkWidget *aux_widget;
266  gint active;
267  gint monto;
268  gint motivo;
269  gint saldo_en_caja;
270  gchar *motivo_texto;
271
272  GtkTreeModel *model;
273  GtkTreeIter iter;
274  
275  /*Saldo en caja*/
276  saldo_en_caja = ReturnSaldoCaja ();
277
278  /*De estar habilitada caja, se asegura que ésta se encuentre 
279    abierta al momento de vender*/
280  
281  if (rizoma_get_value_boolean ("CAJA"))
282    if (check_caja()) // Se abre la caja en caso de que está cerrada
283      open_caja (TRUE);
284
285  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_out_amount"));
286  monto = atoi (gtk_entry_get_text (GTK_ENTRY (aux_widget)));
287
288  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "cmb_caja_out_motiv"));
289  active = gtk_combo_box_get_active (GTK_COMBO_BOX (aux_widget));
290
291  if (active == -1)
292    ErrorMSG (aux_widget, "Debe seleccionar un tipo de egreso");
293  else if (monto <= 0)
294    ErrorMSG (aux_widget, "No pueden haber egresos de monto $0 o menor");
295  else if (monto > saldo_en_caja)
296    ErrorMSG (aux_widget, "No se puede retirar más dinero del que hay en caja");
297  else
298    {
299      model = gtk_combo_box_get_model (GTK_COMBO_BOX (aux_widget));
300      gtk_combo_box_get_active_iter (GTK_COMBO_BOX (aux_widget), &iter);
301
302      gtk_tree_model_get (model, &iter,
303                          0, &motivo,
304			  1, &motivo_texto,
305                          -1);
306
307      if (Egresar (monto, motivo, user_data->user_id))
308	{	  	  
309	  print_cash_box_info (get_last_cash_box_id (), 0, monto, motivo_texto);
310
311	  if (con_cierre == TRUE)
312	    {
313	      if (CerrarCaja(ReturnSaldoCaja()))
314		{
315		  con_cierre = FALSE;
316		  gtk_widget_show_all (GTK_WIDGET (builder_get (builder, "dialog_cash_box_closed")));
317		}
318	      else
319		ErrorMSG (aux_widget, "No se pudo cerrar la caja apropiadamente\nPor favor intente nuevamente");
320	    }
321
322	  CloseVentanaEgreso();
323	}
324      else
325        ErrorMSG(aux_widget, "No fue posible ingresar el egreso de dinero de la caja");
326    }
327}
328
329/**
330 * Es llamada por la funcion EgresarDinero.
331 *
332 * Esta funcion cierra la ventana "wnd_caja_egreso" y limpia la caja de
333 * texto "entry_caja_out_amount"
334 *
335 */
336
337void
338CloseVentanaEgreso (void)
339{
340  GtkWidget *wid;
341
342  wid = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_out_amount"));
343  gtk_entry_set_text(GTK_ENTRY(wid), "");
344
345  wid = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_caja_egreso"));
346  gtk_widget_hide(wid);
347
348  if (con_cierre == TRUE)
349   {
350     con_cierre = FALSE;
351   }
352}
353
354
355/**
356 * Es llamada por la funcion "IniciarLaCaja".
357 *
358 * Esta funcion visualiza la ventana "wnd_caja_egreso" y  carga en la lista
359 * desplegable(combobox) los motivos del ingreso de dinero a la caja, 
360 *
361 * @param monto: entero que contiene el monto de inicio de la caja
362 *
363 */
364void
365VentanaEgreso (gint monto)
366{
367  GtkWidget *combo;
368  GtkWidget *aux_widget;
369  GtkListStore *store;
370  GtkTreeIter iter;
371  PGresult *res, *resId;
372  gint tuples, i;
373  gint nulVenId; // El Id de "Nulidad de venta" 
374
375  res = EjecutarSQL ("SELECT id, descrip FROM tipo_egreso");
376  tuples = PQntuples (res);
377
378  combo = GTK_WIDGET (gtk_builder_get_object(builder, "cmb_caja_out_motiv"));
379  store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo)));
380
381  if (store == NULL)
382    {
383      GtkCellRenderer *cell;
384      store = gtk_list_store_new(2,
385                                 G_TYPE_INT,
386                                 G_TYPE_STRING);
387
388      gtk_combo_box_set_model(GTK_COMBO_BOX(combo),GTK_TREE_MODEL(store));
389
390      cell = gtk_cell_renderer_text_new();
391      gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(combo), cell, TRUE);
392      gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), cell,
393                                     "text", 1,
394                                     NULL);
395    }
396
397  gtk_list_store_clear(store);
398  
399  /*Obtención del Id de 'nulidad de venta' */
400  resId = EjecutarSQL ("SELECT id FROM tipo_egreso WHERE descrip='Nulidad de Venta'");
401  nulVenId = atoi (PUT(PQvaluebycol(resId, 0, "id")));
402
403  /*Poblamiento del combobox*/
404  for (i = 0; i < tuples; i++)
405    {
406      if (atoi (PUT(PQvaluebycol(res, i, "id"))) != nulVenId) /*No queremos que el motivo "Nulidad de Venta" aparezca como opción*/ 
407	{
408	  gtk_list_store_append(store, &iter);
409	  gtk_list_store_set(store, &iter,
410			     0, atoi(PQvaluebycol(res, i, "id")),
411			     1, PQvaluebycol(res, i, "descrip"),
412			     -1);
413	}
414    }
415
416  gtk_combo_box_set_active (GTK_COMBO_BOX(combo), 0);
417  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_out_amount"));
418  gtk_entry_set_text(GTK_ENTRY(aux_widget), g_strdup_printf("%d", monto));
419  gtk_widget_grab_focus(aux_widget);
420
421  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_caja_egreso"));
422  gtk_widget_show_all(aux_widget);
423}
424
425/**
426 * Es llamada por las funciones "IniciarLaCaja" y "open_caja"
427 *
428 * Esta funcion insertar los valores iniciales de la caja
429 * (id_vendedor,fecha_inicio, inicio(monto))
430 *
431 * @return TRUE si se realizo correctamented, FALSE si fallo.
432 *
433 */
434
435gboolean
436InicializarCaja (gint monto)
437{
438  PGresult *res;
439  gchar *q;
440
441  q = g_strdup_printf ("INSERT INTO caja (id_vendedor, fecha_inicio, inicio) "
442                       "VALUES(%d, NOW(), %d)", user_data->user_id, monto);
443  res = EjecutarSQL (q);
444  g_free (q);
445
446  if (res != NULL)
447    return TRUE;
448  else
449    return FALSE;
450}
451
452/**
453 * Es llamada por la funcion "CerrarCajaWin"
454 *
455 * Esta funcion retorna el valor de inicio de la caja
456 *
457 * @return monto de la consulta, -1 si fallo
458 *
459 */
460gint
461ArqueoCaja (void)
462{
463  PGresult *res;
464
465  res = EjecutarSQL("select * from get_arqueo_caja (-1)");
466
467  if ((res != NULL) && (PQntuples(res)>0))
468    return atoi (PQgetvalue (res, 0, 0));
469  else
470    return -1;
471}
472
473/**
474 * Es llamada por la funcion "CerrarLaCaja"
475 *
476 * Esta funcion actualiza la caja para insertar los valores de cierre de la caja
477 * (fecha_termino, termino(monto))
478 *
479 * @param monto entero que contiene el dinero de cierre la caja
480 * @return TRUE si se realizo correctamented, FALSE si fallo.
481 *
482 */
483
484gboolean
485CerrarCaja (gint monto)
486{
487  PGresult *res;
488  gchar *q;
489
490  if (monto == -1)
491    monto = ArqueoCaja ();
492
493  q = g_strdup_printf ("UPDATE caja SET fecha_termino=NOW(), termino=%d "
494                       "WHERE id=(SELECT last_value FROM caja_id_seq)",
495                       monto);
496  res = EjecutarSQL (q);
497  g_free (q);
498
499  if (res != NULL || PQntuples (res) == 0)
500    return TRUE;
501  else
502    return FALSE;
503}
504
505/**
506 * Esta funcion es llamda por "prepare_caja"
507 *
508 * Retornamos TRUE si la caja fue cerrada anteriormente y debemos
509 * inicilizarla otra vez de lo contrario FALSE lo cual significa que
510 * la caja no se a cerrado
511 *
512 * @return TRUE when the caja was closed previously
513 */
514gboolean
515check_caja (void)
516{
517  PGresult *res;
518
519  res = EjecutarSQL ("select is_caja_abierta()");
520
521  if (PQntuples (res) == 0)
522    {
523      g_printerr("%s: could not retrieve the result of the sql query\n",
524                 G_STRFUNC);
525      return FALSE;
526    }
527
528  if (g_str_equal(PQgetvalue(res, 0, 0), "t"))
529    return FALSE;
530  else
531    return TRUE;
532}
533
534/**
535 * Closes the dialog that close the caja
536 */
537void
538CloseCajaWin (void)
539{
540  GtkWidget *widget;
541
542  widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_caja_close"));
543  gtk_widget_hide (widget);
544}
545
546/**
547 * Esta funcion es llamada por "open_caja 
548 * Raise the initialization caja dialog
549 *
550 * @param proposed_amount the amount that must be entered in the entry
551 */
552void
553InicializarCajaWin (gint proposed_amount)
554{
555  GtkWidget *widget;
556
557  widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_init_amount"));
558  gtk_entry_set_text(GTK_ENTRY(widget), g_strdup_printf("%d", proposed_amount));
559  gtk_widget_grab_focus(widget);
560
561  widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_caja_init"));
562  gtk_widget_show_all (widget);
563}
564
565/**
566 * Esta Funcion es llamda por "open_caja"
567 *
568 * Callback connected to accept button of the initialize caja dialog
569 *
570 * @param widget the widget that emited the signal
571 * @param data the user data
572 */
573void
574IniciarLaCaja (GtkWidget *widget, gpointer data)
575{
576  GtkWidget *aux_widget;
577  gint inicio;
578  gint monto;
579
580  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_init_amount"));
581  monto = atoi (gtk_entry_get_text (GTK_ENTRY (aux_widget)));
582
583  inicio = caja_get_last_amount();
584
585  CloseCajaWin ();
586
587  InicializarCaja (inicio);
588
589  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_caja_init"));
590  gtk_widget_hide (aux_widget);
591
592  if (inicio < monto)
593    VentanaIngreso (monto - inicio);
594  else if (inicio > monto)
595    VentanaEgreso (inicio - monto);
596}
597
598
599/**
600 * Es llamada por la funcion "on_btn_cash_box_close_clicked"
601 *
602 * Raise the close caja dialog
603 *
604 */
605void
606CerrarCajaWin (void)
607{
608  GtkWidget *widget;
609  gint amount_must_have;
610  gint monto_base_caja;
611  gint egreso_cierre;
612  gint proxima_apertura;
613
614  monto_base_caja = rizoma_get_value_int ("MONTO_BASE_CAJA");
615  amount_must_have = ArqueoCaja();
616
617  if (amount_must_have > monto_base_caja)
618    egreso_cierre = amount_must_have - monto_base_caja;
619  else
620    egreso_cierre = 0;
621
622  proxima_apertura = (egreso_cierre == 0) ? amount_must_have : monto_base_caja;
623
624  /*Se setean los labels con la información correspondiente*/
625
626  /*Monto que debería haber en caja*/
627  widget = GTK_WIDGET (builder_get (builder, "lbl_caja_close_must_have"));
628  gtk_label_set_markup (GTK_LABEL (widget), 
629			g_strdup_printf ("<b>$ %s</b>", PutPoints (g_strdup_printf ("%d", amount_must_have))));
630  g_object_set_data(G_OBJECT (widget), "must-have", (gpointer)amount_must_have);
631  
632  /*Monto que se retirará de caja*/
633  widget = GTK_WIDGET (builder_get (builder, "lbl_cash_out"));
634  gtk_label_set_markup (GTK_LABEL (widget), 
635			g_strdup_printf ("<b>$ %s</b>", PutPoints (g_strdup_printf ("%d", egreso_cierre))));
636
637  /*Monto con el cual se iniciará la siguiente caja*/
638  widget = GTK_WIDGET (builder_get (builder, "lbl_initial_cash"));
639  gtk_label_set_markup (GTK_LABEL (widget), 
640			g_strdup_printf ("<b>$ %s</b>", PutPoints (g_strdup_printf ("%d", proxima_apertura))));
641
642
643  /*Diferencia de caja - se calcula dependiendo de lo que se ingrese en el siguiente widget*/
644  widget = GTK_WIDGET (gtk_builder_get_object(builder, "lbl_caja_close_lost"));
645  gtk_label_set_text(GTK_LABEL(widget), "");
646  gtk_widget_hide (widget);
647
648  /*Monto con el que se cierra caja*/
649  widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_close_have"));
650  gtk_entry_set_max_length (GTK_ENTRY(widget), 9);
651  gtk_entry_set_text(GTK_ENTRY(widget), g_strdup_printf("%d", amount_must_have));
652  gtk_editable_select_region (GTK_EDITABLE(widget), 0, -1);
653  gtk_widget_grab_focus(widget);
654  gtk_widget_hide (widget);
655
656  widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_close_amount"));
657  gtk_entry_set_text(GTK_ENTRY(widget), g_strdup_printf("%d", amount_must_have));
658  gtk_widget_hide (widget);
659
660  /*Se ocultas los widgets restantes*/
661  widget = GTK_WIDGET (builder_get (builder, "label59"));
662  gtk_widget_hide (widget);
663
664  widget = GTK_WIDGET (builder_get (builder, "label60"));
665  gtk_widget_hide (widget);
666
667  widget = GTK_WIDGET (builder_get (builder, "label62"));
668  gtk_widget_hide (widget);
669
670  widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_caja_close"));
671  gtk_widget_show (widget);
672}
673
674/**
675 * Callback associated to the accept button of close caja dialog
676 *
677 * @param widget the widget that emited the signal
678 * @param data the user data
679 */
680void
681CerrarLaCaja (GtkWidget *widget, gpointer data)
682{
683  GtkWidget *aux_widget;
684  gint must_have;
685  //gint real_have;
686  //gint end_amount;
687  gint monto_base_caja=rizoma_get_value_int ("MONTO_BASE_CAJA");
688  gint motivo;
689
690  //Lo que deberia tener
691  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "lbl_caja_close_must_have"));
692  must_have = (gint)g_object_get_data(G_OBJECT(aux_widget), "must-have");
693
694  //Lo que realmente tiene
695  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_close_have"));
696  //real_have = atoi(gtk_entry_get_text(GTK_ENTRY(aux_widget)));
697
698  //El monto de cierre (Lo que realmente tiene pero filtrado)
699  aux_widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_close_amount"));
700  //end_amount = atoi(gtk_entry_get_text(GTK_ENTRY(aux_widget)));
701
702  /*(En los casos donde hay más o menos dinero, se debe preguntar el motivo)*/  
703  /* if (end_amount < must_have) //Si hay menos dinero del que debería */
704  /*   { */
705  /*     con_cierre = TRUE; //FLAG */
706  /*     CloseCajaWin (); */
707  /*     VentanaEgreso(must_have - end_amount); */
708  /*   }    */
709  /* else if (end_amount > must_have) //Si hay más dinero del que debería */
710  /*   { */
711  /*     con_cierre = TRUE; //FLAG */
712  /*     CloseCajaWin (); */
713  /*     VentanaIngreso (end_amount - must_have); */
714  /*   } */
715  /* else if (end_amount == must_have) //Si está el dinero que debería */
716  /*   { */
717
718  motivo = atoi (PQvaluebycol (EjecutarSQL ("SELECT id FROM tipo_egreso WHERE descrip='Retiro por cierre'"), 0, "id"));
719  if (must_have > monto_base_caja)
720    //Se deja en caja el monto base
721    Egresar (must_have-monto_base_caja, motivo, user_data->user_id);
722
723  if (CerrarCaja(ReturnSaldoCaja()))
724    {      
725      CloseCajaWin ();
726      /*aux_widget = GTK_WIDGET (gtk_builder_get_object (builder, "quit_message"));
727	gtk_dialog_response (GTK_DIALOG(aux_widget), GTK_RESPONSE_YES);*/
728      print_cash_box_info (get_last_cash_box_id (), 0, 0, NULL);
729      gtk_widget_show_all (GTK_WIDGET (builder_get (builder, "dialog_cash_box_closed")));
730    }
731  else
732    ErrorMSG (aux_widget, "No se pudo cerrar la caja apropiadamente\nPor favor intente nuevamente");
733  //}
734}
735
736/**
737 * prepares the software to open the caja based in the in the user
738 * that is running the software.
739 *
740 */
741void
742prepare_caja (void)
743{
744  if (check_caja())
745    open_caja (FALSE);
746}
747
748/**
749 * Es llamada por la funcion "prepare_caja"
750 *
751 * initializes a new caja
752 *
753 * @param automatic_mode TRUE if does NOT must prompt a dialog
754 * interaction with the user
755 */
756void
757open_caja (gboolean automatic_mode)
758{
759  if (automatic_mode)
760    InicializarCaja (caja_get_last_amount ());
761  else
762    InicializarCajaWin (caja_get_last_amount ());
763}
764
765
766/**
767 * Es llamada por las funciones "open_caja" y "IniciarLaCaja"
768 *
769 * Retrieves the last amount of money that has the current caja
770 * (opened or closed)
771 *
772 * @return the amount of money
773 */
774gint
775caja_get_last_amount (void)
776{
777  PGresult *res;
778  gchar *q;
779  gint last_amount = 0;
780  gint last_caja;
781
782  res = EjecutarSQL("select max(id) from caja");
783  last_caja = atoi (PQgetvalue (res, 0, 0));
784
785  q = g_strdup_printf ("select termino from caja where id=%d", last_caja);
786  res = EjecutarSQL (q);
787  g_free (q);
788
789  if (PQntuples (res) != 0)
790    {
791      last_amount = atoi (PQgetvalue (res, 0, 0));
792    }
793
794  return last_amount;
795}
796
797/**
798 * Es llamada cuando se preiona enter en la caja de texto "entry_caja_close_have"
799 * (signal actived)
800 *
801 * Uodates the entry of amount to close and the label of lost money in
802 * the close 'caja' dialog.
803 *
804 * @param editable the entry that emits the signal
805 * @param data the user data
806 */
807void
808on_entry_caja_close_have_changed (GtkEditable *editable, gpointer data)
809{
810  GtkWidget *widget;
811  gint monto;
812  gint must_have;
813
814  if (!HaveCharacters (g_strdup (gtk_entry_get_text(GTK_ENTRY(editable)))))
815    {
816      monto = atoi(gtk_entry_get_text(GTK_ENTRY(editable)));
817      widget = GTK_WIDGET (gtk_builder_get_object(builder, "lbl_caja_close_must_have"));
818      must_have = (gint)g_object_get_data(G_OBJECT(widget), "must-have");
819
820      widget = GTK_WIDGET (gtk_builder_get_object(builder, "lbl_caja_close_lost"));
821      gtk_label_set_text(GTK_LABEL(widget), g_strdup_printf("%d", must_have - monto));
822
823      if (must_have > monto)
824        gtk_label_set_markup (GTK_LABEL(widget), g_strdup_printf("<span color=\"red\">%d</span>", monto - must_have));
825      else
826        gtk_label_set_markup (GTK_LABEL(widget), g_strdup_printf("%d", monto - must_have));
827
828      widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_caja_close_amount"));
829      gtk_entry_set_text (GTK_ENTRY(widget), g_strdup_printf("%d", monto));
830
831    }
832}
833
834/**
835 * Es llamada cuando el boton "btn_cash_box_close" es presionado
836 * (signal clicked)
837 *
838 * Llama a la funcion "CerrarCajaWin"
839 *
840 * @param editable the entry that emits the signal
841 * @param data the user data
842 */
843void
844on_btn_cash_box_close_clicked (void)
845{
846  CerrarCajaWin ();
847}