PageRenderTime 102ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 2ms

/src/ventas.c

#
C | 7178 lines | 4781 code | 1293 blank | 1104 comment | 632 complexity | 0fe42238b99186b58a80fbcbc7c58742 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. /*ventas.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. #define _XOPEN_SOURCE 600
  24. #include<features.h>
  25. #include<gtk/gtk.h>
  26. #include<gdk/gdkkeysyms.h>
  27. #include<math.h>
  28. #include<stdlib.h>
  29. #include<string.h>
  30. #include<time.h>
  31. #include"tipos.h"
  32. #include"ventas.h"
  33. #include"credito.h"
  34. #include"postgres-functions.h"
  35. #include"errors.h"
  36. #include"manejo_productos.h"
  37. #include"manejo_pagos.h"
  38. #include"boleta.h"
  39. #include"config_file.h"
  40. #include"utils.h"
  41. #include"encriptar.h"
  42. #include"factura_more.h"
  43. #include"rizoma_errors.h"
  44. #include"proveedores.h"
  45. #include"caja.h"
  46. #include"vale.h"
  47. GtkBuilder *builder;
  48. GtkWidget *vuelto_button;
  49. GtkWidget *calendar_window;
  50. GtkWidget *button_cheque;
  51. GtkWidget *buscador_window;
  52. GtkWidget *label_found;
  53. GtkWidget *tipos_window;
  54. GtkWidget *canje_cantidad;
  55. GtkWidget *window_seller;
  56. gchar *tipo_venta;
  57. gint monto_cheque = 0;
  58. gboolean cheques = FALSE;
  59. GtkWidget *canje_entry;
  60. gboolean ventas = TRUE;
  61. gint tipo_documento = -1;
  62. gboolean mayorista = FALSE;
  63. gboolean closing_tipos = FALSE;
  64. gboolean block_discount = FALSE;
  65. // Venta de mercadería que se encuentre en la tabla de reserva
  66. gboolean venta_reserva = FALSE;
  67. // Inhabilita los procedimientos que requieran un stock en el producto
  68. //gboolean no_venta = FALSE;
  69. /**
  70. * Display the information of a product on the main sales window
  71. *
  72. * @param barcode the barcode of the product
  73. * @param mayorista TRUE if the product has a especial value for mayorist sales
  74. * @param marca the brand of the product
  75. * @param descripcion the description of the product
  76. * @param contenido the contents (amount) of the product
  77. * @param unidad the unit of the product (i.e. kg)
  78. * @param stock the current stock of the product
  79. * @param stock_day for how many days the current stock will be enough
  80. * @param precio the price of the product
  81. * @param precio_mayor the price of the producto for mayorist values
  82. * @param cantidad_mayor how many products must be saled to be considered as mayorist
  83. * @param codigo_corto the short code associated to the product
  84. */
  85. void
  86. FillProductSell (gchar *barcode,
  87. gboolean mayorista,
  88. gchar *marca,
  89. gchar *descripcion,
  90. gchar *contenido,
  91. gchar *unidad,
  92. gchar *stock,
  93. gchar *stock_day,
  94. gchar *precio,
  95. gchar *precio_mayor,
  96. gchar *cantidad_mayor,
  97. gchar *codigo_corto)
  98. {
  99. GtkWidget *widget;
  100. gchar *str_aux;
  101. //caja de producto
  102. widget = GTK_WIDGET(gtk_builder_get_object(builder, "barcode_entry"));
  103. gtk_entry_set_text(GTK_ENTRY(widget), barcode);
  104. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "product_label")),
  105. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s\n%s %s %s</span>",
  106. g_strndup (descripcion, 30), marca, contenido, unidad));
  107. if (strtod (PUT (stock), (char **)NULL) <= GetMinStock (barcode))
  108. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_stockday")),
  109. g_strdup_printf("<span foreground=\"red\"><b>%.2f dia(s)</b></span>",
  110. strtod (PUT (stock_day), (char **)NULL)));
  111. else
  112. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_stockday")),
  113. g_strdup_printf ("<b>%.2f dia(s)</b>", strtod (PUT (stock_day), (char **)NULL)));
  114. //precio
  115. /*gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_precio")),
  116. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>",
  117. PutPoints (precio)));*/
  118. if (rut_cliente_pre_factura > 0)
  119. {
  120. gchar *q;
  121. gdouble client_price = 0;
  122. q = g_strdup_printf ("SELECT precio FROM cliente_precio WHERE rut_cliente = %d AND barcode = '%s'",
  123. rut_cliente_pre_factura, barcode);
  124. PGresult *res = EjecutarSQL (q);
  125. if (res != NULL && PQntuples (res) != 0)
  126. {
  127. client_price = strtod (PUT (PQgetvalue (res, 0, 0)), (char **)NULL);
  128. if (client_price > 0)
  129. precio = PUT (g_strdup_printf ("%.3f",client_price));
  130. }
  131. g_free (q);
  132. }
  133. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_precio")), precio);
  134. //precio de mayorista
  135. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_mayor")),
  136. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>",
  137. PutPoints (precio_mayor)));
  138. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_mayor_cantidad")),
  139. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>",
  140. PutPoints (cantidad_mayor)));
  141. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_stock")),
  142. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%.2f</span>",
  143. strtod (PUT (stock), (char **)NULL)));
  144. str_aux = g_strdup(gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "cantidad_entry"))));
  145. str_aux = g_strdup_printf ("%.0f", strtod (PUT (str_aux), (char **)NULL) * atoi (precio));
  146. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_subtotal")),
  147. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>", PutPoints(str_aux)));
  148. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "codigo_corto")),
  149. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>", codigo_corto));
  150. }
  151. void
  152. CanjearProducto (GtkWidget *widget, gpointer data)
  153. {
  154. GtkWidget *entry = (GtkWidget *) data;
  155. if (entry == NULL)
  156. {
  157. gtk_widget_destroy (gtk_widget_get_toplevel (widget));
  158. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  159. }
  160. else
  161. {
  162. gchar *barcode = g_strdup (gtk_entry_get_text (GTK_ENTRY (canje_entry)));
  163. if ((GetDataByOne (g_strdup_printf ("SELECT barcode FROM producto WHERE barcode='%s'",
  164. barcode))) == NULL)
  165. {
  166. ErrorMSG (entry, "No existe el producto");
  167. return;
  168. }
  169. else
  170. {
  171. gdouble cantidad = strtod (PUT (g_strdup (gtk_entry_get_text (GTK_ENTRY (canje_cantidad)))),
  172. (char **)NULL);
  173. CanjearProduct (barcode, cantidad);
  174. CanjearProducto (widget, NULL);
  175. }
  176. }
  177. }
  178. void
  179. CanjearProductoWin (GtkWidget *widget, gpointer data)
  180. {
  181. GtkWidget *window;
  182. GtkWidget *vbox;
  183. GtkWidget *hbox;
  184. GtkWidget *label;
  185. GtkWidget *button;
  186. window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  187. gtk_window_set_title (GTK_WINDOW (window), "Canjear Producto");
  188. gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER_ALWAYS);
  189. gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
  190. gtk_window_present (GTK_WINDOW (window));
  191. gtk_widget_show (window);
  192. g_signal_connect (G_OBJECT (window), "destroy",
  193. G_CALLBACK (CanjearProducto), NULL);
  194. vbox = gtk_vbox_new (FALSE, 3);
  195. gtk_container_add (GTK_CONTAINER (window), vbox);
  196. gtk_widget_show (vbox);
  197. hbox = gtk_hbox_new (FALSE, 3);
  198. gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 3);
  199. gtk_widget_show (hbox);
  200. label = gtk_label_new ("Código de Barras: ");
  201. gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
  202. gtk_widget_show (label);
  203. canje_entry = gtk_entry_new ();
  204. gtk_box_pack_start (GTK_BOX (hbox), canje_entry, FALSE, FALSE, 3);
  205. gtk_widget_show (canje_entry);
  206. g_signal_connect (G_OBJECT (canje_entry), "activate",
  207. G_CALLBACK (SearchSellProduct), (gpointer)FALSE);
  208. gtk_window_set_focus (GTK_WINDOW (window), canje_entry);
  209. hbox = gtk_hbox_new (FALSE, 3);
  210. gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 3);
  211. gtk_widget_show (hbox);
  212. label = gtk_label_new ("Cantidad: ");
  213. gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
  214. gtk_widget_show (label);
  215. canje_cantidad = gtk_entry_new ();
  216. gtk_box_pack_start (GTK_BOX (hbox), canje_cantidad, FALSE, FALSE, 3);
  217. gtk_widget_show (canje_cantidad);
  218. g_signal_connect (G_OBJECT (canje_entry), "activate",
  219. G_CALLBACK (SendCursorTo), (gpointer)canje_cantidad);
  220. hbox = gtk_hbox_new (FALSE, 3);
  221. gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 3);
  222. gtk_widget_show (hbox);
  223. button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
  224. gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 3);
  225. gtk_widget_show (button);
  226. g_signal_connect (G_OBJECT (button), "clicked",
  227. G_CALLBACK (CanjearProducto), NULL);
  228. button = gtk_button_new_from_stock (GTK_STOCK_OK);
  229. gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 3);
  230. gtk_widget_show (button);
  231. g_signal_connect (G_OBJECT (button), "clicked",
  232. G_CALLBACK (CanjearProducto), (gpointer)canje_entry);
  233. g_signal_connect (G_OBJECT (canje_cantidad), "activate",
  234. G_CALLBACK (SendCursorTo), (gpointer)button);
  235. }
  236. void
  237. SetChequeDate (GtkCalendar *calendar, gpointer data)
  238. {
  239. GtkButton *button = (GtkButton *) data;
  240. guint day, month, year;
  241. time_t t;
  242. struct tm *current;
  243. if (calendar == NULL)
  244. {
  245. calendar = GTK_CALENDAR (gtk_calendar_new ());
  246. gtk_calendar_get_date (calendar, &year, &month, &day);
  247. gtk_button_set_label (button, g_strdup_printf ("%.2u/%.2u/%.4u", day, month+1, year));
  248. }
  249. else
  250. {
  251. time (&t);
  252. current = localtime (&t);
  253. gtk_calendar_get_date (calendar, &year, &month, &day);
  254. if (year >= (current->tm_year + 1900) && month >= current->tm_mon && day >= current->tm_mday)
  255. {
  256. gtk_button_set_label (button, g_strdup_printf ("%.2u/%.2u/%.4u", day, month+1, year));
  257. SetToggleMode (GTK_TOGGLE_BUTTON (data), NULL);
  258. }
  259. }
  260. }
  261. void
  262. SelectChequeDate (GtkToggleButton *widget, gpointer data)
  263. {
  264. GtkWidget *vbox;
  265. GtkCalendar *calendar;
  266. GtkRequisition req;
  267. gint h; //w;
  268. gint x, y;
  269. gint button_y, button_x;
  270. gboolean toggle = gtk_toggle_button_get_active (widget);
  271. if (toggle == TRUE)
  272. {
  273. gdk_window_get_origin (GTK_WIDGET (widget)->window, &x, &y);
  274. gtk_widget_size_request (GTK_WIDGET (widget), &req);
  275. h = req.height;
  276. //w = req.width;
  277. button_y = GTK_WIDGET (widget)->allocation.y;
  278. button_x = GTK_WIDGET (widget)->allocation.x;
  279. calendar_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  280. gtk_window_set_screen (GTK_WINDOW (calendar_window),
  281. gtk_widget_get_screen (GTK_WIDGET (widget)));
  282. gtk_container_set_border_width (GTK_CONTAINER (calendar_window), 5);
  283. gtk_window_set_type_hint (GTK_WINDOW (calendar_window), GDK_WINDOW_TYPE_HINT_DOCK);
  284. gtk_window_set_decorated (GTK_WINDOW (calendar_window), FALSE);
  285. gtk_window_set_resizable (GTK_WINDOW (calendar_window), FALSE);
  286. gtk_window_stick (GTK_WINDOW (calendar_window));
  287. gtk_window_set_title (GTK_WINDOW (calendar_window), "Calendario");
  288. vbox = gtk_vbox_new (FALSE, 3);
  289. gtk_container_add (GTK_CONTAINER (calendar_window), vbox);
  290. gtk_widget_show (vbox);
  291. calendar = GTK_CALENDAR (gtk_calendar_new ());
  292. gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (calendar), FALSE, FALSE, 0);
  293. gtk_widget_show (GTK_WIDGET (calendar));
  294. g_signal_connect (G_OBJECT (calendar), "day-selected-double-click",
  295. G_CALLBACK (SetChequeDate), (gpointer) widget);
  296. gtk_widget_show (calendar_window);
  297. x = (x + button_x);
  298. y = (y + button_y) + h;
  299. gtk_window_move (GTK_WINDOW (calendar_window), x, y);
  300. gtk_window_present (GTK_WINDOW (calendar_window));
  301. }
  302. else if (toggle == FALSE)
  303. {
  304. gtk_widget_destroy (calendar_window);
  305. }
  306. }
  307. void
  308. DatosCheque (void)
  309. {
  310. GtkWidget *window;
  311. GtkWidget *label;
  312. GtkWidget *frame;
  313. GtkWidget *button;
  314. GtkWidget *hbox;
  315. GtkWidget *vbox;
  316. GtkWidget *vbox2;
  317. window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  318. gtk_window_set_title (GTK_WINDOW (window), "Ingreso de Cheque");
  319. gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER_ALWAYS);
  320. gtk_widget_show (window);
  321. gtk_window_present (GTK_WINDOW (window));
  322. gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
  323. gtk_widget_show (window);
  324. vbox = gtk_vbox_new (FALSE, 3);
  325. gtk_container_add (GTK_CONTAINER (window), vbox);
  326. gtk_widget_show (vbox);
  327. hbox = gtk_hbox_new (FALSE, 3);
  328. gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 3);
  329. gtk_widget_show (hbox);
  330. button = gtk_button_new_with_mnemonic ("_Vender");
  331. gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 3);
  332. gtk_widget_show (button);
  333. frame = gtk_frame_new ("Datos Cheque");
  334. gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 3);
  335. gtk_widget_show (frame);
  336. vbox2 = gtk_vbox_new (FALSE, 3);
  337. gtk_container_add (GTK_CONTAINER (frame), vbox2);
  338. gtk_widget_show (vbox2);
  339. hbox = gtk_hbox_new (FALSE, 3);
  340. gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 3);
  341. gtk_widget_show (hbox);
  342. label = gtk_label_new ("Serie: ");
  343. gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
  344. gtk_widget_show (label);
  345. venta->cheque_serie = gtk_entry_new_with_max_length (10);
  346. gtk_box_pack_end (GTK_BOX (hbox), venta->cheque_serie, FALSE, FALSE, 3);
  347. gtk_widget_show (venta->cheque_serie);
  348. g_signal_connect (G_OBJECT (venta->venta_rut), "changed",
  349. G_CALLBACK (SendCursorTo), (gpointer)venta->cheque_serie);
  350. hbox = gtk_hbox_new (FALSE, 3);
  351. gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 3);
  352. gtk_widget_show (hbox);
  353. label = gtk_label_new ("Número: ");
  354. gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
  355. gtk_widget_show (label);
  356. venta->cheque_numero = gtk_entry_new ();
  357. gtk_box_pack_end (GTK_BOX (hbox), venta->cheque_numero, FALSE, FALSE, 3);
  358. gtk_widget_show (venta->cheque_numero);
  359. g_signal_connect (G_OBJECT (venta->cheque_serie), "activate",
  360. G_CALLBACK (SendCursorTo), (gpointer)venta->cheque_numero);
  361. hbox = gtk_hbox_new (FALSE, 3);
  362. gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 3);
  363. gtk_widget_show (hbox);
  364. label = gtk_label_new ("Banco: ");
  365. gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
  366. gtk_widget_show (label);
  367. venta->cheque_banco = gtk_entry_new_with_max_length (50);
  368. gtk_box_pack_end (GTK_BOX (hbox), venta->cheque_banco, FALSE, FALSE, 3);
  369. gtk_widget_show (venta->cheque_banco);
  370. g_signal_connect (G_OBJECT (venta->cheque_numero), "activate",
  371. G_CALLBACK (SendCursorTo), (gpointer)venta->cheque_banco);
  372. hbox = gtk_hbox_new (FALSE, 3);
  373. gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 3);
  374. gtk_widget_show (hbox);
  375. label = gtk_label_new ("Plaza: ");
  376. gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
  377. gtk_widget_show (label);
  378. venta->cheque_plaza = gtk_entry_new_with_max_length (50);
  379. gtk_box_pack_end (GTK_BOX (hbox), venta->cheque_plaza, FALSE, FALSE, 3);
  380. gtk_widget_show (venta->cheque_plaza);
  381. g_signal_connect (G_OBJECT (venta->cheque_banco), "activate",
  382. G_CALLBACK (SendCursorTo), (gpointer)venta->cheque_plaza);
  383. hbox = gtk_hbox_new (FALSE, 3);
  384. gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 3);
  385. gtk_widget_show (hbox);
  386. label = gtk_label_new ("Fecha: ");
  387. gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
  388. gtk_widget_show (label);
  389. button_cheque = gtk_toggle_button_new ();
  390. gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button_cheque), FALSE);
  391. gtk_box_pack_end (GTK_BOX (hbox), button_cheque, FALSE, FALSE, 3);
  392. gtk_widget_show (button_cheque);
  393. g_signal_connect (G_OBJECT (venta->cheque_plaza), "activate",
  394. G_CALLBACK (SendCursorTo), (gpointer)button_cheque);
  395. SetChequeDate (NULL, (gpointer)button_cheque);
  396. g_signal_connect (G_OBJECT (button_cheque), "toggled",
  397. G_CALLBACK (SelectChequeDate), NULL);
  398. hbox = gtk_hbox_new (FALSE, 3);
  399. gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 3);
  400. gtk_widget_show (hbox);
  401. label = gtk_label_new ("Monto: ");
  402. gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
  403. gtk_widget_show (label);
  404. venta->cheque_monto = gtk_entry_new_with_max_length (50);
  405. gtk_box_pack_end (GTK_BOX (hbox), venta->cheque_monto, FALSE, FALSE, 3);
  406. gtk_widget_show (venta->cheque_monto);
  407. g_signal_connect (G_OBJECT (button_cheque), "toggled",
  408. G_CALLBACK (SendCursorTo), (gpointer)venta->cheque_monto);
  409. g_signal_connect (G_OBJECT (venta->cheque_monto), "activate",
  410. G_CALLBACK (SendCursorTo), (gpointer)button);
  411. venta->tipo_venta = CHEQUE;
  412. }
  413. void
  414. CancelarTipo (GtkWidget *widget, gpointer data)
  415. {
  416. if (closing_tipos == TRUE)
  417. return;
  418. closing_tipos = TRUE;
  419. gtk_widget_destroy (gtk_widget_get_toplevel (widget));
  420. if ((gboolean)data == TRUE)
  421. {
  422. //TiposVenta (NULL, NULL);
  423. }
  424. else
  425. {
  426. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "sencillo_entry")));
  427. venta->tipo_venta = SIMPLE;
  428. }
  429. closing_tipos = FALSE;
  430. }
  431. /**
  432. *
  433. *
  434. */
  435. void
  436. on_precio_neto_sell_edited (GtkCellRendererText *cell, gchar *path_string, gchar *precio_neto_t, gpointer data)
  437. {
  438. GtkTreeModel *model = GTK_TREE_MODEL (data);
  439. GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
  440. GtkTreeIter iter;
  441. gchar *codigo, *barcode;
  442. gdouble iva, otros;
  443. gdouble precio_final, precio_neto, costo_neto, cantidad;
  444. gint sub_neto, sub_total;
  445. gdouble ganancia_minima = strtod (PUT (rizoma_get_value ("GANANCIA_MINIMA")), (char **)NULL);
  446. //Verifica que sea un valor numérico
  447. if (!is_numeric (precio_neto_t))
  448. {
  449. AlertMSG (GTK_WIDGET (builder_get (builder, "sell_products_list")),
  450. "El precio neto debe ser un valor numérico");
  451. return;
  452. }
  453. gtk_tree_model_get_iter (model, &iter, path);
  454. gtk_tree_path_free (path);
  455. gtk_tree_model_get (model, &iter,
  456. 0, &codigo, // Se obtiene el codigo del producto
  457. 2, &cantidad,
  458. -1);
  459. barcode = PQvaluebycol (EjecutarSQL (g_strdup_printf ("SELECT barcode FROM codigo_corto_to_barcode('%s')", codigo)),
  460. 0, "barcode");
  461. precio_neto = strtod (PUT (precio_neto_t), (char **)NULL);
  462. costo_neto = obtener_costo_promedio (barcode);
  463. ganancia_minima = (ganancia_minima > 0) ? (ganancia_minima/100)+1 : 1;
  464. costo_neto = costo_neto * ganancia_minima;
  465. //Se obtienen los impuestos
  466. iva = GetIVA (barcode);
  467. iva = (iva > 0) ? iva / 100 : 0;
  468. otros = GetOtros (barcode);
  469. otros = (otros > 0) ? otros / 100 : 0;
  470. if (precio_neto < costo_neto)
  471. {
  472. AlertMSG (GTK_WIDGET (builder_get (builder, "sell_products_list")),
  473. g_strdup_printf ("El precio es inferior al mínimo permitido ($ %s)",
  474. PutPoints (g_strdup_printf ("%ld", lround (costo_neto)))));
  475. return;
  476. }
  477. precio_final = (precio_neto * (1 + otros + iva));
  478. sub_neto = lround (precio_neto*cantidad);
  479. sub_total = lround (precio_final*cantidad);
  480. gtk_list_store_set (GTK_LIST_STORE (model), &iter,
  481. 3, precio_neto,
  482. 4, sub_neto,
  483. 5, precio_final,
  484. 6, sub_total,
  485. -1);
  486. /*Se modifican los datos de la estructura*/
  487. venta->product_check = BuscarPorCodigo (venta->header, codigo);
  488. venta->product_check->product->precio_mayor = precio_final;
  489. venta->product_check->product->precio = precio_final;
  490. venta->product_check->product->precio_neto = precio_neto;
  491. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")),
  492. g_strdup_printf ("<span size=\"40000\">%s</span>",
  493. PutPoints (g_strdup_printf ("%ld", lround (CalcularTotal (venta->header))))));
  494. }
  495. /**
  496. *
  497. *
  498. */
  499. void
  500. on_precio_final_sell_edited (GtkCellRendererText *cell, gchar *path_string, gchar *precio_final_t, gpointer data)
  501. {
  502. GtkTreeModel *model = GTK_TREE_MODEL (data);
  503. GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
  504. GtkTreeIter iter;
  505. gchar *codigo, *barcode;
  506. gdouble iva, otros;
  507. gdouble precio_final, precio_neto, costo_neto, cantidad;
  508. gint sub_neto, sub_total;
  509. gdouble ganancia_minima = strtod (PUT (rizoma_get_value ("GANANCIA_MINIMA")), (char **)NULL);
  510. //Verifica que sea un valor numérico
  511. if (!is_numeric (precio_final_t))
  512. {
  513. AlertMSG (GTK_WIDGET (builder_get (builder, "sell_products_list")),
  514. "El precio neto debe ser un valor numérico");
  515. return;
  516. }
  517. gtk_tree_model_get_iter (model, &iter, path);
  518. gtk_tree_path_free (path);
  519. gtk_tree_model_get (model, &iter,
  520. 0, &codigo, // Se obtiene el codigo del producto
  521. 2, &cantidad,
  522. -1);
  523. barcode = PQvaluebycol (EjecutarSQL
  524. (g_strdup_printf ("SELECT barcode FROM codigo_corto_to_barcode('%s')", codigo)),
  525. 0, "barcode");
  526. precio_final = strtod (PUT (precio_final_t), (char **)NULL);
  527. costo_neto = obtener_costo_promedio (barcode);
  528. ganancia_minima = (ganancia_minima > 0) ? (ganancia_minima/100)+1 : 1;
  529. costo_neto = costo_neto * ganancia_minima;
  530. //Se obtienen los impuestos
  531. iva = GetIVA (barcode);
  532. iva = (iva > 0) ? iva / 100 : 0;
  533. otros = GetOtros (barcode);
  534. otros = (otros > 0) ? otros / 100 : 0;
  535. //Costo neto + impuestos
  536. costo_neto *= (1 + otros + iva);
  537. if ((precio_final / (1 + otros + iva)) < costo_neto)
  538. {
  539. AlertMSG (GTK_WIDGET (builder_get (builder, "sell_products_list")),
  540. g_strdup_printf ("El precio es inferior al mínimo permitido ($ %s)",
  541. PutPoints (g_strdup_printf ("%ld", lround (costo_neto)))));
  542. return;
  543. }
  544. precio_neto = (precio_final / (1 + otros + iva));
  545. sub_neto = lround ( (precio_neto*cantidad) );
  546. sub_total = lround ( (precio_final*cantidad) );
  547. gtk_list_store_set (GTK_LIST_STORE (model), &iter,
  548. 3, precio_neto,
  549. 4, sub_neto,
  550. 5, precio_final,
  551. 6, sub_total,
  552. -1);
  553. /*Se modifican los datos de la estructura*/
  554. venta->product_check = BuscarPorCodigo (venta->header, codigo);
  555. venta->product_check->product->precio_mayor = precio_final;
  556. venta->product_check->product->precio = precio_final;
  557. venta->product_check->product->precio_neto = precio_neto;
  558. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")),
  559. g_strdup_printf ("<span size=\"40000\">%s</span>",
  560. PutPoints (g_strdup_printf ("%ld", lround (CalcularTotal (venta->header))))));
  561. }
  562. /**
  563. *
  564. *
  565. */
  566. void
  567. on_cantidad_sell_edited (GtkCellRendererText *cell, gchar *path_string, gchar *cantidad_t, gpointer data)
  568. {
  569. GtkTreeModel *model = GTK_TREE_MODEL (data);
  570. GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
  571. GtkTreeIter iter;
  572. gchar *codigo, *color;
  573. gdouble cantidad, precio_neto, precio_final, iva, otros;
  574. //Verifica que sea un valor numérico
  575. if (!is_numeric (cantidad_t) || (cantidad = strtod (PUT (cantidad_t), (char **)NULL)) < 1 )
  576. {
  577. AlertMSG (GTK_WIDGET (builder_get (builder, "sell_products_list")),
  578. "La cantidad debe ser un valor numérico mayor a cero");
  579. return;
  580. }
  581. gtk_tree_model_get_iter (model, &iter, path);
  582. gtk_tree_path_free (path);
  583. gtk_tree_model_get (model, &iter,
  584. 0, &codigo, // Se obtiene el codigo del producto
  585. 3, &precio_neto,
  586. 5, &precio_final,
  587. -1);
  588. /*Se modifican los datos de la estructura*/
  589. venta->product_check = BuscarPorCodigo (venta->header, codigo);
  590. venta->product_check->product->cantidad = cantidad;
  591. /*Se ve si es mayorista, de acuerdo a eso se le cambia el precio*/
  592. if (venta->product_check->product->mayorista == TRUE && venta->product_check->product->cantidad_mayorista > 0 &&
  593. venta->product_check->product->precio_mayor > 0 && cantidad >= venta->product_check->product->cantidad_mayorista)
  594. {
  595. //Se toma en cuenta el precio mayorista SOLO si no se ha modificado el precio del producto
  596. if (venta->product_check->product->precio == venta->product_check->product->precio_original)
  597. {
  598. precio_final = venta->product_check->product->precio_mayor;
  599. //Se obtienen los impuestos
  600. iva = venta->product_check->product->iva;
  601. iva = (iva > 0) ? iva / 100 : 0;
  602. otros = venta->product_check->product->otros;
  603. otros = (otros > 0) ? otros / 100 : 0;
  604. precio_neto = venta->product_check->product->precio_mayor / (1 + otros + iva);
  605. venta->product_check->product->precio_neto = precio_neto;
  606. }
  607. }
  608. /*Se elige el color de la fila*/
  609. if (venta->product_check->product->cantidad <= venta->product_check->product->stock)
  610. color = (venta->product_check->product->cantidad != venta->product_check->product->cantidad_impresa) ? g_strdup ("Blue") : g_strdup ("Black");
  611. else /*Si la cantidad solicitada supera al stock*/
  612. color = g_strdup ("Red");
  613. gtk_list_store_set (GTK_LIST_STORE (model), &iter,
  614. 2, cantidad,
  615. 3, precio_neto,
  616. 4, lround (precio_neto*cantidad),
  617. 5, precio_final,
  618. 6, lround (precio_final*cantidad),
  619. 9, color,
  620. 10, TRUE,
  621. -1);
  622. //Se actualiza la cantidad en la tabla mesa
  623. if (rizoma_get_value_boolean ("MODO_MESERO") ||
  624. rizoma_get_value_boolean ("MODO_VENTA_RESTAURANT"))
  625. modificar_producto_mesa (venta->num_mesa, venta->product_check->product->barcode, venta->product_check->product->cantidad, venta->product_check->product->cantidad_impresa);
  626. /* AHORA SE PERMITE VENTA NEGATIVA
  627. if (venta->product_check->product->stock < cantidad)
  628. {
  629. no_venta = TRUE;
  630. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_invoice")), FALSE);
  631. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_sale")), FALSE);
  632. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_devolver")), FALSE);
  633. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_traspaso_enviar")), FALSE);
  634. }*/
  635. //habilitar_venta ();
  636. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")),
  637. g_strdup_printf ("<span size=\"40000\">%s</span>",
  638. PutPoints (g_strdup_printf ("%ld", lround (CalcularTotal (venta->header))))));
  639. }
  640. /**
  641. *
  642. */
  643. void
  644. on_btn_seleccionar_mesa_clicked (GtkButton *button, gpointer data)
  645. {
  646. clean_container (GTK_CONTAINER (builder_get (builder, "wnd_cambio_mesa")));
  647. gtk_widget_show (GTK_WIDGET (builder_get (builder, "wnd_cambio_mesa")));
  648. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_numero_mesa")));
  649. }
  650. /**
  651. * Obtiene pre-ventas y reservas
  652. */
  653. void
  654. on_btn_get_preventa_ok_clicked (GtkButton *button, gpointer data)
  655. {
  656. gint id;
  657. gchar *preventa_txt1;
  658. gchar *preventa_txt2;
  659. gchar *entry_text;
  660. guint32 total;
  661. gdouble iva, otros;
  662. GtkTreeIter iter;
  663. PGresult *res;
  664. gchar *q;
  665. gint tuples, i;
  666. GtkListStore *sell = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (builder_get (builder, "sell_products_list"))));
  667. entry_text = pango_trim_string (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_id_preventa"))));
  668. if (g_str_equal (entry_text, "") || strlen (entry_text) < 3)
  669. {
  670. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_id_preventa")), "El ID ingresado es inválido");
  671. return;
  672. }
  673. preventa_txt1 = g_strndup (entry_text, 2);
  674. preventa_txt2 = invested_strndup (entry_text, 2);
  675. //Si el código no es un PV (PreVenta) o un RV (ReserVa) es inválido
  676. if ( (!g_str_equal (preventa_txt1, "PV") && !g_str_equal (preventa_txt1, "RV"))
  677. || HaveCharacters (preventa_txt2) || g_str_equal (preventa_txt2, ""))
  678. {
  679. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_id_preventa")), "El ID ingresado es inválido");
  680. return;
  681. }
  682. //printf ("COD: %s %s", preventa_txt1, preventa_txt2);
  683. id = atoi (preventa_txt2);
  684. //Si es un id valido
  685. if (id > 0)
  686. {
  687. /*TODO: Se debería dejar que la preventa de agregue a la lista
  688. junto a productos anteriormente agregados. Se debe cuidar que una
  689. misma pre-venta no se cargue 2 veces en la misma lista.
  690. Para ello debe haber una especie de 'manejo' de pre-venta.*/
  691. gtk_list_store_clear (sell);
  692. CleanEntryAndLabelData ();
  693. ListClean ();
  694. //Se obtiene la preventa, si el id es del tipo PV
  695. if (g_str_equal (preventa_txt1, "PV"))
  696. q = g_strdup_printf ("SELECT barcode, cantidad, precio "
  697. "FROM preventa_detalle pvd "
  698. "INNER JOIN preventa pv "
  699. "ON pvd.id_preventa = pv.id "
  700. "WHERE pv.id = %d "
  701. "AND pv.vendido = false", id);
  702. //Se obtiene la reserva, si el id es del tipo RV
  703. else if (g_str_equal (preventa_txt1, "RV"))
  704. q = g_strdup_printf ("SELECT barcode, cantidad, precio FROM reserva_detalle WHERE id_reserva = %d", id);
  705. res = EjecutarSQL (q);
  706. g_free (q);
  707. if (res != NULL && PQntuples (res) != 0)
  708. {
  709. tuples = PQntuples (res);
  710. /*Se agregan las mercaderías independientemente de si tienen o no stock (al realizar el pago total de venta
  711. ésta se finalizará y en ese proceso se debe exigir el stock suficiente de cada mercadería)*/
  712. for (i = 0; i < tuples; i++)
  713. {
  714. AgregarALista (NULL, PQvaluebycol (res, i, "barcode"), strtod (PUT (PQvaluebycol (res, i, "cantidad")), (char **)NULL));
  715. //Se reemplazan los 2 precios, para asegurarse que se venda con el precio puesto en el pedido, sin importar si la mercadería esta por mayor o no
  716. venta->products->product->precio = strtod (PUT (PQvaluebycol (res, i, "precio")), (char **)NULL);
  717. venta->products->product->precio_mayor = strtod (PUT (PQvaluebycol (res, i, "precio")), (char **)NULL);
  718. iva = (gdouble)venta->products->product->iva / 100;
  719. otros = (gdouble)venta->products->product->otros / 100;
  720. venta->products->product->precio_neto = (venta->products->product->precio / (1 + otros + iva));
  721. gtk_list_store_insert_after (sell, &iter, NULL);
  722. gtk_list_store_set (sell, &iter,
  723. 0, venta->products->product->codigo,
  724. 1, g_strdup_printf ("%s %s %d %s",
  725. venta->products->product->producto,
  726. venta->products->product->marca,
  727. venta->products->product->contenido,
  728. venta->products->product->unidad),
  729. 2, venta->products->product->cantidad,
  730. 3, venta->products->product->precio_neto,
  731. 4, lround (venta->products->product->cantidad * venta->products->product->precio_neto),
  732. 5, venta->products->product->precio,
  733. 6, lround (venta->products->product->cantidad * venta->products->product->precio),
  734. 7, venta->products->product->stock,
  735. 8, venta->products->product->cantidad_impresa,
  736. 9, (venta->products->product->cantidad > venta->products->product->stock) ? "Red":"Black",
  737. 10, TRUE,
  738. -1);
  739. venta->products->product->iter = iter;
  740. }
  741. total = llround (CalcularTotal (venta->header));
  742. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")),
  743. g_strdup_printf ("<span size=\"40000\">%s</span>",
  744. PutPoints (g_strdup_printf ("%u", total))));
  745. }
  746. else
  747. {
  748. //No existen datos con ese id
  749. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_id_preventa")), "");
  750. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_id_preventa")),
  751. g_strdup_printf ("No existen datos con el id %s%s", preventa_txt1, preventa_txt2));
  752. return;
  753. }
  754. if (g_str_equal (preventa_txt1, "PV"))
  755. venta->id_preventa = id;
  756. else if (g_str_equal (preventa_txt2, "RV"))
  757. {
  758. res = get_data_from_reserva_id (id);
  759. if (res == NULL || PQntuples (res) == 0)
  760. {
  761. //No existen datos con ese id
  762. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_id_preventa")), "");
  763. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_id_preventa")),
  764. g_strdup_printf ("No existen datos con el id %s%s", preventa_txt1, preventa_txt2));
  765. return;
  766. }
  767. venta_reserva = TRUE;
  768. venta->deuda_total = atoi (PQvaluebycol (res, 0, "monto"));
  769. venta->total_pagado = atoi (PQvaluebycol (res, 0, "monto_pagado"));
  770. venta->rut_cliente = atoi (g_strdup (PQvaluebycol(res, 0, "rut_cliente")));
  771. venta->id_reserva = id;
  772. }
  773. }
  774. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_get_preventa")));
  775. if (g_str_equal (preventa_txt1, "RV"))
  776. TipoVenta (NULL, NULL);
  777. }
  778. /**
  779. * Es llamada cuando se presiona el boton "btn_print_preventa" (signal clicked)
  780. *
  781. * Esta funcion muestra la ventana "wnd_preventa"
  782. *
  783. * @param button the button
  784. * @param user_data the user data
  785. */
  786. void
  787. on_btn_get_preventa_clicked (GtkButton *button, gpointer data)
  788. {
  789. GtkWidget *widget;
  790. widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_get_preventa"));
  791. clean_container (GTK_CONTAINER (widget));
  792. gtk_widget_show(widget);
  793. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder,"entry_id_preventa")));
  794. }
  795. /**
  796. * Main window
  797. */
  798. void
  799. ventas_win ()
  800. {
  801. GtkTreeViewColumn *column;
  802. GtkCellRenderer *renderer;
  803. GtkTreeIter iter;
  804. GtkWidget *ventas_gui;
  805. GError *error = NULL;
  806. //Inicializacion de la estructura venta
  807. venta = (Venta *) g_malloc (sizeof (Venta));
  808. venta->header = NULL;
  809. venta->products = NULL;
  810. venta->window = NULL;
  811. venta->id_preventa = 0;
  812. Productos *fill = venta->header;
  813. //TODO: Usar esta estructura para almacenar los datos del cliente seleccionado
  814. cliente = (DatosCliente *) g_malloc (sizeof (DatosCliente));
  815. //Inicialización de la estructura de cheques de restaurant
  816. pago_chk_rest = (PagoChequesRest *) g_malloc (sizeof (PagoChequesRest));
  817. pago_chk_rest->header = NULL;
  818. pago_chk_rest->cheques = NULL;
  819. //ChequesRestaurant *fill = pago_chk_rest->header;
  820. //Inicialización de pago mixto
  821. pago_mixto = (PagoMixto *) g_malloc (sizeof (PagoMixto));
  822. pago_mixto->check_rest1 = NULL;
  823. pago_mixto->check_rest2 = NULL;
  824. //Se inicializa bandera global (venta suscritos)
  825. rut_cliente_pre_factura = 0;
  826. venta->total_pagado = 0;
  827. venta->num_mesa = 0;
  828. builder = gtk_builder_new ();
  829. gtk_builder_add_from_file (builder, DATADIR"/ui/rizoma-ventas.ui", &error);
  830. if (error != NULL)
  831. g_printerr ("%s: %s\n", G_STRFUNC, error->message);
  832. gtk_builder_add_from_file (builder, DATADIR"/ui/rizoma-common.ui", &error);
  833. if (error != NULL)
  834. g_printerr ("%s: %s\n", G_STRFUNC, error->message);
  835. gtk_builder_connect_signals (builder, NULL);
  836. // check if is enabled the print of invoices to show or not show the
  837. // make invoice button
  838. if (!(rizoma_get_value_boolean ("PRINT_FACTURA")))
  839. {
  840. GtkWidget *aux_widget;
  841. aux_widget = GTK_WIDGET(gtk_builder_get_object (builder, "btn_invoice"));
  842. gtk_widget_hide (aux_widget);
  843. }
  844. if (rizoma_get_value_boolean ("CAJA"))
  845. {
  846. gtk_widget_show (GTK_WIDGET (builder_get (builder, "btn_cash_box_close")));
  847. }
  848. if (rizoma_get_value_boolean ("TRASPASO"))
  849. {
  850. gtk_widget_show (GTK_WIDGET (builder_get (builder, "btn_traspaso_enviar")));
  851. }
  852. ventas_gui = GTK_WIDGET (gtk_builder_get_object (builder, "wnd_sell"));
  853. //Titulo
  854. gtk_window_set_title (GTK_WINDOW (ventas_gui),
  855. g_strdup_printf ("POS Rizoma Comercio: Ventas - Conectado a [%s@%s]",
  856. config_profile,
  857. rizoma_get_value ("SERVER_HOST")));
  858. // check if the window must be set to fullscreen
  859. if (rizoma_get_value_boolean("FULLSCREEN"))
  860. gtk_window_maximize(GTK_WINDOW(ventas_gui));
  861. gtk_widget_show_all (ventas_gui);
  862. // Se setea el label con el nombre de usuario
  863. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_seller_name")),
  864. g_strdup_printf ("<span size=\"15000\">%s</span>", user_data->user));
  865. // Se setea el label con el número de mesa
  866. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "lbl_num_mesa")),
  867. g_strdup_printf ("<span size=\"15000\">%d</span>", venta->num_mesa));
  868. // Se setea el label con el número de boleta
  869. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_ticket_number")),
  870. g_strdup_printf ("<span size=\"15000\">%.6d</span>", get_ticket_number (SIMPLE)-1)); //antes get_last_sell_id ()
  871. // El numerno de venta no se debe basar en el numero de ticket, puesto que aquel corresponde a los documentos que se han emitido
  872. /* gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_ticket_number")), */
  873. /* g_strdup_printf ("<b><big>%.6d</big></b>", get_ticket_number (SIMPLE))); */
  874. venta->store = gtk_list_store_new (11,
  875. G_TYPE_STRING, //CODIGO
  876. G_TYPE_STRING, //DESCRIPCION
  877. G_TYPE_DOUBLE, //CANTIDAD
  878. G_TYPE_DOUBLE, //PRECIO NETO
  879. G_TYPE_INT, //SUB TOTAL NETO
  880. G_TYPE_DOUBLE, //PRECIO FINAL
  881. G_TYPE_INT, //SUB TOTAL FINAL
  882. G_TYPE_DOUBLE, //STOCK
  883. G_TYPE_DOUBLE, //CANTIDAD IMPRESA
  884. G_TYPE_STRING, //COLOR
  885. G_TYPE_BOOLEAN); //COLOREAR
  886. if (venta->header != NULL)
  887. {
  888. gdouble precio, precio_neto;
  889. do
  890. {
  891. if (fill->product->cantidad_mayorista > 0 && fill->product->precio_mayor > 0 && fill->product->cantidad >= fill->product->cantidad_mayorista &&
  892. fill->product->mayorista == TRUE)
  893. precio = fill->product->precio_mayor;
  894. else
  895. precio = fill->product->precio;
  896. precio_neto = precio / (fill->product->otros/100 + fill->product->iva/100 + 1);
  897. fill->product->precio_neto = precio_neto;
  898. gtk_list_store_insert_after (venta->store, &iter, NULL);
  899. gtk_list_store_set (venta->store, &iter,
  900. 0, fill->product->codigo,
  901. 1, g_strdup_printf ("%s %s %d %s",
  902. fill->product->producto,
  903. fill->product->marca,
  904. fill->product->contenido,
  905. fill->product->unidad),
  906. 2, fill->product->cantidad,
  907. 3, precio_neto,
  908. 4, lround (fill->product->cantidad * precio_neto),
  909. 5, precio,
  910. 6, lround (fill->product->cantidad * precio),
  911. 7, fill->product->stock,
  912. 8, fill->product->cantidad_impresa,
  913. 9, (fill->product->cantidad > fill->product->stock) ? "Red":"Black",
  914. 10, TRUE,
  915. -1);
  916. fill = fill->next;
  917. }
  918. while (fill != venta->header);
  919. }
  920. venta->treeview_products = GTK_WIDGET (gtk_builder_get_object (builder, "sell_products_list"));
  921. gtk_tree_view_set_model (GTK_TREE_VIEW (venta->treeview_products), GTK_TREE_MODEL (venta->store));
  922. renderer = gtk_cell_renderer_text_new ();
  923. column = gtk_tree_view_column_new_with_attributes ("Código", renderer,
  924. "text", 0,
  925. "foreground", 9,
  926. "foreground-set", 10,
  927. NULL);
  928. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->treeview_products), column);
  929. gtk_tree_view_column_set_alignment (column, 0.5);
  930. g_object_set (G_OBJECT (renderer), "xalign", 0.0, "font", "15", NULL);
  931. gtk_tree_view_column_set_resizable (column, FALSE);
  932. renderer = gtk_cell_renderer_text_new ();
  933. column = gtk_tree_view_column_new_with_attributes ("Descripción", renderer,
  934. "text", 1,
  935. "foreground", 9,
  936. "foreground-set", 10,
  937. NULL);
  938. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->treeview_products), column);
  939. gtk_tree_view_column_set_alignment (column, 0.5);
  940. g_object_set (G_OBJECT (renderer), "xalign", 0.0, "font", "15", NULL);
  941. gtk_tree_view_column_set_resizable (column, FALSE);
  942. gtk_tree_view_column_set_min_width (column, 400);
  943. gtk_tree_view_column_set_expand (column, TRUE);
  944. /* renderer = gtk_cell_renderer_text_new (); */
  945. /* column = gtk_tree_view_column_new_with_attributes ("Marca", renderer, */
  946. /* "text", 2, */
  947. /* NULL); */
  948. /* gtk_tree_view_append_column (GTK_TREE_VIEW (venta->treeview_products), column); */
  949. /* gtk_tree_view_column_set_alignment (column, 0.5); */
  950. /* gtk_tree_view_column_set_resizable (column, FALSE); */
  951. /* renderer = gtk_cell_renderer_text_new (); */
  952. /* column = gtk_tree_view_column_new_with_attributes ("Cont.", renderer, */
  953. /* "text", 3, */
  954. /* NULL); */
  955. /* gtk_tree_view_append_column (GTK_TREE_VIEW (venta->treeview_products), column); */
  956. /* gtk_tree_view_column_set_alignment (column, 0.5); */
  957. /* gtk_tree_view_column_set_resizable (column, FALSE); */
  958. /* renderer = gtk_cell_renderer_text_new (); */
  959. /* column = gtk_tree_view_column_new_with_attributes ("Uni.", renderer, */
  960. /* "text", 4, */
  961. /* NULL); */
  962. /* gtk_tree_view_append_column (GTK_TREE_VIEW (venta->treeview_products), column); */
  963. /* g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL); */
  964. /* gtk_tree_view_column_set_resizable (column, FALSE); */
  965. renderer = gtk_cell_renderer_text_new ();
  966. g_object_set (renderer, "editable", TRUE, NULL);
  967. g_signal_connect (G_OBJECT (renderer), "edited", G_CALLBACK (on_cantidad_sell_edited), (gpointer)venta->store);
  968. column = gtk_tree_view_column_new_with_attributes ("Cant.", renderer,
  969. "text", 2,
  970. "foreground", 9,
  971. "foreground-set", 10,
  972. NULL);
  973. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->treeview_products), column);
  974. gtk_tree_view_column_set_alignment (column, 0.5);
  975. g_object_set (G_OBJECT (renderer), "xalign", 1.0, "font", "15", NULL);
  976. gtk_tree_view_column_set_resizable (column, FALSE);
  977. gtk_tree_view_column_set_cell_data_func (column, renderer, control_decimal, (gpointer)2, NULL);
  978. if (rizoma_get_value_boolean ("MODO_GUIA_FACTURA"))
  979. {
  980. renderer = gtk_cell_renderer_text_new ();
  981. //El precio es editable si PRECIO_DISCRECIONAL esta habilitado
  982. if (rizoma_get_value_boolean ("PRECIO_DISCRECIONAL"))
  983. {
  984. g_object_set (renderer, "editable", TRUE, NULL);
  985. g_signal_connect (G_OBJECT (renderer), "edited", G_CALLBACK (on_precio_neto_sell_edited), (gpointer)venta->store);
  986. }
  987. column = gtk_tree_view_column_new_with_attributes ("Prec. Neto Un.", renderer,
  988. "text", 3,
  989. "foreground", 9,
  990. "foreground-set", 10,
  991. NULL);
  992. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->treeview_products), column);
  993. gtk_tree_view_column_set_alignment (column, 0.5);
  994. g_object_set (G_OBJECT (renderer), "xalign", 1.0, "font", "15", NULL);
  995. gtk_tree_view_column_set_resizable (column, FALSE);
  996. gtk_tree_view_column_set_cell_data_func (column, renderer, control_decimal, (gpointer)3, NULL);
  997. renderer = gtk_cell_renderer_text_new ();
  998. column = gtk_tree_view_column_new_with_attributes ("Sub Total Neto", renderer,
  999. "text", 4,
  1000. "foreground", 9,
  1001. "foreground-set", 10,
  1002. NULL);
  1003. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->treeview_products), column);
  1004. gtk_tree_view_column_set_alignment (column, 0.5);
  1005. g_object_set (G_OBJECT (renderer), "xalign", 1.0, "font", "15", NULL);
  1006. gtk_tree_view_column_set_resizable (column, FALSE);
  1007. gtk_tree_view_column_set_max_width (column, 100);
  1008. gtk_tree_view_column_set_cell_data_func (column, renderer, control_decimal, (gpointer)4, NULL);
  1009. }
  1010. renderer = gtk_cell_renderer_text_new ();
  1011. //El precio es editable si PRECIO_DISCRECIONAL esta habilitado
  1012. if (rizoma_get_value_boolean ("PRECIO_DISCRECIONAL"))
  1013. {
  1014. g_object_set (renderer, "editable", TRUE, NULL);
  1015. g_signal_connect (G_OBJECT (renderer), "edited", G_CALLBACK (on_precio_final_sell_edited), (gpointer)venta->store);
  1016. }
  1017. column = gtk_tree_view_column_new_with_attributes ("Precio Uni.", renderer,
  1018. "text", 5,
  1019. "foreground", 9,
  1020. "foreground-set", 10,
  1021. NULL);
  1022. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->treeview_products), column);
  1023. gtk_tree_view_column_set_alignment (column, 0.5);
  1024. g_object_set (G_OBJECT (renderer), "xalign", 1.0, "font", "15", NULL);
  1025. gtk_tree_view_column_set_resizable (column, FALSE);
  1026. gtk_tree_view_column_set_cell_data_func (column, renderer, control_decimal, (gpointer)5, NULL);
  1027. renderer = gtk_cell_renderer_text_new ();
  1028. column = gtk_tree_view_column_new_with_attributes ("Sub Total", renderer,
  1029. "text", 6,
  1030. "foreground", 9,
  1031. "foreground-set", 10,
  1032. NULL);
  1033. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->treeview_products), column);
  1034. gtk_tree_view_column_set_alignment (column, 0.5);
  1035. g_object_set (G_OBJECT (renderer), "xalign", 1.0, "font", "15", NULL);
  1036. gtk_tree_view_column_set_resizable (column, FALSE);
  1037. gtk_tree_view_column_set_max_width (column, 100);
  1038. gtk_tree_view_column_set_cell_data_func (column, renderer, control_decimal, (gpointer)6, NULL);
  1039. if (venta->header != NULL)
  1040. CalcularVentas (venta->header);
  1041. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  1042. if (rizoma_get_value_boolean ("CAJA"))
  1043. {
  1044. if (check_caja())
  1045. {
  1046. open_caja (FALSE);
  1047. }
  1048. else
  1049. {
  1050. gtk_widget_show_all (GTK_WIDGET (builder_get (builder, "dialog_cash_box_opened")));
  1051. }
  1052. }
  1053. /*conectando señales*/
  1054. only_number_filer_on_container (GTK_CONTAINER (builder_get (builder, "wnd_mixed_pay_step1")));
  1055. // Conectando la señal 'insert-text' para permitir solo números
  1056. /* g_signal_connect (G_OBJECT (builder_get (builder, "entry_int_code_mixed_pay")), "insert-text", */
  1057. /* G_CALLBACK (only_numberi_filter), NULL); */
  1058. /* g_signal_connect (G_OBJECT (builder_get (builder, "entry_int_amount_mixed_pay")), "insert-text", */
  1059. /* G_CALLBACK (only_numberi_filter), NULL); */
  1060. /* g_signal_connect (G_OBJECT (builder_get (builder, "entry_int_amount_mixed_pay2")), "insert-text", */
  1061. /* G_CALLBACK (only_numberi_filter), NULL); */
  1062. /* // TODO: crear (al igual que clean_container) una función que asigne este callback a todos los entry */
  1063. /* // numéricos */
  1064. /* g_signal_connect (G_OBJECT (builder_get (builder, "entry_int_code_detail_mp")), "insert-text", */
  1065. /* G_CALLBACK (only_numberi_filter), NULL); */
  1066. /* g_signal_connect (G_OBJECT (builder_get (builder, "entry_int_exp_date_mp")), "insert-text", */
  1067. /* G_CALLBACK (only_numberi_filter), NULL); */
  1068. /* g_signal_connect (G_OBJECT (builder_get (builder, "entry_int_amount_detail_mp")), "insert-text", */
  1069. /* G_CALLBACK (only_numberi_filter), NULL); */
  1070. g_signal_connect (G_OBJECT (builder_get (builder, "sencillo_entry")), "insert-text",
  1071. G_CALLBACK (only_numberi_filter), NULL);
  1072. // Conectando la señal 'insert-text' para calcular diferencia con el monto total
  1073. g_signal_connect (G_OBJECT (builder_get (builder, "entry_int_amount_mixed_pay")), "changed",
  1074. G_CALLBACK (calculate_amount), NULL);
  1075. g_signal_connect (G_OBJECT (builder_get (builder, "entry_int_amount_mixed_pay2")), "changed",
  1076. G_CALLBACK (calculate_amount), NULL);
  1077. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")), "<span size=\"40000\">0</span>");
  1078. //Algunas configuraciones del .rizoma
  1079. if (!rizoma_get_value_boolean ("PRECIO_DISCRECIONAL"))
  1080. gtk_editable_set_editable (GTK_EDITABLE (builder_get (builder, "entry_precio")), FALSE);
  1081. if (rizoma_get_value_boolean ("MODO_MESERO"))
  1082. {
  1083. on_btn_seleccionar_mesa_clicked (NULL, NULL);
  1084. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "btn_invoice")));
  1085. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "btn_sale")));
  1086. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "btn_realizar_pedido")));
  1087. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "btn_cash_box_close")));
  1088. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "btn_devolver")));
  1089. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "btn_traspaso_enviar")));
  1090. }
  1091. else if (!rizoma_get_value_boolean ("MODO_VENTA_RESTAURANT")) /*Se ocultan los botones de mesas*/
  1092. {
  1093. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "hbox1_mesa")));
  1094. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "btn_seleccionar_mesa")));
  1095. }
  1096. if (rizoma_get_value_boolean ("VENTA_SUSCRITO"))
  1097. {
  1098. //gtk_editable_set_editable (GTK_EDITABLE (builder_get (builder, "barcode_entry")), FALSE);
  1099. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "barcode_entry")), FALSE);
  1100. gtk_editable_set_editable (GTK_EDITABLE (builder_get (builder, "entry_precio")), TRUE);
  1101. gtk_widget_show (GTK_WIDGET (builder_get (builder, "btn_cliente_pre_factura")));
  1102. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "btn_cliente_pre_factura")));
  1103. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "hbox13")));
  1104. gtk_widget_show (GTK_WIDGET (builder_get (builder, "box2")));
  1105. }
  1106. else
  1107. {
  1108. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "btn_cliente_pre_factura")));
  1109. gtk_widget_show (GTK_WIDGET (builder_get (builder, "hbox13")));
  1110. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "box2")));
  1111. }
  1112. }
  1113. gboolean
  1114. AgregarProducto (GtkButton *button, gpointer data)
  1115. {
  1116. gchar *codigo = g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "codigo_corto"))));
  1117. gchar *barcode = g_strdup (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "barcode_entry"))));
  1118. guint32 total;
  1119. gchar *precio_discrecional;
  1120. gdouble stock = GetCurrentStock (barcode);
  1121. gdouble cantidad;
  1122. gdouble ganancia_minima = strtod (PUT (rizoma_get_value ("GANANCIA_MINIMA")), (char **)NULL);
  1123. gdouble costo_neto, iva, otros;
  1124. GtkTreeIter iter;
  1125. GtkWidget *aux_widget;
  1126. cantidad = strtod (PUT(g_strdup (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "cantidad_entry"))))), (char **) NULL);
  1127. if (cantidad <= 0)
  1128. {
  1129. aux_widget = GTK_WIDGET(gtk_builder_get_object (builder, "cantidad_entry"));
  1130. AlertMSG (aux_widget, "Debe ingresar una cantidad mayor a 0");
  1131. return FALSE;
  1132. }
  1133. aux_widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_precio"));
  1134. if (g_str_equal ("0", g_strdup (gtk_entry_get_text (GTK_ENTRY (aux_widget)))))
  1135. {
  1136. AlertMSG (GTK_WIDGET (gtk_builder_get_object (builder, "entry_precio")), "No se pueden vender productos con precio 0");
  1137. //CleanEntryAndLabelData ();
  1138. return FALSE;
  1139. }
  1140. /* AHORA SE PERMITE VENTA NEGATIVA
  1141. else if (cantidad > stock)
  1142. {
  1143. no_venta = TRUE;
  1144. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_invoice")), FALSE);
  1145. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_sale")), FALSE);
  1146. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_devolver")), FALSE);
  1147. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_traspaso_enviar")), FALSE);
  1148. //aux_widget = GTK_WIDGET (gtk_builder_get_object (builder, "cantidad_entry"));
  1149. //AlertMSG (aux_widget, "Stock insuficiente, debe ingresar una cantidad igual o menor al stock disponible");
  1150. //return FALSE;
  1151. }
  1152. */
  1153. else if (strchr (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "cantidad_entry"))), ',') != NULL ||
  1154. strchr (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "cantidad_entry"))), '.') != NULL)
  1155. {
  1156. if (VentaFraccion (barcode) == FALSE)
  1157. {
  1158. aux_widget = GTK_WIDGET (gtk_builder_get_object (builder, "cantidad_entry"));
  1159. AlertMSG (aux_widget,
  1160. "Este producto no se puede vender por fracción de unidad");
  1161. return FALSE;
  1162. }
  1163. }
  1164. if (!g_str_equal (codigo, ""))
  1165. {
  1166. gdouble precio, precio_neto;
  1167. gboolean nuevo;
  1168. gchar *color;
  1169. /*Agregamos el producto a la lista enlazada circular*/
  1170. if ( venta->products != NULL && //Si existen productos en la lista y está el seleccionado
  1171. (venta->product_check = BuscarPorCodigo (venta->header, codigo)) != NULL)
  1172. {
  1173. nuevo = FALSE;
  1174. }
  1175. else //Si no hay productos en la lista o no está el seleccionado
  1176. {
  1177. AgregarALista (codigo, barcode, cantidad);
  1178. venta->product_check = venta->products;
  1179. nuevo = TRUE;
  1180. }
  1181. /*AHORA SE PERMITE VENTA NEGATIVA
  1182. if (!nuevo && (venta->product_check->product->cantidad + cantidad) > stock)
  1183. {
  1184. no_venta = TRUE;
  1185. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_invoice")), FALSE);
  1186. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_sale")), FALSE);
  1187. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_devolver")), FALSE);
  1188. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_traspaso_enviar")), FALSE);
  1189. //AlertMSG (GTK_WIDGET (gtk_builder_get_object (builder, "cantidad_entry")),
  1190. //"No puede vender más productos de los que tiene en stock");
  1191. //if (nuevo)
  1192. //EliminarDeLista (venta->product_check->product->codigo, venta->product_check->product->lugar);
  1193. //return FALSE;
  1194. }*/
  1195. precio_discrecional = g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_precio"))));
  1196. //Se comprueba que el precio sea un valor numerico y mayor a 0
  1197. if (!is_numeric (precio_discrecional) ||
  1198. (precio = strtod (PUT (precio_discrecional), (char **)NULL)) <= 0 )
  1199. {
  1200. AlertMSG (GTK_WIDGET (gtk_builder_get_object (builder, "entry_precio")),
  1201. "El precio debe ser un valor numérico mayor a cero");
  1202. if (nuevo)
  1203. EliminarDeLista (venta->product_check->product->codigo, venta->product_check->product->lugar);
  1204. return FALSE;
  1205. }
  1206. if ( (rizoma_get_value_boolean ("PRECIO_DISCRECIONAL") == TRUE && precio != venta->product_check->product->precio) ||
  1207. venta->product_check->product->precio == 0 || rizoma_get_value_boolean ("VENTA_SUSCRITO") == TRUE)
  1208. {
  1209. //TODOOO: Se debe habilitar el entry precio, para darle uno y al agregarlo a la lista se debe deshabilitar
  1210. //Se actualiza el valor en la estructura para el registro de venta (si es mayorista da igual, porque prevalece el precio discrecional)
  1211. venta->product_check->product->precio_mayor = precio;
  1212. venta->product_check->product->precio = precio;
  1213. }
  1214. else if (venta->product_check->product->cantidad_mayorista > 0 && venta->product_check->product->precio_mayor > 0 &&
  1215. ((nuevo) ? venta->product_check->product->cantidad : venta->product_check->product->cantidad+cantidad) >= venta->product_check->product->cantidad_mayorista &&
  1216. venta->product_check->product->mayorista == TRUE)
  1217. precio = venta->product_check->product->precio_mayor;
  1218. else
  1219. precio = venta->product_check->product->precio;
  1220. costo_neto = venta->product_check->product->fifo;
  1221. ganancia_minima = (ganancia_minima > 0) ? (ganancia_minima/100)+1 : 1;
  1222. costo_neto = costo_neto * ganancia_minima;
  1223. //Se obtienen los impuestos
  1224. iva = venta->product_check->product->iva;
  1225. iva = (iva > 0) ? iva / 100 : 0;
  1226. otros = venta->product_check->product->otros;
  1227. otros = (otros > 0) ? otros / 100 : 0;
  1228. //Costo neto + impuestos
  1229. costo_neto *= (1 + otros + iva);
  1230. precio_neto = precio / (1 + otros + iva);
  1231. //Si el precio es inferior al mínimo permitido
  1232. if (precio < costo_neto)
  1233. {
  1234. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_precio")),
  1235. g_strdup_printf ("El precio es inferior al mínimo permitido ($ %s)",
  1236. PutPoints (g_strdup_printf ("%ld", lround (costo_neto)))));
  1237. if (nuevo)
  1238. EliminarDeLista (venta->product_check->product->codigo, venta->product_check->product->lugar);
  1239. return FALSE;
  1240. }
  1241. venta->product_check->product->precio_neto = precio_neto;
  1242. if (!nuevo)
  1243. venta->product_check->product->cantidad += cantidad;
  1244. /*Si esta en modo mesero, se agrega el producto a la mesa actual*/
  1245. if (rizoma_get_value_boolean ("MODO_MESERO") ||
  1246. rizoma_get_value_boolean ("MODO_VENTA_RESTAURANT"))
  1247. {
  1248. if (nuevo)
  1249. agregar_producto_mesa (venta->num_mesa, venta->product_check->product->barcode, precio, cantidad);
  1250. else
  1251. aumentar_producto_mesa (venta->num_mesa, venta->product_check->product->barcode, cantidad);
  1252. /*Blue indica que no ha sido impreso, o falta imprimir la 'cantidad' a preparar restante*/
  1253. color = (venta->product_check->product->cantidad > venta->product_check->product->stock) ? g_strdup ("Red") : g_strdup ("Blue");
  1254. }
  1255. else /*Si no está en modo restaurant, se ven otras condiciones para el color*/
  1256. color = (venta->product_check->product->cantidad > venta->product_check->product->stock) ? g_strdup ("Red") : g_strdup ("Black");
  1257. /*
  1258. Agregamos el producto al TreeView
  1259. */
  1260. if (nuevo) gtk_list_store_insert_after (venta->store, &iter, NULL);
  1261. gtk_list_store_set (venta->store, (nuevo) ? &iter : &venta->product_check->product->iter,
  1262. 0, venta->product_check->product->codigo,
  1263. 1, g_strdup_printf ("%s %s %d %s",
  1264. venta->product_check->product->producto,
  1265. venta->product_check->product->marca,
  1266. venta->product_check->product->contenido,
  1267. venta->product_check->product->unidad),
  1268. 2, venta->product_check->product->cantidad,
  1269. 3, precio_neto,
  1270. 4, lround (venta->product_check->product->cantidad * precio_neto),
  1271. 5, precio,
  1272. 6, lround (venta->product_check->product->cantidad * precio),
  1273. 7, stock,
  1274. 8, venta->product_check->product->cantidad_impresa, //TODOOO::ver todas las funcinoes que modifican estre treeview
  1275. 9, color,
  1276. 10, TRUE,
  1277. -1);
  1278. if (nuevo) venta->product_check->product->iter = iter;
  1279. //TODOOO: Color requiere de un g_free?... si un *gchar iniciado con g_strdup se libera con g_free, ¿se le puede volver asignar un valor?
  1280. /* Eliminamos los datos del producto en las entradas */
  1281. CleanEntryAndLabelData ();
  1282. /* Seteamos el Sub-Total y el Total */
  1283. total = llround (CalcularTotal (venta->header));
  1284. //total = sum_treeview_column (GTK_TREE_VIEW (ventas->treeview_products), 6, G_TYPE_INT);
  1285. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")),
  1286. g_strdup_printf ("<span size=\"40000\">%s</span>",
  1287. PutPoints (g_strdup_printf ("%u", total))));
  1288. // gtk_window_set_focus( GTK_WINDOW( main_window ), GTK_WIDGET (gtk_builder_get_object (builder, "label_total")));
  1289. }
  1290. return TRUE;
  1291. }
  1292. /*
  1293. * Es llamada por las funciones SearchSellProduct
  1294. *
  1295. * Esta funcion limpia las etiquetas (label) de los datos del producto
  1296. *
  1297. */
  1298. void
  1299. CleanSellLabels (void)
  1300. {
  1301. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "codigo_corto")), "");
  1302. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "product_label")), "");
  1303. gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object (builder, "barcode_entry")), "");
  1304. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_stockday")), "");
  1305. gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object (builder, "entry_precio")), "");
  1306. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_stock")), "");
  1307. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_subtotal")), "");
  1308. //gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object (builder, "cantidad_entry")), "1");
  1309. }
  1310. /*
  1311. * Es llamada por las funciones SearchSellProduct
  1312. *
  1313. * Esta funcion limpia las etiquetas (label) de los datos del producto
  1314. *
  1315. */
  1316. void
  1317. CleanEntryAndLabelData (void)
  1318. {
  1319. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "product_label")), "");
  1320. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "codigo_corto")), "");
  1321. gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object (builder, "cantidad_entry")), "1");
  1322. gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object (builder, "barcode_entry")), "");
  1323. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_stockday")), "");
  1324. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_mayor_cantidad")), "");
  1325. gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object (builder, "entry_precio")), "");
  1326. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_mayor")), "");
  1327. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_subtotal")), "");
  1328. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_stock")), "");
  1329. if (get_treeview_length (GTK_TREE_VIEW (venta->treeview_products)) == 0)
  1330. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")), "<span size=\"40000\">0</span>");
  1331. gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (builder, "sell_add_button")), FALSE);
  1332. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  1333. if (rizoma_get_value_boolean ("VENTA_SUSCRITO") == TRUE && rut_cliente_pre_factura > 0 &&
  1334. get_treeview_length (GTK_TREE_VIEW (builder_get (builder, "sell_products_list"))) <= 0)
  1335. {
  1336. rut_cliente_pre_factura = 0;
  1337. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "barcode_entry")), FALSE);
  1338. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "btn_cliente_pre_factura")));
  1339. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "lbl_selected_client")), "");
  1340. }
  1341. }
  1342. /**
  1343. * Es llamada cuando el boton "button_delete_product" es presionado (signal click).
  1344. *
  1345. * Esta funcion elimina el producto de la treeView y llamas a la funcion
  1346. * EliminarDeLIsta() y CalcularVentas()
  1347. *
  1348. * @param button the GtkButton that recieves the signal
  1349. * @param data the pointer passed to the callback
  1350. */
  1351. void
  1352. EliminarProducto (GtkButton *button, gpointer data)
  1353. {
  1354. GtkTreeIter iter;
  1355. GtkTreeSelection *selection;
  1356. gchar *codigo;
  1357. gint position;
  1358. selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (venta->treeview_products));
  1359. if (gtk_tree_selection_get_selected (selection, NULL, &iter) == TRUE)
  1360. {
  1361. gtk_tree_model_get (GTK_TREE_MODEL (venta->store), &iter,
  1362. 0, &codigo,
  1363. -1);
  1364. position = atoi (gtk_tree_model_get_string_from_iter (GTK_TREE_MODEL (venta->store), &iter));
  1365. EliminarDeLista (codigo, position);
  1366. eliminar_producto_mesa (venta->num_mesa, codigo_corto_to_barcode (codigo));
  1367. gtk_list_store_remove (GTK_LIST_STORE (venta->store), &iter);
  1368. CalcularVentas (venta->header);
  1369. //habilitar_venta ();
  1370. }
  1371. select_back_deleted_row("sell_products_list", position);
  1372. //Si no quedan productos en la lista de venta y la vandera de venta_reserva = TRUE
  1373. if (venta->header == NULL && venta_reserva == TRUE)
  1374. {
  1375. venta_reserva = FALSE;
  1376. venta->deuda_total = 0;
  1377. venta->total_pagado = 0;
  1378. venta->rut_cliente = 0;
  1379. venta->id_reserva = 0;
  1380. venta->id_preventa = 0;
  1381. }
  1382. }
  1383. /**
  1384. * Callback connected to the button present in
  1385. * rizoma-ventas.ui:tipo_venta_win_venta, the button sell_button
  1386. *
  1387. * @param button the GtkButton that recieves the signal
  1388. * @param data the pointer passed to the callback
  1389. */
  1390. void
  1391. on_sell_button_clicked (GtkButton *button, gpointer data)
  1392. {
  1393. gchar *rut = NULL;
  1394. gchar *cheque_date = NULL;
  1395. gint monto = atoi (CutPoints (g_strdup (gtk_label_get_text
  1396. (GTK_LABEL (gtk_builder_get_object (builder, "label_total"))))));
  1397. gchar *discount = "0";
  1398. gint maquina = atoi (rizoma_get_value ("MAQUINA"));
  1399. gint vendedor = user_data->user_id;
  1400. gint paga_con;
  1401. gint ticket = 0;
  1402. gboolean canceled;
  1403. // && rizoma_get_value_int ("VENDEDOR") != 1) se agrega en todos estos if mientras no se complete la
  1404. // la funcionalidad de pre-venta
  1405. if (((tipo_documento != VENTA && tipo_documento != FACTURA) && rizoma_get_value_int ("VENDEDOR") != 1) || venta_reserva == TRUE)
  1406. paga_con = atoi (g_strdup (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "sencillo_entry")))));
  1407. if ((tipo_documento != VENTA && paga_con <= 0) && rizoma_get_value_int ("VENDEDOR") != 1 && venta_reserva == FALSE)
  1408. {
  1409. GtkWidget *aux;
  1410. aux = GTK_WIDGET(gtk_builder_get_object(builder, "wnd_sale_type"));
  1411. g_assert (aux != NULL);
  1412. gtk_widget_show_all(aux);
  1413. return;
  1414. }
  1415. if ((tipo_documento != VENTA && paga_con < monto) && rizoma_get_value_int ("VENDEDOR") != 1 && venta_reserva == FALSE)
  1416. {
  1417. ErrorMSG (GTK_WIDGET (gtk_builder_get_object (builder, "sencillo_entry")), "No esta pagando con el dinero suficiente");
  1418. return;
  1419. }
  1420. if ((tipo_documento != VENTA) && rizoma_get_value_int ("VENDEDOR") != 1)
  1421. discount = g_strdup (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "entry_discount_money"))));
  1422. if (strlen (discount) == 0 )
  1423. discount = "0";
  1424. switch (tipo_documento)
  1425. {
  1426. case SIMPLE: case VENTA:
  1427. if (monto >= 180)
  1428. ticket = get_ticket_number (tipo_documento);
  1429. else
  1430. ticket = -1;
  1431. break;
  1432. /* case VENTA: */
  1433. /* ticket = -1; */
  1434. /* break; */
  1435. default:
  1436. g_printerr("Could not be found the document type %s", G_STRFUNC);
  1437. }
  1438. // DiscountStock (venta->header);
  1439. //TODO: Se descomenta cuando se termine la funcionalidad de pre-venta
  1440. /* if (tipo_documento == VENTA) */
  1441. /* canceled = FALSE; */
  1442. /* else */
  1443. if (venta_reserva == TRUE)
  1444. {
  1445. //Con esto nos aseguramos que el pago no exceda el total adeudado
  1446. paga_con = (paga_con+venta->total_pagado >= venta->deuda_total) ? venta->deuda_total-venta->total_pagado : paga_con;
  1447. //Si el pago liquída la deuda, se debe asegurar que haya stock para todo!
  1448. if (compare_treeview_column (GTK_TREE_VIEW (venta->treeview_products), 9, G_TYPE_STRING, "Red"))
  1449. {
  1450. AlertMSG (GTK_WIDGET (gtk_builder_get_object (builder, "btn_close_win")),
  1451. "Hay productos sin el stock suficiente para finalizar esta venta,\n"
  1452. "asegúrese de tener el stock suficiente para terminar la venta de este pedido");
  1453. return;
  1454. }
  1455. //Realizar pago
  1456. if (registrar_pago_reserva (venta->id_reserva, paga_con, CASH))
  1457. {
  1458. canceled = TRUE;
  1459. SaveSell (venta->deuda_total, maquina, vendedor, CASH, rut, discount, ticket, tipo_documento,
  1460. cheque_date, cheques, canceled, TRUE);
  1461. }
  1462. }
  1463. else
  1464. {
  1465. canceled = TRUE;
  1466. SaveSell (monto, maquina, vendedor, CASH, rut, discount, ticket, tipo_documento,
  1467. cheque_date, cheques, canceled, FALSE);
  1468. }
  1469. gtk_widget_hide (gtk_widget_get_toplevel (GTK_WIDGET (button)));
  1470. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  1471. gtk_list_store_clear (venta->store);
  1472. CleanEntryAndLabelData ();
  1473. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_total")), "");
  1474. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_ticket_number")),
  1475. g_strdup_printf ("<span size=\"15000\">%.6d</span>", get_ticket_number (SIMPLE)-1)); //antes get_last_sell_id ()
  1476. ListClean ();
  1477. if (venta_reserva == TRUE)
  1478. {
  1479. venta_reserva = FALSE;
  1480. venta->deuda_total = 0;
  1481. venta->total_pagado = 0;
  1482. venta->rut_cliente = 0;
  1483. venta->id_reserva = 0;
  1484. }
  1485. }
  1486. /**
  1487. * Al recibir un signal de "cantidad_entry", cambia el foco dependiendo de la opción
  1488. * VENTA_DIRECTA especificada en el .rizoma
  1489. *
  1490. * @parametro entry tipo GtkEntry * que recive la señal
  1491. * @parametro data tipo gpointer entrega el puntero para el procedimiento interno
  1492. */
  1493. void
  1494. MoveFocus (GtkEntry *entry, gpointer data)
  1495. { // Al presionar [ENTER] en el entry "Cantidad"
  1496. if (atoi(rizoma_get_value("VENTA_DIRECTA")) == FALSE || // Si VENTA_DIRECTA = 0 mueve el foco al botón "Añadir"
  1497. (atoi(rizoma_get_value("VENTA_DIRECTA")) == TRUE && // O Si VENTA_DIRECTA = 1 Y Es una venta fracción
  1498. (VentaFraccion (g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "barcode_entry")))))) ))
  1499. {
  1500. GtkWidget *button;
  1501. button = GTK_WIDGET (gtk_builder_get_object (builder, "sell_add_button"));
  1502. gtk_widget_set_sensitive(button, TRUE);
  1503. gtk_widget_grab_focus (button);
  1504. } // De lo contrario el foco regresa al entry "Código de barras"
  1505. else if (rizoma_get_value_boolean ("VENTA_SUSCRITO") == FALSE)
  1506. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  1507. if (rizoma_get_value_boolean ("VENTA_SUSCRITO") == TRUE && rut_cliente_pre_factura > 0)
  1508. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "entry_precio")));
  1509. }
  1510. void
  1511. AumentarCantidad (GtkEntry *entry, gpointer data)
  1512. {
  1513. gdouble cantidad = strtod (PUT (g_strdup (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "cantidad_entry"))))), (char **)NULL);
  1514. gint precio = atoi (g_strdup (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "entry_precio")))));
  1515. gint precio_mayor = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "label_mayor"))))));
  1516. gdouble cantidad_mayor = strtod (PUT (g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "label_mayor_cantidad"))))),
  1517. (char **)NULL);
  1518. guint32 subtotal;
  1519. //gchar nombre_entry = gtk_buildable_get_name (GTK_BUILDABLE (entry));
  1520. if (precio != 0 && ((mayorista == FALSE || cantidad < cantidad_mayor) ||
  1521. (mayorista == TRUE && (cantidad_mayor == 0 || precio_mayor == 0))))
  1522. {
  1523. subtotal = llround ((gdouble)cantidad * precio);
  1524. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_subtotal")),
  1525. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>",
  1526. PutPoints (g_strdup_printf ("%u", subtotal))));
  1527. }
  1528. else
  1529. if (precio_mayor != 0 && mayorista == TRUE && cantidad >= cantidad_mayor)
  1530. {
  1531. subtotal = llround ((gdouble)cantidad * precio_mayor);
  1532. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_subtotal")),
  1533. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>",
  1534. PutPoints (g_strdup_printf ("%u", subtotal))));
  1535. }
  1536. }
  1537. void
  1538. TipoVenta (GtkWidget *widget, gpointer data)
  1539. {
  1540. GtkWindow *window;
  1541. gchar *tipo_vendedor = rizoma_get_value ("VENDEDOR");
  1542. gboolean sencillo_directo = rizoma_get_value_boolean ("SENCILLO_DIRECTO");
  1543. /*Verifica si hay productos añadidos en la TreeView para vender*/
  1544. if (venta->header == NULL)
  1545. {
  1546. ErrorMSG (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")), "No hay productos para vender");
  1547. return;
  1548. }
  1549. /*De estar habilitada caja, se asegura que ésta se encuentre
  1550. abierta al momento de vender*/
  1551. //TODO: Unificar esta comprobación en las funciones primarias
  1552. // encargadas de hacer cualquier movimiento de caja
  1553. if (rizoma_get_value_boolean ("CAJA"))
  1554. if (check_caja()) // Se abre la caja en caso de que esté cerrada
  1555. open_caja (TRUE);
  1556. if (g_str_equal (tipo_vendedor, "1") && venta_reserva == FALSE) //Si se vende una reserva se debe ingresar un monto
  1557. {
  1558. //tipo_documento = VENTA;
  1559. tipo_documento = SIMPLE;
  1560. window = GTK_WINDOW (gtk_builder_get_object (builder, "vendedor_venta"));
  1561. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "button_imprimir")));
  1562. gtk_widget_show_all (GTK_WIDGET (window));
  1563. }
  1564. else
  1565. {
  1566. tipo_documento = SIMPLE;
  1567. window = GTK_WINDOW (gtk_builder_get_object (builder, "tipo_venta_win_venta"));
  1568. if (sencillo_directo == TRUE)
  1569. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "sencillo_entry")));
  1570. else
  1571. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_discount_money")));
  1572. clean_container (GTK_CONTAINER (window));
  1573. //gtk_widget_show (GTK_WIDGET (window));
  1574. if (venta_reserva == TRUE)
  1575. {
  1576. gtk_widget_show (GTK_WIDGET (builder_get (builder, "lbl_monto_pagado")));
  1577. gtk_widget_show (GTK_WIDGET (builder_get (builder, "label1_monto_pagado")));
  1578. gtk_label_set_markup_with_mnemonic (GTK_LABEL (builder_get (builder, "label72")), "_Abonar");
  1579. }
  1580. else
  1581. {
  1582. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "lbl_monto_pagado")));
  1583. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "label1_monto_pagado")));
  1584. gtk_label_set_markup_with_mnemonic (GTK_LABEL (builder_get (builder, "label72")), "_Vender");
  1585. }
  1586. if (venta->total_pagado > 0)
  1587. gtk_label_set_markup (GTK_LABEL (builder_get (builder, "lbl_monto_pagado")), g_strdup_printf ("<span size=\"20000\">%s</span>",
  1588. PutPoints (g_strdup_printf ("%d",venta->total_pagado)) ));
  1589. if (!venta_reserva)
  1590. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "sell_button")), FALSE);
  1591. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_close_win")), TRUE);
  1592. gtk_widget_show (GTK_WIDGET (window));
  1593. }
  1594. return;
  1595. }
  1596. void
  1597. CalcularVuelto (void)
  1598. {
  1599. /* gchar *pago = g_strdup (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "sencillo_entry")))); */
  1600. gint paga_con = atoi (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "sencillo_entry"))));
  1601. gint total = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "label_total"))))));
  1602. gint resto;
  1603. gchar *resto_t;
  1604. /* if (strcmp (pago, "c") == 0) */
  1605. /* PagoCheque (); */
  1606. if (paga_con > 0)
  1607. {
  1608. if (paga_con+venta->total_pagado < total)
  1609. {
  1610. resto_t = (venta_reserva) ? PutPoints (g_strdup_printf ("%d", total-(paga_con+venta->total_pagado))) : g_strdup ("Monto Insuficiente");
  1611. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "vuelto_label")),
  1612. g_strdup_printf ("<span size=\"30000\">%s</span>", resto_t));
  1613. gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (builder, "sell_button")), (venta_reserva) ? TRUE : FALSE); //Debe estar siempre habilitado para venta reserva
  1614. if (venta_reserva)
  1615. gtk_label_set_markup_with_mnemonic (GTK_LABEL (builder_get (builder, "label72")), "_Abonar");
  1616. return;
  1617. }
  1618. else
  1619. {
  1620. resto = paga_con+venta->total_pagado - total;
  1621. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "vuelto_label")),
  1622. g_strdup_printf ("<span size=\"30000\">%s</span> "
  1623. "<span size=\"15000\">Vuelto</span>",
  1624. PutPoints (g_strdup_printf ("%d", resto))));
  1625. gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (builder, "sell_button")), TRUE);
  1626. if (venta_reserva)
  1627. gtk_label_set_markup_with_mnemonic (GTK_LABEL (builder_get (builder, "label72")), "_Vender");
  1628. }
  1629. }
  1630. else
  1631. {
  1632. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "vuelto_label")),
  1633. g_strdup_printf ("<span size=\"30000\">%s</span>",
  1634. (venta->total_pagado) ? PutPoints (g_strdup_printf ("%d", total-venta->total_pagado)):""));
  1635. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "sell_button")), FALSE);
  1636. }
  1637. }
  1638. gint
  1639. AddProduct (void)
  1640. {
  1641. GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (venta->products_tree));
  1642. GtkTreeIter iter;
  1643. gint value;
  1644. if (gtk_tree_selection_get_selected (selection, NULL, &iter) == TRUE)
  1645. {
  1646. gtk_tree_model_get (GTK_TREE_MODEL (venta->products_store), &iter,
  1647. 0, &value,
  1648. -1);
  1649. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "codigo_corto")),
  1650. g_strdup_printf ("%d", value));
  1651. SearchSellProduct (NULL, NULL);
  1652. // CloseProductsWindow ();
  1653. }
  1654. return 0;
  1655. }
  1656. void
  1657. LooksForClient (void)
  1658. {
  1659. gint rut;
  1660. gint total;
  1661. if (SearchClient () == TRUE)
  1662. {
  1663. rut = atoi (g_strdup (gtk_entry_get_text (GTK_ENTRY (venta->entry_rut))));
  1664. gtk_widget_set_sensitive (venta->client_label, TRUE);
  1665. gtk_label_set_text (GTK_LABEL (venta->name_label),
  1666. ReturnClientName (rut));
  1667. total = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "label_total"))))));
  1668. gtk_widget_set_sensitive (venta->client_venta, TRUE);
  1669. if (VentaPosible (rut, total) == TRUE)
  1670. {
  1671. gtk_label_set_text (GTK_LABEL (venta->client_vender),
  1672. "Si");
  1673. gtk_widget_set_sensitive (venta->sell_button, TRUE);
  1674. }
  1675. else
  1676. gtk_label_set_text (GTK_LABEL (venta->client_vender),
  1677. "No");
  1678. }
  1679. else
  1680. {
  1681. gtk_widget_set_sensitive (venta->client_label, FALSE);
  1682. gtk_label_set_text (GTK_LABEL (venta->name_label),"");
  1683. gtk_widget_set_sensitive (venta->client_venta, FALSE);
  1684. gtk_label_set_text (GTK_LABEL (venta->client_vender), "");
  1685. }
  1686. }
  1687. gboolean
  1688. SearchClient (void)
  1689. {
  1690. gchar *rut = g_strdup (gtk_entry_get_text (GTK_ENTRY (venta->entry_rut)));
  1691. if (RutExist (rut) == FALSE)
  1692. return FALSE;
  1693. else
  1694. return TRUE;
  1695. }
  1696. gchar *
  1697. ModifieBarcode (gchar *barcode)
  1698. {
  1699. gchar *alt;
  1700. gchar lastchar;
  1701. if (strchr (barcode, '-') == NULL)
  1702. {
  1703. lastchar = barcode[strlen (barcode)-1];
  1704. alt = g_strndup (barcode, strlen (barcode) -1 );
  1705. return strcat (alt, g_strdup_printf ("-%c", lastchar));
  1706. }
  1707. else
  1708. return g_strdup (barcode);
  1709. }
  1710. void
  1711. parse_barcode (GtkEntry *entry, gpointer data)
  1712. {
  1713. gboolean barcode_fragmentado = rizoma_get_value_boolean ("BARCODE_FRAGMENTADO");
  1714. if (barcode_fragmentado == FALSE)
  1715. {
  1716. SearchSellProduct (entry, data);
  1717. return;
  1718. }
  1719. // Especificaciones para fragmentar barcode
  1720. gint bar_rango_producto_a = rizoma_get_value_int ("BAR_RANGO_PRODUCTO_A")-1;
  1721. gint bar_rango_producto_b = rizoma_get_value_int ("BAR_RANGO_PRODUCTO_B")-1;
  1722. gint bar_rango_cantidad_a = rizoma_get_value_int ("BAR_RANGO_CANTIDAD_A")-1;
  1723. gint bar_rango_cantidad_b = rizoma_get_value_int ("BAR_RANGO_CANTIDAD_B")-1;
  1724. gint bar_num_decimal = rizoma_get_value_int ("BAR_NUM_DECIMAL");
  1725. gint largo_barcode = bar_rango_producto_b - bar_rango_producto_a + 1;
  1726. gint largo_cantidad = bar_rango_cantidad_b - bar_rango_cantidad_a + 1;
  1727. gchar *barcode = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
  1728. gchar barcode_split[largo_barcode+1]; //+1 '\0'
  1729. gchar cantidad[largo_cantidad+2]; //+2 ',' y '\0'
  1730. if (g_str_equal (barcode, "") || HaveCharacters (barcode) ||
  1731. DataExist (g_strdup_printf ("SELECT barcode FROM producto WHERE barcode = %s", barcode)))
  1732. {
  1733. SearchSellProduct (entry, data);
  1734. }
  1735. else if (strlen(barcode) == 13)
  1736. {
  1737. //Divide el barcode
  1738. //barcode_split = invested_strndup (g_strndup (barcode, 7), 1);
  1739. strdup_string_range (barcode_split, barcode, bar_rango_producto_a, bar_rango_producto_b);
  1740. strdup_string_range_with_decimal (cantidad, barcode, bar_rango_cantidad_a, bar_rango_cantidad_b, bar_num_decimal);
  1741. //Divide Cantidad
  1742. if (DataExist (g_strdup_printf ("SELECT barcode FROM producto WHERE barcode = %s", barcode_split)))
  1743. {
  1744. //Setea el widget del barcode
  1745. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "barcode_entry")), barcode_split);
  1746. //Setea el widget cantidad
  1747. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "cantidad_entry")), cantidad);
  1748. //Llama a SearchSellProduct
  1749. SearchSellProduct (entry, data);
  1750. }
  1751. else
  1752. SearchSellProduct (entry, data);
  1753. }
  1754. else
  1755. SearchSellProduct (entry, data);
  1756. }
  1757. gint
  1758. SearchSellProduct (GtkEntry *entry, gpointer data)
  1759. {
  1760. gchar *barcode;
  1761. gchar *materia_prima;
  1762. gdouble stock, precio;
  1763. if (entry == NULL)
  1764. barcode = g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "barcode_entry"))));
  1765. else
  1766. barcode = g_strdup (gtk_entry_get_text (entry));
  1767. materia_prima = g_strdup (PQvaluebycol (EjecutarSQL ("SELECT id FROM tipo_mercaderia WHERE UPPER(nombre) LIKE 'MATERIA PRIMA'"), 0, "id"));
  1768. PGresult *res;
  1769. gint venta_directa = atoi(rizoma_get_value("VENTA_DIRECTA"));
  1770. gint venta_discrecional = atoi(rizoma_get_value("PRECIO_DISCRECIONAL"));
  1771. gchar *q= NULL;
  1772. if (strcmp (barcode, "") == 0)
  1773. return 0;
  1774. if (HaveCharacters (barcode) == TRUE || g_str_equal (barcode, ""))
  1775. {
  1776. BuscarProducto (NULL, NULL);
  1777. return 0;
  1778. }
  1779. gtk_entry_set_text (entry, barcode);
  1780. q = g_strdup_printf ("SELECT * FROM informacion_producto_venta ('%s')", barcode);
  1781. res = EjecutarSQL(q);
  1782. g_free(q);
  1783. // TODO: Crear validaciones unificadas que permitan manejar con más claridad el control de los datos que se ingresan
  1784. if (res == NULL)
  1785. return -1;
  1786. // Si la respuesta es de 0 filas (si no hay coincidencias en la búsqueda)
  1787. if (PQntuples (res) == 0)
  1788. {
  1789. if (strcmp (barcode, "") != 0) // Si se ingresó algún código, significa que no existe el producto
  1790. AlertMSG (GTK_WIDGET (entry), g_strdup_printf
  1791. ("No existe un producto con el código de barras %s!!", barcode));
  1792. if (ventas != FALSE)
  1793. CleanSellLabels ();
  1794. return -1;
  1795. }
  1796. // Si el producto es "Materia Prima" no se puede comercializar
  1797. if (g_str_equal (PQvaluebycol (res, 0, "tipo"), materia_prima) == TRUE)
  1798. {
  1799. GtkWidget *aux_widget;
  1800. aux_widget = GTK_WIDGET (builder_get (builder, "ventas_gui"));
  1801. gchar *str = g_strdup_printf("El código %s corresponde a una materia prima, no es comercializable", barcode);
  1802. CleanSellLabels();
  1803. AlertMSG (aux_widget, str);
  1804. g_free (str);
  1805. return -1;
  1806. }
  1807. // Si el estado es F significa que el producto fue eliminado
  1808. if (strcmp (PQvaluebycol (res, 0, "estado"),"f") == 0)
  1809. {
  1810. GtkWidget *aux_widget;
  1811. aux_widget = GTK_WIDGET(gtk_builder_get_object(builder, "ventas_gui"));
  1812. gchar *str = g_strdup_printf("El código %s fué invalidado por el administrador", barcode);
  1813. CleanSellLabels();
  1814. AlertMSG (aux_widget, str);
  1815. g_free (str);
  1816. return -1;
  1817. }
  1818. stock = strtod (PUT(PQvaluebycol(res, 0, "stock")), (char **)NULL);
  1819. //check if the product has stock
  1820. if (stock <= 0)
  1821. {
  1822. //the product has not stock, so display a message
  1823. //and abort the operation
  1824. /* AlertMSG (GTK_WIDGET (builder_get (builder, "barcode_entry")), */
  1825. /* g_strdup_printf ("El producto %s no tiene stock", barcode)); */
  1826. /* CleanSellLabels(); */
  1827. /* return -1; */
  1828. }
  1829. mayorista = strcmp (PQvaluebycol( res, 0, "mayorista"), "t") == 0 ? TRUE : FALSE;
  1830. precio = strtod (PUT (PQvaluebycol (res, 0, "precio")), (char **)NULL);
  1831. FillProductSell (PQvaluebycol (res, 0, "barcode"), mayorista, PQvaluebycol (res, 0, "marca"), PQvaluebycol (res, 0, "descripcion"),
  1832. PQvaluebycol (res, 0, "contenido"), PQvaluebycol (res, 0, "unidad"),
  1833. PQvaluebycol (res, 0, "stock"), PQvaluebycol (res, 0, "stock_day"),
  1834. PQvaluebycol (res, 0, "precio"), PQvaluebycol (res, 0, "precio_mayor"),
  1835. PQvaluebycol (res, 0, "cantidad_mayor"), PQvaluebycol (res, 0, "codigo_corto"));
  1836. if (venta_discrecional == 1 || precio == 0) //Si el precio es 0 caerá aquí aunque haya venta_directa
  1837. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "entry_precio")));
  1838. else if (venta_directa == 1)
  1839. {
  1840. if (VentaFraccion (PQvaluebycol (res, 0, "barcode")))
  1841. gtk_widget_grab_focus( GTK_WIDGET (gtk_builder_get_object (builder, "cantidad_entry")));
  1842. else
  1843. AgregarProducto( NULL, NULL );
  1844. }
  1845. else
  1846. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "cantidad_entry")));
  1847. return 0;
  1848. }
  1849. void
  1850. CloseBuscarWindow (GtkWidget *widget, gpointer data)
  1851. {
  1852. gboolean add = (gboolean) data;
  1853. gboolean fraccion = VentaFraccion (g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "barcode_entry")))));
  1854. gint venta_directa = atoi(rizoma_get_value("VENTA_DIRECTA"));
  1855. gint venta_discrecional = atoi(rizoma_get_value("PRECIO_DISCRECIONAL"));
  1856. gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "ventas_buscar")));
  1857. if (add == TRUE && venta_discrecional == 1)
  1858. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "entry_precio")));
  1859. else if (add == TRUE && venta_directa == 0)
  1860. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "cantidad_entry")));
  1861. else if (add == TRUE && (venta_directa == 1 && fraccion == TRUE))
  1862. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "cantidad_entry")));
  1863. else
  1864. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  1865. }
  1866. void
  1867. on_entry_precio_activate (GtkEntry *entry, gpointer data)
  1868. {
  1869. gint venta_directa;
  1870. gboolean fraccion;
  1871. gchar *precio_venta = g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_precio"))));
  1872. gchar *barcode = g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "barcode_entry"))));
  1873. if (g_str_equal (barcode, "") || HaveCharacters (barcode))
  1874. {
  1875. ErrorMSG (GTK_WIDGET (builder_get (builder, "barcode_entry")),
  1876. "Debe seleccionar un producto con anterioridad");
  1877. return;
  1878. }
  1879. if (g_str_equal (precio_venta, "") || !is_numeric (precio_venta))
  1880. {
  1881. ErrorMSG (GTK_WIDGET (entry), "El precio de venta debe ser un número válido");
  1882. return;
  1883. }
  1884. venta_directa = atoi (rizoma_get_value ("VENTA_DIRECTA"));
  1885. fraccion = VentaFraccion (g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "barcode_entry")))));
  1886. if (venta_directa == 1)
  1887. {
  1888. if (fraccion == TRUE)
  1889. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "cantidad_entry")));
  1890. else
  1891. AgregarProducto (NULL, NULL);
  1892. }
  1893. else if (rizoma_get_value_boolean ("VENTA_SUSCRITO") == FALSE)
  1894. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "cantidad_entry")));
  1895. if (rizoma_get_value_boolean ("VENTA_SUSCRITO") == TRUE && rut_cliente_pre_factura > 0)
  1896. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "sell_add_button")));
  1897. }
  1898. void
  1899. BuscarProducto (GtkWidget *widget, gpointer data)
  1900. {
  1901. GtkWidget *aux_widget;
  1902. GtkWidget *entry;
  1903. GtkWindow *window;
  1904. GtkListStore *store;
  1905. GtkTreeView *treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "ventas_search_treeview"));
  1906. GtkCellRenderer *renderer;
  1907. GtkTreeViewColumn *column;
  1908. aux_widget = GTK_WIDGET(gtk_builder_get_object (builder,
  1909. "ventas_buscar_entry"));
  1910. entry = GTK_WIDGET(gtk_builder_get_object (builder, "barcode_entry"));
  1911. gtk_entry_set_text (GTK_ENTRY (aux_widget),
  1912. gtk_entry_get_text (GTK_ENTRY (entry)));
  1913. if (gtk_tree_view_get_model (treeview) == NULL )
  1914. {
  1915. store = gtk_list_store_new (10,
  1916. G_TYPE_STRING,
  1917. G_TYPE_STRING,
  1918. G_TYPE_STRING,
  1919. G_TYPE_STRING,
  1920. G_TYPE_INT,
  1921. G_TYPE_STRING,
  1922. G_TYPE_STRING,
  1923. G_TYPE_INT,
  1924. G_TYPE_STRING,
  1925. G_TYPE_BOOLEAN);
  1926. gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (store));
  1927. renderer = gtk_cell_renderer_text_new ();
  1928. column = gtk_tree_view_column_new_with_attributes ("Código", renderer,
  1929. "text", 0,
  1930. NULL);
  1931. gtk_tree_view_append_column (treeview, column);
  1932. gtk_tree_view_column_set_alignment (column, 0.5);
  1933. g_object_set (G_OBJECT (renderer), "xalign", 0.5, NULL);
  1934. gtk_tree_view_column_set_min_width (column, 75);
  1935. gtk_tree_view_column_set_max_width (column, 75);
  1936. gtk_tree_view_column_set_resizable (column, FALSE);
  1937. if (solo_venta != TRUE)
  1938. {
  1939. renderer = gtk_cell_renderer_text_new ();
  1940. column = gtk_tree_view_column_new_with_attributes ("Código de Barras",
  1941. renderer,
  1942. "text", 1,
  1943. NULL);
  1944. gtk_tree_view_append_column (treeview, column);
  1945. gtk_tree_view_column_set_alignment (column, 0.5);
  1946. g_object_set (G_OBJECT (renderer), "xalign", 0.5, NULL);
  1947. gtk_tree_view_column_set_resizable (column, FALSE);
  1948. }
  1949. renderer = gtk_cell_renderer_text_new ();
  1950. column = gtk_tree_view_column_new_with_attributes ("Descripción",
  1951. renderer,
  1952. "text", 2,
  1953. "foreground", 8,
  1954. "foreground-set", 9,
  1955. NULL);
  1956. gtk_tree_view_append_column (treeview, column);
  1957. gtk_tree_view_column_set_alignment (column, 0.5);
  1958. g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
  1959. gtk_tree_view_column_set_min_width (column, 270);
  1960. gtk_tree_view_column_set_max_width (column, 270);
  1961. gtk_tree_view_column_set_resizable (column, FALSE);
  1962. renderer = gtk_cell_renderer_text_new ();
  1963. column = gtk_tree_view_column_new_with_attributes ("Marca", renderer,
  1964. "text", 3,
  1965. NULL);
  1966. gtk_tree_view_append_column (treeview, column);
  1967. gtk_tree_view_column_set_alignment (column, 0.5);
  1968. g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
  1969. gtk_tree_view_column_set_min_width (column, 90);
  1970. gtk_tree_view_column_set_max_width (column, 90);
  1971. gtk_tree_view_column_set_resizable (column, FALSE);
  1972. renderer = gtk_cell_renderer_text_new ();
  1973. column = gtk_tree_view_column_new_with_attributes ("Cont.", renderer,
  1974. "text", 4,
  1975. NULL);
  1976. gtk_tree_view_append_column (treeview, column);
  1977. gtk_tree_view_column_set_alignment (column, 0.5);
  1978. g_object_set (G_OBJECT (renderer), "xalign", 0.5, NULL);
  1979. gtk_tree_view_column_set_min_width (column, 40);
  1980. gtk_tree_view_column_set_max_width (column, 40);
  1981. gtk_tree_view_column_set_resizable (column, FALSE);
  1982. renderer = gtk_cell_renderer_text_new ();
  1983. column = gtk_tree_view_column_new_with_attributes ("Uni.", renderer,
  1984. "text", 5,
  1985. NULL);
  1986. gtk_tree_view_append_column (treeview, column);
  1987. gtk_tree_view_column_set_alignment (column, 0.5);
  1988. g_object_set (G_OBJECT (renderer), "xalign", 0.5, NULL);
  1989. gtk_tree_view_column_set_min_width (column, 40);
  1990. gtk_tree_view_column_set_max_width (column, 40);
  1991. gtk_tree_view_column_set_resizable (column, FALSE);
  1992. renderer = gtk_cell_renderer_text_new ();
  1993. column = gtk_tree_view_column_new_with_attributes ("Stock", renderer,
  1994. "text", 6,
  1995. NULL);
  1996. gtk_tree_view_append_column (treeview, column);
  1997. gtk_tree_view_column_set_alignment (column, 0.5);
  1998. g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
  1999. gtk_tree_view_column_set_min_width (column, 60);
  2000. gtk_tree_view_column_set_max_width (column, 60);
  2001. gtk_tree_view_column_set_resizable (column, FALSE);
  2002. renderer = gtk_cell_renderer_text_new ();
  2003. column = gtk_tree_view_column_new_with_attributes ("Precio", renderer,
  2004. "text", 7,
  2005. NULL);
  2006. gtk_tree_view_append_column (treeview, column);
  2007. gtk_tree_view_column_set_alignment (column, 0.5);
  2008. g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
  2009. gtk_tree_view_column_set_min_width (column, 70);
  2010. gtk_tree_view_column_set_max_width (column, 70);
  2011. gtk_tree_view_column_set_resizable (column, FALSE);
  2012. }
  2013. aux_widget = GTK_WIDGET(gtk_builder_get_object(builder, "ventas_buscar_entry"));
  2014. gtk_entry_set_text(GTK_ENTRY(aux_widget), gtk_entry_get_text(GTK_ENTRY(entry)));
  2015. window = GTK_WINDOW (gtk_builder_get_object (builder, "ventas_buscar"));
  2016. gtk_widget_show_all (GTK_WIDGET (window));
  2017. SearchAndFill ();
  2018. return;
  2019. }
  2020. /**
  2021. * Populate the search products window, takes as argument the content of
  2022. * the 'ventas_buscar_entry' for the buscar_producto plpgsql function, and
  2023. * the rows returned by the function are inserted into the TreeView model
  2024. *
  2025. */
  2026. void
  2027. SearchAndFill (void)
  2028. {
  2029. PGresult *res=NULL;
  2030. gint resultados, i;
  2031. gchar *q;
  2032. gchar *string;
  2033. gchar *materia_prima;
  2034. GtkTreeView *tree = GTK_TREE_VIEW (gtk_builder_get_object (builder, "ventas_search_treeview"));
  2035. GtkTreeIter iter;
  2036. GtkListStore *store;
  2037. gboolean con_stock;
  2038. string = g_strdup (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "ventas_buscar_entry"))));
  2039. store = GTK_LIST_STORE (gtk_tree_view_get_model (tree));
  2040. materia_prima = g_strdup (PQvaluebycol (EjecutarSQL ("SELECT id FROM tipo_mercaderia WHERE UPPER(nombre) LIKE 'MATERIA PRIMA'"), 0, "id"));
  2041. con_stock = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (builder_get (builder, "rdbutton_solo_stock")));
  2042. if (!(g_str_equal (string, "")))
  2043. {
  2044. q = g_strdup_printf ("SELECT * FROM buscar_producto ('%s', "
  2045. "'{\"barcode\", \"codigo_corto\",\"marca\","
  2046. "\"descripcion\"}', true, %s) WHERE tipo_id != %s", string, (con_stock) ? "true":"false", materia_prima);
  2047. res = EjecutarSQL (q);
  2048. resultados = PQntuples (res);
  2049. }
  2050. else
  2051. resultados = 0;
  2052. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "ventas_label_found")),
  2053. g_strdup_printf ("<b>%d producto(s)</b>", resultados));
  2054. gtk_list_store_clear (store);
  2055. if (resultados == 0)
  2056. {
  2057. gtk_list_store_append (store, &iter);
  2058. gtk_list_store_set (store, &iter,
  2059. 2, "No se encontró descripción",
  2060. 8, "Red",
  2061. 9, TRUE,
  2062. -1);
  2063. }
  2064. else
  2065. {
  2066. for (i = 0; i < resultados; i++)
  2067. {
  2068. gtk_list_store_append (store, &iter);
  2069. gtk_list_store_set (store, &iter,
  2070. 0, PQvaluebycol (res, i, "codigo_corto"),
  2071. 1, PQvaluebycol (res, i, "barcode"),
  2072. 2, PQvaluebycol (res, i, "descripcion"),
  2073. 3, PQvaluebycol (res, i, "marca"),
  2074. 4, atoi (PQvaluebycol (res, i, "contenido")),
  2075. 5, PQvaluebycol (res, i, "unidad"),
  2076. 6, g_strdup_printf("%.3f", strtod (PUT (PQvaluebycol (res, i, "stock")), (char **)NULL)),
  2077. 7, atoi (PQvaluebycol (res, i, "precio")),
  2078. -1);
  2079. }
  2080. }
  2081. gtk_widget_grab_focus (GTK_WIDGET (tree));
  2082. gtk_tree_selection_select_path (gtk_tree_view_get_selection (tree), gtk_tree_path_new_from_string ("0"));
  2083. }
  2084. void
  2085. FillSellData (GtkTreeView *treeview, GtkTreePath *arg1, GtkTreeViewColumn *arg2, gpointer data)
  2086. {
  2087. GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (gtk_builder_get_object (builder, "ventas_search_treeview")));
  2088. GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_builder_get_object (builder, "ventas_search_treeview"))));
  2089. GtkTreeIter iter;
  2090. gchar *barcode, *product, *codigo;
  2091. gdouble precio;
  2092. if (gtk_tree_selection_get_selected (selection, NULL, &iter) == TRUE)
  2093. {
  2094. gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
  2095. 0, &codigo,
  2096. 1, &barcode,
  2097. 2, &product,
  2098. 7, &precio,
  2099. -1);
  2100. if (codigo == NULL)
  2101. return;
  2102. if (ventas == TRUE)
  2103. {
  2104. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "product_label")),
  2105. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>", product));
  2106. /*gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_precio")),
  2107. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>",
  2108. PutPoints (g_strdup_printf ("%d", precio))));*/
  2109. /*gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_subtotal")),
  2110. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>",
  2111. PutPoints (g_strdup_printf ("%u", atoi (gtk_entry_get_text (GTK_ENTRY (gtk_builder_get_object (builder, "cantidad_entry")))) *
  2112. atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "label_precio"))))))))));*/
  2113. /*Si se selecciono un cliente
  2114. (Que puede tener precio preferencial para el producto seleccionado)*/
  2115. if (rut_cliente_pre_factura > 0)
  2116. {
  2117. gchar *q;
  2118. gdouble client_price = 0;
  2119. q = g_strdup_printf ("SELECT precio FROM cliente_precio WHERE rut_cliente = %d AND barcode = '%s'",
  2120. rut_cliente_pre_factura, barcode);
  2121. PGresult *res = EjecutarSQL (q);
  2122. if (res != NULL && PQntuples (res) != 0)
  2123. {
  2124. client_price = strtod (PUT (PQgetvalue (res, 0, 0)), (char **)NULL);
  2125. if (client_price > 0)
  2126. precio = client_price;
  2127. }
  2128. g_free (q);
  2129. }
  2130. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_precio")), PUT (g_strdup_printf ("%.3f",precio)));
  2131. /*gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_precio")),
  2132. g_strdup_printf ("%d", precio * atoi (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "cantidad_entry"))))));*/
  2133. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "codigo_corto")),
  2134. g_strdup_printf ("<span weight=\"ultrabold\" size=\"12000\">%s</span>", codigo));
  2135. gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object (builder, "barcode_entry")), barcode);
  2136. CloseBuscarWindow (NULL, (gpointer)TRUE);
  2137. SearchSellProduct (GTK_ENTRY (builder_get (builder, "barcode_entry")), (gpointer)TRUE);
  2138. }
  2139. else
  2140. CloseBuscarWindow (NULL, (gpointer)TRUE);
  2141. }
  2142. }
  2143. void
  2144. Descuento (GtkWidget *widget, gpointer data)
  2145. {
  2146. gchar *widget_name = g_strdup (gtk_buildable_get_name (GTK_BUILDABLE (widget)));
  2147. gint amount = atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
  2148. gint total;
  2149. gint money_discount = 0;
  2150. gint percent_discount = 0;
  2151. if (block_discount) return;
  2152. block_discount = TRUE;
  2153. if (amount <= 0)
  2154. {
  2155. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_discount_money")), "");
  2156. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_discount_percent")), "");
  2157. CalcularVentas (venta->header);
  2158. block_discount = FALSE;
  2159. return;
  2160. }
  2161. CalcularVentas (venta->header);
  2162. total = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (builder_get (builder, "label_total"))))));
  2163. if (g_str_equal (widget_name, "entry_discount_money"))
  2164. {
  2165. if (amount > total)
  2166. {
  2167. block_discount = FALSE;
  2168. return;
  2169. }
  2170. money_discount = amount;
  2171. percent_discount = lround ( (gdouble) (money_discount * 100) / total);
  2172. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_discount_percent")),
  2173. g_strdup_printf ("%d", percent_discount));
  2174. }
  2175. else if (g_str_equal (widget_name, "entry_discount_percent"))
  2176. {
  2177. if (amount > 100)
  2178. {
  2179. block_discount = FALSE;
  2180. return;
  2181. }
  2182. money_discount = lround ( (gdouble) (total * amount) / 100);
  2183. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_discount_money")),
  2184. g_strdup_printf ("%d", money_discount));
  2185. }
  2186. block_discount = FALSE;
  2187. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")),
  2188. g_strdup_printf ("<span size=\"40000\">%s</span>", PutPoints (g_strdup_printf ("%u", total - money_discount))));
  2189. }
  2190. /**
  2191. *
  2192. */
  2193. gboolean
  2194. CalcularVentas (Productos *header)
  2195. {
  2196. guint32 total = llround (CalcularTotal (header));
  2197. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")),
  2198. g_strdup_printf ("<span size=\"40000\">%s</span>",
  2199. PutPoints (g_strdup_printf ("%u", total))));
  2200. return TRUE;
  2201. }
  2202. /**
  2203. * Actualmente el procedimiento de venta no tiene restricción de stock,
  2204. * admitiendo de esta forma ventas con stock negativo.
  2205. */
  2206. /*void
  2207. habilitar_venta (void)
  2208. {
  2209. gboolean valid;
  2210. GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (venta->treeview_products));
  2211. GtkTreeIter iter;
  2212. gdouble stock, cantidad;
  2213. valid = gtk_tree_model_get_iter_first (model, &iter);
  2214. while (valid)
  2215. {
  2216. gtk_tree_model_get (model, &iter,
  2217. 2, &cantidad,
  2218. 7, &stock,
  2219. -1);
  2220. if (cantidad > stock)
  2221. return;
  2222. valid = gtk_tree_model_iter_next (model, &iter);
  2223. }
  2224. //no_venta = FALSE;
  2225. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_invoice")), TRUE);
  2226. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_sale")), TRUE);
  2227. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_devolver")), TRUE);
  2228. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_traspaso_enviar")), TRUE);
  2229. }
  2230. */
  2231. void
  2232. CloseCancelWindow (void)
  2233. {
  2234. gtk_widget_destroy (venta->cancel_window);
  2235. venta->cancel_window = NULL;
  2236. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  2237. }
  2238. void
  2239. FindCancelSell (GtkWidget *widget, gpointer data)
  2240. {
  2241. gchar *text = g_strdup (gtk_entry_get_text (GTK_ENTRY ( data)));
  2242. PGresult *res;
  2243. gint tuples, i;
  2244. GtkTreeIter iter;
  2245. gchar *q = NULL;
  2246. q = g_strdup_printf("SELECT venta.id, monto, users.usuario FROM venta "
  2247. "INNER JOIN users ON users.id = venta.vendedor "
  2248. "WHERE venta.id = %s AND canceled = FALSE",
  2249. text);
  2250. res = EjecutarSQL (q);
  2251. g_free(q);
  2252. tuples = PQntuples (res);
  2253. gtk_list_store_clear (venta->cancel_store);
  2254. for (i = 0; i < tuples; i++)
  2255. {
  2256. gtk_list_store_append (venta->cancel_store, &iter);
  2257. gtk_list_store_set (venta->cancel_store, &iter,
  2258. 0, PQvaluebycol (res, i, "id"),
  2259. 1, PQvaluebycol (res, i, "usuario"),
  2260. 2, PQvaluebycol (res, i, "monto"),
  2261. -1);
  2262. }
  2263. }
  2264. void
  2265. CancelSell (GtkWidget *widget, gpointer data)
  2266. {
  2267. GtkWidget *window_kill = gtk_widget_get_toplevel (widget);
  2268. gint cancel = (gboolean)data;
  2269. gchar *id_venta;
  2270. GtkTreeIter iter;
  2271. GtkTreeSelection *selection;
  2272. //PGresult *res;
  2273. if (cancel == 1)
  2274. {
  2275. selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (venta->cancel_tree));
  2276. if (gtk_tree_selection_get_selected (selection, NULL, &iter) == TRUE)
  2277. {
  2278. gtk_tree_model_get (GTK_TREE_MODEL (venta->cancel_store), &iter,
  2279. 0, &id_venta,
  2280. -1);
  2281. gchar *q;
  2282. q = g_strdup_printf ("select cancelar_venta(%s)", id_venta);
  2283. EjecutarSQL (q);
  2284. g_free(id_venta);
  2285. g_free(q);
  2286. gtk_list_store_remove(venta->cancel_store,&iter);
  2287. }
  2288. }
  2289. gtk_widget_set_sensitive (venta->cancel_window, TRUE);
  2290. gtk_widget_destroy (window_kill);
  2291. }
  2292. void
  2293. AskCancelSell (GtkWidget *widget, gpointer data)
  2294. {
  2295. GtkWidget *window;
  2296. GtkWidget *vbox;
  2297. GtkWidget *hbox;
  2298. GtkWidget *button;
  2299. GtkWidget *label;
  2300. gtk_widget_set_sensitive (venta->cancel_window, FALSE);
  2301. window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  2302. gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER_ALWAYS);
  2303. gtk_window_present (GTK_WINDOW (window));
  2304. gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
  2305. gtk_widget_show (window);
  2306. g_signal_connect (G_OBJECT (window), "destroy",
  2307. G_CALLBACK (CancelSell), (gpointer)FALSE);
  2308. vbox = gtk_vbox_new (FALSE, 3);
  2309. gtk_container_add (GTK_CONTAINER (window), vbox);
  2310. gtk_widget_show (vbox);
  2311. hbox = gtk_hbox_new (FALSE, 3);
  2312. gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 3);
  2313. gtk_widget_show (hbox);
  2314. label = gtk_label_new ("¿Desea cancelar la venta?");
  2315. gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
  2316. gtk_widget_show (label);
  2317. hbox = gtk_hbox_new (FALSE, 3);
  2318. gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 3);
  2319. gtk_widget_show (hbox);
  2320. button = gtk_button_new_from_stock (GTK_STOCK_NO);
  2321. gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 3);
  2322. gtk_widget_show (button);
  2323. g_signal_connect (G_OBJECT (button), "clicked",
  2324. G_CALLBACK (CancelSell), (gpointer)0);
  2325. button = gtk_button_new_from_stock (GTK_STOCK_YES);
  2326. gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 3);
  2327. gtk_widget_show (button);
  2328. gtk_window_set_focus (GTK_WINDOW (window), button);
  2329. g_signal_connect (G_OBJECT (button), "clicked",
  2330. G_CALLBACK (CancelSell), (gpointer)1);
  2331. }
  2332. /*
  2333. * El callback asociado al calendario que se encuentra en la venta
  2334. * para cancelar ventas
  2335. */
  2336. void
  2337. CancelSellDaySelected(GtkCalendar *calendar,gpointer data)
  2338. {
  2339. GtkTreeIter iter;
  2340. PGresult *res;
  2341. gint tuples, i;
  2342. guint year,month,day;
  2343. gtk_calendar_get_date(calendar,&year,&month,&day);
  2344. gchar *q = NULL;
  2345. q = g_strdup_printf("SELECT venta.id, users.usuario,monto FROM venta "
  2346. "INNER JOIN users ON users.id = venta.vendedor "
  2347. "WHERE date_trunc('day',fecha) = '%.4d-%.2d-%.2d' "
  2348. "AND canceled = FALSE",
  2349. year,month+1,day);
  2350. res = EjecutarSQL (q);
  2351. g_free(q);
  2352. tuples = PQntuples (res);
  2353. gtk_list_store_clear (venta->cancel_store);
  2354. for (i = 0; i < tuples; i++)
  2355. {
  2356. gtk_list_store_append (venta->cancel_store, &iter);
  2357. gtk_list_store_set (venta->cancel_store, &iter,
  2358. 0, PQvaluebycol (res, i, "id"),
  2359. 1, PQvaluebycol (res, i, "usuario"),
  2360. 2, PQvaluebycol (res, i, "monto"),
  2361. -1);
  2362. }
  2363. }
  2364. void
  2365. CancelSellViewDetails(GtkTreeView *tree_view, gpointer user_data)
  2366. {
  2367. gchar *q = NULL;
  2368. int i,tuples;
  2369. gchar *id_venta=NULL;
  2370. PGresult *res;
  2371. GtkTreeIter iter_detail,iter;
  2372. GtkTreeSelection *selection;
  2373. gtk_list_store_clear(venta->cancel_store_details);
  2374. selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (venta->cancel_tree));
  2375. if (gtk_tree_selection_get_selected (selection, NULL, &iter) == TRUE)
  2376. {
  2377. gtk_tree_model_get (GTK_TREE_MODEL (venta->cancel_store), &iter,
  2378. 0, &id_venta,
  2379. -1);
  2380. q = g_strdup_printf("SELECT producto.descripcion|| ' ' ||producto.marca, "
  2381. "cantidad, (venta_detalle.precio * cantidad) "
  2382. "FROM venta_detalle inner join producto on "
  2383. "venta_detalle.barcode = producto.barcode "
  2384. "WHERE id_venta=%s",
  2385. id_venta);
  2386. res = EjecutarSQL (q);
  2387. g_free(q);
  2388. tuples = PQntuples (res);
  2389. for (i = 0; i < tuples; i++)
  2390. {
  2391. gtk_list_store_append (venta->cancel_store_details, &iter_detail);
  2392. gtk_list_store_set (venta->cancel_store_details, &iter_detail,
  2393. 0, PQgetvalue (res, i, 0),
  2394. 1, PQgetvalue (res, i, 1),
  2395. 2, PQgetvalue (res, i, 2),
  2396. -1);
  2397. }
  2398. }
  2399. }
  2400. /**
  2401. * This function shows (and hide) the corresponding widgets
  2402. * as the selection made.
  2403. *
  2404. * @param: GtkToggleButton *togglebutton
  2405. * @param: gpointer user_data
  2406. */
  2407. void
  2408. change_pay2_mode (GtkToggleButton *togglebutton, gpointer user_data)
  2409. {
  2410. //The "Efectivo" toggle button
  2411. if (gtk_toggle_button_get_active (togglebutton))
  2412. {
  2413. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_int_amount_mixed_pay2")));
  2414. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "entry_rut_mixed_pay_2")), FALSE);
  2415. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_rut_mixed_pay_2")), "");
  2416. gtk_label_set_text (GTK_LABEL (builder_get (builder, "lbl_name_mixed_pay_2")), "");
  2417. }
  2418. else
  2419. {
  2420. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "entry_rut_mixed_pay_2")), TRUE);
  2421. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_rut_mixed_pay_2")));
  2422. }
  2423. }
  2424. /*
  2425. * callback asociado a boton 'cancelar venta' para la costruccion de
  2426. * la ventana para cancelar una venta
  2427. */
  2428. void
  2429. CancelWindow (GtkWidget *widget, gpointer data)
  2430. {
  2431. GtkTreeViewColumn *column;
  2432. GtkCellRenderer *renderer;
  2433. GtkWidget *scroll;
  2434. GtkWidget *hbox;
  2435. GtkWidget *vbox;
  2436. GtkWidget *button;
  2437. GtkWidget *entry;
  2438. GtkWidget *calendario;
  2439. venta->cancel_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  2440. gtk_window_set_title (GTK_WINDOW (venta->cancel_window), "Cancelar Venta");
  2441. gtk_window_set_position (GTK_WINDOW (venta->cancel_window), GTK_WIN_POS_CENTER_ALWAYS);
  2442. gtk_window_present (GTK_WINDOW (venta->cancel_window));
  2443. gtk_window_set_resizable (GTK_WINDOW (venta->cancel_window), FALSE);
  2444. g_signal_connect (G_OBJECT (venta->cancel_window), "destroy",
  2445. G_CALLBACK (CloseCancelWindow), NULL);
  2446. vbox = gtk_vbox_new (FALSE, 3);
  2447. gtk_container_add (GTK_CONTAINER (venta->cancel_window), vbox);
  2448. hbox = gtk_hbox_new (FALSE, 3);//principal
  2449. gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 3);
  2450. GtkWidget *vbox_izquierda = gtk_vbox_new(FALSE,3);
  2451. gtk_box_pack_start(GTK_BOX(hbox),vbox_izquierda,FALSE,FALSE,3);
  2452. GtkWidget *hbox_busqueda = gtk_hbox_new(FALSE,3);
  2453. gtk_box_pack_start(GTK_BOX(vbox_izquierda),hbox_busqueda,FALSE,FALSE,3);
  2454. //entry de busqueda
  2455. entry = gtk_entry_new ();
  2456. gtk_window_set_focus (GTK_WINDOW (venta->cancel_window), entry);
  2457. gtk_box_pack_start (GTK_BOX (hbox_busqueda), entry, FALSE, FALSE, 3);
  2458. g_signal_connect (G_OBJECT (entry), "activate",
  2459. G_CALLBACK (FindCancelSell), (gpointer) entry);
  2460. //boton de busqueda
  2461. button = gtk_button_new_from_stock (GTK_STOCK_FIND);
  2462. gtk_box_pack_end (GTK_BOX (hbox_busqueda), button, FALSE, FALSE, 3);
  2463. g_signal_connect (G_OBJECT (button), "clicked",
  2464. G_CALLBACK (FindCancelSell), (gpointer) entry);
  2465. /* calendario */
  2466. GtkWidget *expansor = gtk_expander_new("Calendario");
  2467. calendario = gtk_calendar_new();
  2468. g_signal_connect(G_OBJECT(calendario),"day-selected-double-click",
  2469. G_CALLBACK (CancelSellDaySelected),NULL);
  2470. gtk_container_add(GTK_CONTAINER(expansor),calendario);
  2471. gtk_box_pack_start(GTK_BOX(vbox_izquierda),expansor,FALSE,FALSE,0);
  2472. /* fin calendario */
  2473. GtkWidget *vbox_derecha = gtk_vbox_new(FALSE,3);
  2474. gtk_box_pack_start(GTK_BOX(hbox),vbox_derecha,FALSE,FALSE,0);
  2475. scroll = gtk_scrolled_window_new (NULL, NULL);
  2476. gtk_widget_set_size_request (scroll, -1, 150);
  2477. gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
  2478. GTK_POLICY_AUTOMATIC,
  2479. GTK_POLICY_AUTOMATIC);
  2480. gtk_box_pack_start (GTK_BOX (vbox_izquierda), scroll, FALSE, FALSE, 0);
  2481. //tree de ventas
  2482. venta->cancel_store = gtk_list_store_new (3,
  2483. G_TYPE_STRING,
  2484. G_TYPE_STRING,
  2485. G_TYPE_STRING);
  2486. venta->cancel_tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (venta->cancel_store));
  2487. gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (venta->cancel_tree), TRUE);
  2488. gtk_container_add (GTK_CONTAINER (scroll), venta->cancel_tree);
  2489. g_signal_connect (G_OBJECT (venta->cancel_tree), "row-activated",
  2490. G_CALLBACK (CancelSellViewDetails), NULL);
  2491. //ventas-ID
  2492. renderer = gtk_cell_renderer_text_new ();
  2493. column = gtk_tree_view_column_new_with_attributes ("ID Venta", renderer,
  2494. "text", 0,
  2495. NULL);
  2496. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->cancel_tree), column);
  2497. gtk_tree_view_column_set_alignment (column, 0.5);
  2498. g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
  2499. gtk_tree_view_column_set_resizable (column, FALSE);
  2500. //ventas-Vendedor
  2501. renderer = gtk_cell_renderer_text_new ();
  2502. column = gtk_tree_view_column_new_with_attributes ("Vendedor", renderer,
  2503. "text", 1,
  2504. NULL);
  2505. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->cancel_tree), column);
  2506. gtk_tree_view_column_set_alignment (column, 0.5);
  2507. g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
  2508. gtk_tree_view_column_set_resizable (column, FALSE);
  2509. //total de la venta
  2510. renderer = gtk_cell_renderer_text_new ();
  2511. column = gtk_tree_view_column_new_with_attributes ("Total", renderer,
  2512. "text", 2,
  2513. NULL);
  2514. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->cancel_tree), column);
  2515. gtk_tree_view_column_set_alignment (column, 0.5);
  2516. g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
  2517. gtk_tree_view_column_set_resizable (column, FALSE);
  2518. /////////////////////////
  2519. //detalles de la venta //
  2520. /////////////////////////
  2521. scroll = gtk_scrolled_window_new (NULL, NULL);
  2522. gtk_widget_set_size_request (scroll, -1, 100);
  2523. gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
  2524. GTK_POLICY_AUTOMATIC,
  2525. GTK_POLICY_AUTOMATIC);
  2526. gtk_box_pack_start (GTK_BOX (vbox_izquierda), scroll, FALSE, FALSE, 0);
  2527. venta->cancel_store_details = gtk_list_store_new (3,
  2528. G_TYPE_STRING,
  2529. G_TYPE_STRING,
  2530. G_TYPE_STRING);
  2531. //tree de ventas
  2532. venta->cancel_tree_details = gtk_tree_view_new_with_model (GTK_TREE_MODEL (venta->cancel_store_details));
  2533. gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (venta->cancel_tree_details), TRUE);
  2534. gtk_container_add (GTK_CONTAINER (scroll), venta->cancel_tree_details);
  2535. // g_signal_connect (G_OBJECT (venta->cancel_tree), "row-activated",
  2536. // G_CALLBACK (AskCancelSell), NULL);
  2537. ////////////////////////
  2538. //descripcion-marca
  2539. renderer = gtk_cell_renderer_text_new ();
  2540. column = gtk_tree_view_column_new_with_attributes ("Descripcion", renderer,
  2541. "text", 0,
  2542. NULL);
  2543. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->cancel_tree_details), column);
  2544. gtk_tree_view_column_set_alignment (column, 0.5);
  2545. g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
  2546. gtk_tree_view_column_set_resizable (column, FALSE);
  2547. //cantidad
  2548. renderer = gtk_cell_renderer_text_new ();
  2549. column = gtk_tree_view_column_new_with_attributes ("Cant.", renderer,
  2550. "text", 1,
  2551. NULL);
  2552. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->cancel_tree_details), column);
  2553. gtk_tree_view_column_set_alignment (column, 0.5);
  2554. g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
  2555. gtk_tree_view_column_set_resizable (column, FALSE);
  2556. //subtotal = (precio*cantidad)
  2557. renderer = gtk_cell_renderer_text_new ();
  2558. column = gtk_tree_view_column_new_with_attributes ("SubTotal", renderer,
  2559. "text", 2,
  2560. NULL);
  2561. gtk_tree_view_append_column (GTK_TREE_VIEW (venta->cancel_tree_details), column);
  2562. gtk_tree_view_column_set_alignment (column, 0.5);
  2563. g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
  2564. gtk_tree_view_column_set_resizable (column, FALSE);
  2565. //boton para cancelar una venta
  2566. button = gtk_button_new_with_mnemonic ("_Cancelar Venta");
  2567. gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
  2568. g_signal_connect (G_OBJECT (button), "clicked",
  2569. G_CALLBACK (AskCancelSell), NULL);
  2570. gtk_widget_show_all(venta->cancel_window);
  2571. }
  2572. void
  2573. CloseWindowChangeSeller (GtkWidget *widget, gpointer data)
  2574. {
  2575. GtkWidget *aux_widget;
  2576. aux_widget = GTK_WIDGET (gtk_builder_get_object (builder, "window_change_seller"));
  2577. gtk_widget_hide (aux_widget);
  2578. aux_widget = GTK_WIDGET(gtk_builder_get_object(builder, "entry_user_vendedor"));
  2579. gtk_entry_set_text(GTK_ENTRY(aux_widget), "");
  2580. aux_widget = GTK_WIDGET(gtk_builder_get_object(builder, "entry_pass_vendedor"));
  2581. gtk_entry_set_text(GTK_ENTRY(aux_widget), "");
  2582. aux_widget = GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry"));
  2583. gtk_widget_grab_focus (aux_widget);
  2584. }
  2585. void
  2586. ChangeSeller (GtkWidget *widget, gpointer data)
  2587. {
  2588. GtkEntry *entry;
  2589. gchar *user;
  2590. gchar *passwd;
  2591. entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_user_vendedor"));
  2592. user = g_strdup (gtk_entry_get_text (entry));
  2593. entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_pass_vendedor"));
  2594. passwd = g_strdup (gtk_entry_get_text (entry));
  2595. if (g_str_equal (user, "") || g_str_equal (passwd, ""))
  2596. {
  2597. ErrorMSG (widget, g_strdup_printf
  2598. ("Debe ingresar usuario y contraseña"));
  2599. return;
  2600. }
  2601. if (AcceptPassword (passwd, user))
  2602. {
  2603. user_data->user_id = ReturnUserId (user);
  2604. user_data->user = g_strdup (user);
  2605. user_data->level = ReturnUserLevel (user);
  2606. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_seller_name")),
  2607. g_strdup_printf ("<span size=\"15000\">%s</span>", user_data->user));
  2608. CloseWindowChangeSeller (widget, NULL);
  2609. }
  2610. else
  2611. {
  2612. ErrorMSG (widget, g_strdup_printf
  2613. ("Usuario o contraseña incorrecta"));
  2614. }
  2615. }
  2616. /**
  2617. * Es llamada cuando el boton "btn_change_seller" es presionado (signal click).
  2618. *
  2619. * Esta funcion visualiza la ventana "window_change_seller" y deja el foco en
  2620. * el "entry_id_vendedor"
  2621. *
  2622. */
  2623. void
  2624. WindowChangeSeller ()
  2625. {
  2626. GtkWindow *window;
  2627. window = GTK_WINDOW (gtk_builder_get_object (builder, "window_change_seller"));
  2628. gtk_widget_show_all (GTK_WIDGET (window));
  2629. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_user_vendedor")));
  2630. }
  2631. /**
  2632. * Funcion Principal
  2633. *
  2634. * Carga los valores de rizoma-login.ui y visualiza la ventana del
  2635. * login "login_window", ademas de cargar el archivo de configuracion "/.rizoma"
  2636. *
  2637. */
  2638. int
  2639. main (int argc, char **argv)
  2640. {
  2641. GtkWindow *login_window;
  2642. GError *err = NULL;
  2643. GtkComboBox *combo;
  2644. GtkListStore *model;
  2645. GtkTreeIter iter;
  2646. GtkCellRenderer *cell;
  2647. GKeyFile *key_file;
  2648. gchar **profiles;
  2649. key_file = rizoma_open_config();
  2650. if (key_file == NULL)
  2651. {
  2652. g_error ("Cannot open config file\n");
  2653. return -1;
  2654. }
  2655. gtk_init (&argc, &argv);
  2656. builder = gtk_builder_new ();
  2657. gtk_builder_add_from_file (builder, DATADIR"/ui/rizoma-login.ui", &err);
  2658. if (err)
  2659. {
  2660. g_error ("ERROR: %s\n", err->message);
  2661. return -1;
  2662. }
  2663. gtk_builder_connect_signals (builder, NULL);
  2664. login_window = GTK_WINDOW(gtk_builder_get_object (builder, "login_window"));
  2665. profiles = g_key_file_get_groups (key_file, NULL);
  2666. g_key_file_free (key_file);
  2667. model = gtk_list_store_new (1,
  2668. G_TYPE_STRING);
  2669. combo = (GtkComboBox *) gtk_builder_get_object (builder, "combo_profile");
  2670. cell = gtk_cell_renderer_text_new ();
  2671. gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(combo), cell, TRUE);
  2672. gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT(combo), cell,
  2673. "text", 0,
  2674. NULL);
  2675. do
  2676. {
  2677. if (*profiles != NULL)
  2678. {
  2679. gtk_list_store_append (model, &iter);
  2680. gtk_list_store_set (model, &iter,
  2681. 0, *profiles,
  2682. -1
  2683. );
  2684. g_free (*profiles);
  2685. }
  2686. } while (*profiles++ != NULL);
  2687. gtk_combo_box_set_model (combo, (GtkTreeModel *)model);
  2688. gtk_combo_box_set_active (combo, 0);
  2689. /*El perfil se elije al seleccionar un grupo,
  2690. pero por defecto se seleccionará el del primero*/
  2691. gchar *group_name;
  2692. gtk_combo_box_get_active_iter (combo, &iter);
  2693. gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter,
  2694. 0, &group_name,
  2695. -1);
  2696. rizoma_set_profile (group_name);
  2697. //Inicia la ventana de venta de acuerdo al tipo de login en el .rizoma
  2698. if (rizoma_get_value_boolean ("ONLY_PASSWORD"))
  2699. {
  2700. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "user_entry")));
  2701. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "label1")));
  2702. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "passwd_entry")));
  2703. }
  2704. gtk_widget_show ((GtkWidget *)login_window);
  2705. gtk_main();
  2706. return 0;
  2707. }
  2708. /**
  2709. * Connected to accept button of the login window
  2710. *
  2711. * This funcion is in charge of validate the user/password and then
  2712. * call the initialization functions
  2713. *
  2714. * @param widget the widget that emits the signal
  2715. * @param data the user data
  2716. */
  2717. void
  2718. check_passwd (GtkWidget *widget, gpointer data)
  2719. {
  2720. GtkTreeIter iter;
  2721. GtkComboBox *combo = (GtkComboBox *) gtk_builder_get_object (builder, "combo_profile");
  2722. GtkTreeModel *model = gtk_combo_box_get_model (combo);
  2723. gchar *group_name;
  2724. gchar *passwd;
  2725. gchar *user;
  2726. gboolean only_password;
  2727. gboolean valido;
  2728. //Se obtiene la configuración del .rizoma
  2729. only_password = rizoma_get_value_boolean ("ONLY_PASSWORD");
  2730. //Se obtiene el grupo seleccionado
  2731. gtk_combo_box_get_active_iter (combo, &iter);
  2732. gtk_tree_model_get (model, &iter,
  2733. 0, &group_name,
  2734. -1);
  2735. rizoma_set_profile (group_name);
  2736. //Obtiene los datos necesarios
  2737. if (!only_password)
  2738. {
  2739. passwd = g_strdup (gtk_entry_get_text ( (GtkEntry *) gtk_builder_get_object (builder,"passwd_entry")));
  2740. user = g_strdup (gtk_entry_get_text ( (GtkEntry *) gtk_builder_get_object (builder,"user_entry")));
  2741. valido = AcceptPassword (passwd, user);
  2742. }
  2743. else
  2744. {
  2745. passwd = g_strdup (gtk_entry_get_text ( (GtkEntry *) gtk_builder_get_object (builder,"passwd_entry")));
  2746. user = AcceptOnlyPassword (passwd);
  2747. valido = g_str_equal (user, "") ? FALSE : TRUE;
  2748. }
  2749. switch (valido)
  2750. {
  2751. case TRUE:
  2752. user_data = (User *) g_malloc (sizeof (User));
  2753. user_data->user_id = ReturnUserId (user);
  2754. user_data->level = ReturnUserLevel (user);
  2755. user_data->user = user;
  2756. Asistencia (user_data->user_id, TRUE);
  2757. log_register_access (user_data, TRUE);
  2758. gtk_widget_destroy (GTK_WIDGET(gtk_builder_get_object (builder,"login_window")));
  2759. g_object_unref ((gpointer) builder);
  2760. builder = NULL;
  2761. ventas_win();
  2762. break;
  2763. case FALSE:
  2764. gtk_entry_set_text ((GtkEntry *) gtk_builder_get_object (builder,"user_entry"), "");
  2765. gtk_entry_set_text ((GtkEntry *) gtk_builder_get_object (builder,"passwd_entry"), "");
  2766. if (only_password)
  2767. rizoma_error_window ((GtkWidget *) gtk_builder_get_object (builder,"passwd_entry"));
  2768. else
  2769. rizoma_error_window ((GtkWidget *) gtk_builder_get_object (builder,"user_entry"));
  2770. break;
  2771. default:
  2772. break;
  2773. }
  2774. }
  2775. /**
  2776. * Callback connected to delete-event of the sales window and the exit
  2777. * button in the same window.
  2778. *
  2779. * Checks if must be closed the caja, if must be closed then calls the
  2780. * propers functions, otherwise raise the confirmation dialog.
  2781. *
  2782. * Note: do not use the parameters of this function, because they are
  2783. * not secure.
  2784. *
  2785. * @param widget the widget that emits the signal
  2786. * @param event the event
  2787. * @param data the user data
  2788. *
  2789. * @return TRUE to stop other handlers of being invoked
  2790. */
  2791. gboolean
  2792. on_delete_ventas_gui (GtkWidget *widget, GdkEvent *event, gpointer data)
  2793. {
  2794. GtkWidget *window;
  2795. window = GTK_WIDGET (gtk_builder_get_object (builder, "quit_message"));
  2796. gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_YES);
  2797. gtk_widget_show_all (window);
  2798. return TRUE;
  2799. }
  2800. /**
  2801. * Callback connected to response signal emited by the confirmation
  2802. * dialog of rizoma-ventas
  2803. *
  2804. * This function must contain all the necesary finalization code, like
  2805. * the exit time of the sales man
  2806. *
  2807. * @param dialog the dialog that emits the signal
  2808. * @param response_id the response
  2809. * @param data the user data
  2810. */
  2811. void
  2812. exit_response (GtkDialog *dialog, gint response_id, gpointer data)
  2813. {
  2814. if (response_id == GTK_RESPONSE_YES)
  2815. {
  2816. Asistencia (user_data->user_id, FALSE);
  2817. log_register_access (user_data, FALSE);
  2818. gtk_main_quit();
  2819. }
  2820. else
  2821. if (response_id == GTK_RESPONSE_NO)
  2822. gtk_widget_hide (GTK_WIDGET (dialog));
  2823. }
  2824. /**
  2825. * related with the credit sale
  2826. */
  2827. void
  2828. on_btn_credit_sale_clicked (GtkButton *button, gpointer data)
  2829. {
  2830. GtkWidget *widget;
  2831. gint tipo_documento;
  2832. gint rut;
  2833. gchar *dv;
  2834. gchar *str_rut;
  2835. gchar **str_splited;
  2836. gint vendedor;
  2837. gint tipo_vendedor;
  2838. gint ticket;
  2839. gint monto;
  2840. gint maquina;
  2841. gchar *discount;
  2842. gboolean canceled;
  2843. if (g_str_equal (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_credit_rut"))), "") ||
  2844. gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_credit_rut"))) == NULL)
  2845. {
  2846. search_client (GTK_WIDGET (builder_get (builder, "entry_credit_rut")), NULL);
  2847. return;
  2848. }
  2849. str_splited = parse_rut (g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_credit_rut")))));
  2850. rut = atoi(str_splited[0]);
  2851. dv = g_strdup(str_splited[1]);
  2852. g_free (str_splited);
  2853. str_rut = g_strdup_printf("%d-%s",rut,dv);
  2854. tipo_vendedor = rizoma_get_value_int ("VENDEDOR");
  2855. //amount
  2856. widget = GTK_WIDGET(gtk_builder_get_object(builder, "label_total"));
  2857. monto = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (widget)))));
  2858. //maquina
  2859. maquina = rizoma_get_value_int ("MAQUINA");
  2860. //salesman
  2861. vendedor = user_data->user_id;
  2862. if (!(RutExist(str_rut)))
  2863. {
  2864. gchar *motivo;
  2865. widget = gtk_widget_get_ancestor(GTK_WIDGET(button),GTK_TYPE_WINDOW);
  2866. motivo = g_strdup_printf("El rut %d no existe", rut);
  2867. AlertMSG(widget, motivo);
  2868. g_free (motivo);
  2869. return;
  2870. }
  2871. if (tiene_limite_credito (rut) &&
  2872. LimiteCredito (str_rut) < (DeudaTotalCliente (rut) + monto))
  2873. {
  2874. gtk_widget_show (GTK_WIDGET (builder_get (builder, "msg_credit_out")));
  2875. return;
  2876. }
  2877. /* if (tipo_vendedor == 1) */
  2878. /* tipo_documento = VENTA; */
  2879. /* else */
  2880. tipo_documento = SIMPLE;
  2881. //if (tipo_documento != VENTA)
  2882. if (tipo_vendedor != 1)
  2883. {
  2884. GtkWidget *wid;
  2885. wid = GTK_WIDGET (gtk_builder_get_object (builder,"entry_discount_percent"));
  2886. if (g_str_equal (gtk_entry_get_text (GTK_ENTRY (wid)),""))
  2887. discount = "0";
  2888. else
  2889. discount = g_strdup(gtk_entry_get_text (GTK_ENTRY (wid)));
  2890. }
  2891. else
  2892. discount = "0";
  2893. switch (tipo_documento)
  2894. {
  2895. case SIMPLE: case VENTA:
  2896. if (monto >= 180)
  2897. ticket = get_ticket_number (tipo_documento);
  2898. else
  2899. ticket = -1;
  2900. break;
  2901. /* case VENTA: */
  2902. /* ticket = -1; */
  2903. /* break; */
  2904. default:
  2905. g_printerr("The document type could not be matched on %s", G_STRFUNC);
  2906. ticket = -1;
  2907. break;
  2908. }
  2909. // TODO: Queda temporalmente comentado hasta que de implemente completamente
  2910. // la funcionalidad de pre-venta
  2911. /* if (tipo_documento == VENTA) */
  2912. /* canceled = FALSE; */
  2913. /* else */
  2914. canceled = TRUE;
  2915. SaveSell (monto, maquina, vendedor, CREDITO, str_rut, discount, ticket, tipo_documento,
  2916. NULL, FALSE, canceled, FALSE);
  2917. //clean the interface
  2918. gtk_widget_hide (gtk_widget_get_toplevel (GTK_WIDGET (button)));
  2919. gtk_widget_hide (GTK_WIDGET(gtk_builder_get_object(builder, "wnd_sale_type")));
  2920. gtk_widget_hide (GTK_WIDGET(gtk_builder_get_object(builder, "tipo_venta_win_venta")));
  2921. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  2922. gtk_list_store_clear (venta->store);
  2923. CleanEntryAndLabelData();
  2924. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_total")), "");
  2925. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_ticket_number")),
  2926. g_strdup_printf ("<span size=\"15000\">%.6d</span>", get_ticket_number (SIMPLE)-1)); //antes get_last_sell_id ()
  2927. clean_credit_data();
  2928. ListClean ();
  2929. }
  2930. /**
  2931. *
  2932. */
  2933. void
  2934. on_btn_reserva_ok_clicked (GtkButton *button, gpointer data)
  2935. {
  2936. gint rut;
  2937. gint vendedor;
  2938. gint maquina;
  2939. gint id_reserva;
  2940. gchar *dv;
  2941. gchar *str_rut;
  2942. gchar **str_splited;
  2943. gchar *str_date;
  2944. GDate *date_aux;
  2945. if (venta->products == NULL)
  2946. {
  2947. ErrorMSG (GTK_WIDGET (gtk_builder_get_object (builder, "btn_cancel_reserva")), "No hay productos para realizar el encargo");
  2948. return;
  2949. }
  2950. if (g_str_equal (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_reserva_rut"))), "") ||
  2951. gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_reserva_rut"))) == NULL)
  2952. {
  2953. search_client (GTK_WIDGET (builder_get (builder, "entry_reserva_rut")), NULL);
  2954. return;
  2955. }
  2956. str_splited = parse_rut (g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_reserva_rut")))));
  2957. rut = atoi(str_splited[0]);
  2958. dv = g_strdup(str_splited[1]);
  2959. g_free (str_splited);
  2960. str_rut = g_strdup_printf("%d-%s",rut,dv);
  2961. //maquina
  2962. maquina = rizoma_get_value_int ("MAQUINA");
  2963. //salesman
  2964. vendedor = user_data->user_id;
  2965. if (!(RutExist(str_rut)))
  2966. {
  2967. AlertMSG (GTK_WIDGET (builder_get (builder, "entry_reserva_rut")),
  2968. g_strdup_printf ("El rut %d no existe", rut));
  2969. return;
  2970. }
  2971. //Obtener la fecha y asegurarse de que no sea más antigua de hoy
  2972. str_date = g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_fecha_reserva"))));
  2973. if (g_str_equal (str_date, ""))
  2974. {
  2975. AlertMSG (GTK_WIDGET (builder_get (builder, "entry_fecha_reserva")),
  2976. "Debe seleccionar una fecha de entrega para este pedido");
  2977. return;
  2978. }
  2979. date_aux = g_date_new();
  2980. g_date_set_parse (date_aux, str_date);
  2981. //Obtener los datos de la venta y registrarlo como 'pedido'
  2982. id_reserva = registrar_reserva (maquina, vendedor, rut, date_aux);
  2983. venta->deuda_total = CalcularTotal (venta->header);
  2984. clean_container (GTK_CONTAINER (builder_get (builder, "wnd_reserva")));
  2985. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_reserva")));
  2986. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  2987. //Si esta como punto de pre-venta no se maneja dinero, por tanto no posibilidad de abono
  2988. if (rizoma_get_value_boolean ("PREVENTA"))
  2989. {
  2990. //Se limpian el store, la estructura y los labels
  2991. gtk_list_store_clear (venta->store);
  2992. PrintValePreVentaReserva (venta->header, id_reserva, "RV");
  2993. ListClean (); //Limpia la estructura de productos de reserva
  2994. CleanEntryAndLabelData();
  2995. }
  2996. else
  2997. {
  2998. //Abonar a reserva
  2999. venta_reserva = TRUE;
  3000. venta->total_pagado = 0;
  3001. venta->rut_cliente = rut;
  3002. venta->id_reserva = id_reserva;
  3003. TipoVenta (NULL, NULL);
  3004. }
  3005. }
  3006. /**
  3007. *
  3008. */
  3009. void
  3010. on_btn_preventa_ok_clicked (GtkButton *button, gpointer data)
  3011. {
  3012. gint vendedor;
  3013. gint maquina;
  3014. gint id_preventa;
  3015. if (venta->header == NULL)
  3016. {
  3017. ErrorMSG (GTK_WIDGET (gtk_builder_get_object (builder, "btn_cancel_preventa")), "No hay productos para vender");
  3018. return;
  3019. }
  3020. //maquina
  3021. maquina = rizoma_get_value_int ("MAQUINA");
  3022. //salesman
  3023. vendedor = user_data->user_id;
  3024. //Obtener los datos de la venta y registrarlo como 'preventa'
  3025. id_preventa = registrar_preventa (maquina, vendedor);
  3026. PrintValePreVentaReserva (venta->header, id_preventa, "PV");
  3027. ListClean (); //Limpia la estructura de productos de reserva
  3028. //Se limpian el store y los labels
  3029. gtk_list_store_clear (venta->store);
  3030. CleanEntryAndLabelData();
  3031. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_preventa")));
  3032. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  3033. }
  3034. /**
  3035. * callback 'entry_numero_mesa' and 'btn_cambiar_mesa_ok'
  3036. */
  3037. void
  3038. on_btn_cambiar_mesa_ok_clicked (GtkWidget *widget, gpointer data)
  3039. {
  3040. gchar *num_mesa;
  3041. PGresult *res;
  3042. gchar *q, *color;
  3043. gint i, tuples;
  3044. gdouble iva, otros;
  3045. GtkListStore *sell = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (builder_get (builder, "sell_products_list"))));
  3046. GtkTreeIter iter;
  3047. num_mesa = g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_numero_mesa"))));
  3048. if (HaveCharacters (num_mesa))
  3049. {
  3050. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_numero_mesa")),
  3051. "El número de la mesa debe ser un valor numérico");
  3052. return;
  3053. }
  3054. venta->num_mesa = atoi (num_mesa);
  3055. //Limpia la estructura de productos
  3056. ListClean ();
  3057. //Se limpian el store y los labels
  3058. gtk_list_store_clear (venta->store);
  3059. CleanEntryAndLabelData();
  3060. //Consulta
  3061. q = g_strdup_printf ("SELECT * FROM mesa WHERE num_mesa = %d", venta->num_mesa);
  3062. res = EjecutarSQL (q);
  3063. tuples = PQntuples (res);
  3064. //Revisa si la mesa existe
  3065. if (res != NULL && tuples > 0)
  3066. {
  3067. //- Si existe, rellena con los productos existentes
  3068. for (i = 0; i < tuples; i++)
  3069. {
  3070. AgregarALista (NULL, PQvaluebycol (res, i, "barcode"), strtod (PUT (PQvaluebycol (res, i, "cantidad_total")), (char **)NULL));
  3071. //Se reemplazan los 2 precios, para asegurarse que se venda con el precio puesto en el pedido, sin importar si la mercadería esta por mayor o no
  3072. venta->products->product->precio = strtod (PUT (PQvaluebycol (res, i, "precio")), (char **)NULL);
  3073. venta->products->product->precio_mayor = strtod (PUT (PQvaluebycol (res, i, "precio")), (char **)NULL);
  3074. venta->products->product->cantidad_impresa = strtod (PUT (PQvaluebycol (res, i, "cantidad_impresa")), (char **)NULL);
  3075. iva = (gdouble)venta->products->product->iva / 100;
  3076. otros = (gdouble)venta->products->product->otros / 100;
  3077. venta->products->product->precio_neto = (venta->products->product->precio / (1 + otros + iva));
  3078. /*Se elige el color de la fila*/
  3079. if (venta->products->product->cantidad <= venta->products->product->stock)
  3080. color = (venta->products->product->cantidad != venta->products->product->cantidad_impresa) ? g_strdup ("Blue") : g_strdup ("Black");
  3081. else /*Si la cantidad solicitada supera al stock*/
  3082. color = g_strdup ("Red");
  3083. gtk_list_store_insert_after (sell, &iter, NULL);
  3084. gtk_list_store_set (sell, &iter,
  3085. 0, venta->products->product->codigo,
  3086. 1, g_strdup_printf ("%s %s %d %s",
  3087. venta->products->product->producto,
  3088. venta->products->product->marca,
  3089. venta->products->product->contenido,
  3090. venta->products->product->unidad),
  3091. 2, venta->products->product->cantidad,
  3092. 3, venta->products->product->precio_neto,
  3093. 4, lround (venta->products->product->cantidad * venta->products->product->precio_neto),
  3094. 5, venta->products->product->precio,
  3095. 6, lround (venta->products->product->cantidad * venta->products->product->precio),
  3096. 7, venta->products->product->stock,
  3097. 8, venta->products->product->cantidad_impresa,
  3098. 9, color,
  3099. 10, TRUE,
  3100. -1);
  3101. venta->products->product->iter = iter;
  3102. //TODOOO: Color requiere de un g_free?... si un *gchar iniciado con g_strdup se libera con g_free, ¿se le puede volver asignar un valor?
  3103. }
  3104. CalcularVentas (venta->header);
  3105. }
  3106. //Setea el label con el numero de mesa
  3107. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "lbl_num_mesa")),
  3108. g_strdup_printf ("<span size=\"15000\">%d</span>", venta->num_mesa));
  3109. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_cambio_mesa")));
  3110. }
  3111. /**
  3112. *
  3113. */
  3114. void
  3115. on_btn_credit_clicked (GtkButton *button, gpointer data)
  3116. {
  3117. if (venta->header == NULL)
  3118. {
  3119. ErrorMSG (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")), "No hay productos para vender");
  3120. return;
  3121. }
  3122. gtk_widget_show_all (GTK_WIDGET (builder_get (builder, "wnd_sale_credit")));
  3123. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_credit_sale")), FALSE);
  3124. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_sale_type")));
  3125. }
  3126. void
  3127. on_btn_client_ok_clicked (GtkButton *button, gpointer data)
  3128. {
  3129. GtkWidget *aux;
  3130. GtkListStore *store;
  3131. GtkTreeSelection *selection;
  3132. GtkTreeIter iter;
  3133. gchar *rut, *dv;
  3134. PGresult *res;
  3135. gchar *q;
  3136. aux = GTK_WIDGET(gtk_builder_get_object(builder, "treeview_clients"));
  3137. store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(aux)));
  3138. selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(aux));
  3139. if (!(gtk_tree_selection_get_selected(selection, NULL, &iter)))
  3140. {
  3141. aux = GTK_WIDGET(gtk_builder_get_object(builder, "wnd_client_search"));
  3142. AlertMSG(aux, "Debe seleccionar un cliente");
  3143. return;
  3144. }
  3145. gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
  3146. 0, &rut,
  3147. -1);
  3148. aux = GTK_WIDGET(gtk_builder_get_object(builder, "wnd_client_search"));
  3149. gtk_widget_hide(aux);
  3150. dv = invested_strndup (rut, strlen (rut)-1);
  3151. rut = g_strndup (rut, strlen (rut)-1);
  3152. q = g_strdup_printf("SELECT nombre || ' ' || apell_p, direccion, telefono, giro from cliente where rut = %s", rut);
  3153. res = EjecutarSQL(q);
  3154. g_free (q);
  3155. rut = g_strdup_printf ("%s-%s", rut, dv);
  3156. if (gtk_widget_get_visible (GTK_WIDGET (builder_get (builder,"wnd_mixed_pay_step1"))))
  3157. {
  3158. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_rut_mixed_pay")), rut);
  3159. gtk_label_set_markup (GTK_LABEL (builder_get (builder, "lbl_name_mixed_pay")),
  3160. g_strdup_printf ("<b>%s</b>", PQgetvalue (res, 0, 0)));
  3161. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_int_amount_mixed_pay")));
  3162. }
  3163. else if (gtk_widget_get_visible (GTK_WIDGET (builder_get (builder,"wnd_mixed_pay_step2"))))
  3164. {
  3165. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_rut_mixed_pay_2")), rut);
  3166. gtk_label_set_markup (GTK_LABEL (builder_get (builder, "lbl_name_mixed_pay_2")),
  3167. g_strdup_printf ("<b>%s</b>", PQgetvalue (res, 0, 0)));
  3168. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_int_amount_mixed_pay2")));
  3169. }
  3170. else if (gtk_widget_get_visible (GTK_WIDGET(builder_get (builder,"wnd_sale_credit"))))
  3171. {
  3172. aux = GTK_WIDGET (gtk_builder_get_object(builder, "entry_credit_rut"));
  3173. gtk_entry_set_text (GTK_ENTRY(aux), rut);
  3174. aux = GTK_WIDGET(gtk_builder_get_object(builder, "btn_credit_sale"));
  3175. fill_credit_data(rut, PQgetvalue(res, 0, 0),
  3176. PQvaluebycol (res, 0, "direccion"),
  3177. PQvaluebycol (res, 0, "telefono"));
  3178. gtk_widget_grab_focus(aux);
  3179. }
  3180. else if (gtk_widget_get_visible (GTK_WIDGET (builder_get (builder,"wnd_sale_invoice"))))
  3181. {
  3182. aux = GTK_WIDGET (builder_get (builder, "entry_invoice_rut"));
  3183. gtk_entry_set_text (GTK_ENTRY(aux), rut);
  3184. aux = GTK_WIDGET (builder_get (builder, "lbl_invoice_name"));
  3185. gtk_label_set_text(GTK_LABEL(aux), PQgetvalue (res, 0, 0));
  3186. aux = GTK_WIDGET (builder_get (builder, "lbl_invoice_giro"));
  3187. gtk_label_set_text(GTK_LABEL(aux), PQvaluebycol(res, 0, "giro"));
  3188. aux = GTK_WIDGET (builder_get (builder, "lbl_direccion_factura"));
  3189. gtk_label_set_text(GTK_LABEL(aux), PQvaluebycol (res, 0, "direccion"));
  3190. aux = GTK_WIDGET (builder_get (builder, "lbl_telefono_factura"));
  3191. gtk_label_set_text(GTK_LABEL(aux), PQvaluebycol(res, 0, "telefono"));
  3192. aux = GTK_WIDGET (builder_get (builder, "btn_make_guide"));
  3193. gtk_widget_set_sensitive(aux, TRUE);
  3194. aux = GTK_WIDGET (builder_get (builder, "btn_make_invoice"));
  3195. gtk_widget_set_sensitive(aux, TRUE);
  3196. gtk_widget_grab_focus (aux);
  3197. }
  3198. else if (gtk_widget_get_visible (GTK_WIDGET (builder_get (builder,"wnd_reserva"))))
  3199. {
  3200. aux = GTK_WIDGET (builder_get (builder, "entry_reserva_rut"));
  3201. gtk_entry_set_text (GTK_ENTRY(aux), rut);
  3202. aux = GTK_WIDGET (builder_get (builder, "lbl_reserva_client_name"));
  3203. gtk_label_set_text(GTK_LABEL(aux), PQgetvalue (res, 0, 0));
  3204. aux = GTK_WIDGET (builder_get (builder, "lbl_reserva_client_addr"));
  3205. gtk_label_set_text(GTK_LABEL(aux), PQvaluebycol (res, 0, "direccion"));
  3206. aux = GTK_WIDGET (builder_get (builder, "lbl_reserva_client_phone"));
  3207. gtk_label_set_text(GTK_LABEL(aux), PQvaluebycol(res, 0, "telefono"));
  3208. aux = GTK_WIDGET (builder_get (builder, "btn_reserva_ok"));
  3209. gtk_widget_set_sensitive(aux, TRUE);
  3210. gtk_widget_grab_focus (aux);
  3211. }
  3212. else if (gtk_widget_get_visible (GTK_WIDGET (builder_get (builder,"wnd_cliente_pre_factura"))))
  3213. {
  3214. aux = GTK_WIDGET (builder_get (builder, "entry_rutcli_pre_factura"));
  3215. gtk_entry_set_text (GTK_ENTRY(aux), rut);
  3216. aux = GTK_WIDGET (builder_get (builder, "lbl_nombrecli_pre_factura"));
  3217. gtk_label_set_text(GTK_LABEL(aux), PQgetvalue (res, 0, 0));
  3218. aux = GTK_WIDGET (builder_get (builder, "lbl_dircli_pre_factura"));
  3219. gtk_label_set_text(GTK_LABEL(aux), PQvaluebycol (res, 0, "direccion"));
  3220. aux = GTK_WIDGET (builder_get (builder, "lbl_fonocli_pre_factura"));
  3221. gtk_label_set_text(GTK_LABEL(aux), PQvaluebycol(res, 0, "telefono"));
  3222. aux = GTK_WIDGET (builder_get (builder, "btn_selectcli_pre_factura"));
  3223. gtk_widget_set_sensitive(aux, TRUE);
  3224. gtk_widget_grab_focus (aux);
  3225. }
  3226. }
  3227. void
  3228. on_treeview_clients_row_activated (GtkTreeView *treeview, GtkTreePath *arg1, GtkTreeViewColumn *arg2, gpointer data)
  3229. {
  3230. on_btn_client_ok_clicked (NULL, NULL);
  3231. }
  3232. void
  3233. on_treeview_emisor_row_activated (GtkTreeView *treeview, GtkTreePath *arg1, GtkTreeViewColumn *arg2, gpointer data)
  3234. {
  3235. on_btn_ok_srch_emisor_clicked (NULL, NULL);
  3236. }
  3237. /**
  3238. * Es llamada cuando se presiona el boton "btn_cancel_sale_credit" (signal clicked)
  3239. *
  3240. * Esta funcion cierra la ventana "wnd_sale_invoice" y llama a la funcion
  3241. * "clean_credit_data" que limpia los datos de la venatan.
  3242. *
  3243. * @param button the button
  3244. * @param user_data the user data
  3245. */
  3246. void
  3247. on_btn_cancel_sale_credit_clicked (GtkButton *button, gpointer data)
  3248. {
  3249. GtkWidget *widget;
  3250. clean_credit_data();
  3251. widget = GTK_WIDGET(gtk_builder_get_object(builder, "wnd_sale_credit"));
  3252. gtk_widget_hide(widget);
  3253. }
  3254. /**
  3255. * Clean the information displayed in the credit client dialog
  3256. *
  3257. */
  3258. void
  3259. clean_credit_data ()
  3260. {
  3261. GtkWidget *widget;
  3262. widget = GTK_WIDGET(gtk_builder_get_object(builder, "entry_credit_rut"));
  3263. gtk_entry_set_text(GTK_ENTRY(widget), "");
  3264. gtk_widget_grab_focus(widget);
  3265. widget = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_client_name"));
  3266. gtk_label_set_text(GTK_LABEL(widget), "");
  3267. widget = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_client_addr"));
  3268. gtk_label_set_text(GTK_LABEL(widget), "");
  3269. widget = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_client_phone"));
  3270. gtk_label_set_text(GTK_LABEL(widget), "");
  3271. return;
  3272. }
  3273. /**
  3274. * Es llamada cuando se presiona el boton "btn_cancel_invoice" (signal clicked)
  3275. *
  3276. * Esta funcion cierra la ventana "wnd_sale_invoice"
  3277. *
  3278. * @param button the button
  3279. * @param user_data the user data
  3280. */
  3281. void
  3282. on_btn_cancel_invoice_clicked (GtkButton *button, gpointer data)
  3283. {
  3284. GtkWidget *widget;
  3285. widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_sale_invoice"));
  3286. clean_container (GTK_CONTAINER (widget));
  3287. gtk_widget_hide(widget);
  3288. }
  3289. /**
  3290. * Es llamada cuando se presiona el boton "btn_cancel_reserva" (signal clicked)
  3291. *
  3292. * Esta funcion cierra la ventana "wnd_reserva"
  3293. *
  3294. * @param button the button
  3295. * @param user_data the user data
  3296. */
  3297. void
  3298. on_btn_cancel_reserva_clicked (GtkButton *button, gpointer data)
  3299. {
  3300. GtkWidget *widget;
  3301. widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_reserva"));
  3302. clean_container (GTK_CONTAINER (widget));
  3303. gtk_widget_hide(widget);
  3304. }
  3305. /**
  3306. * Es llamada cuando se presiona el boton "btn_realizar_pedido" (signal clicked)
  3307. *
  3308. * Esta funcion muestra la ventana "wnd_reserva"
  3309. *
  3310. * @param button the button
  3311. * @param user_data the user data
  3312. */
  3313. void
  3314. on_btn_realizar_pedido_clicked (GtkButton *button, gpointer data)
  3315. {
  3316. GtkWidget *widget;
  3317. if (venta->products == NULL)
  3318. {
  3319. ErrorMSG (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")), "No hay productos para realizar el encargo");
  3320. return;
  3321. }
  3322. widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_reserva"));
  3323. gtk_widget_show(widget);
  3324. gtk_entry_set_text (GTK_ENTRY (builder_get (builder,"entry_fecha_reserva")), CurrentDate(1));
  3325. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_reserva_rut")));
  3326. }
  3327. /**
  3328. * Es llamada cuando se presiona el boton "btn_print_preventa" (signal clicked)
  3329. *
  3330. * Esta funcion muestra la ventana "wnd_preventa"
  3331. *
  3332. * @param button the button
  3333. * @param user_data the user data
  3334. */
  3335. void
  3336. on_btn_preventa_clicked (GtkButton *button, gpointer data)
  3337. {
  3338. GtkWidget *widget;
  3339. widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_preventa"));
  3340. gtk_widget_show (widget);
  3341. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "btn_preventa_ok")));
  3342. }
  3343. /**
  3344. * Es llamada cuando se presiona el boton "btn_close_win" (signal clicked)
  3345. * de la ventana "tipo_venta_win_venta"
  3346. *
  3347. * Esta funcion recalcula el total de la venta seteando el resultado en el
  3348. * texto del label "label_total" de la ventana "wnd_sell".
  3349. *
  3350. * NOTA: Esto es realizado evitar la permanencia (gráfica) de la cifra de
  3351. * venta total con descuento en caso de ser calculada y no realizar la venta
  3352. *
  3353. * @param button the button
  3354. * @param user_data the user data
  3355. */
  3356. void
  3357. on_btn_cancel_tipo_venta_win_venta (GtkButton *button, gpointer data)
  3358. {
  3359. guint32 total;
  3360. //Seteamos el Sub-Total y el Total
  3361. total = llround (CalcularTotal (venta->header));
  3362. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")),
  3363. g_strdup_printf ("<span size=\"40000\">%s</span>",
  3364. PutPoints (g_strdup_printf ("%u", total))));
  3365. if (venta_reserva)
  3366. {
  3367. //Se limpian el store, la estructura y los labels
  3368. gtk_list_store_clear (venta->store);
  3369. ListClean (); //Limpia la estructura de productos de reserva
  3370. CleanEntryAndLabelData();
  3371. }
  3372. }
  3373. /**
  3374. * Conected to the internal entry of the GtkComboBoxEntry that displays the rut
  3375. * of the clients when is being sold with invoice
  3376. *
  3377. * @param editable The entry
  3378. * @param user_data
  3379. */
  3380. void
  3381. on_entry_invoice_rut_activate (GtkEntry *entry, gpointer user_data)
  3382. {
  3383. /*
  3384. GtkWidget *widget;
  3385. PGresult *res;
  3386. gchar *rut;
  3387. gchar *q;
  3388. gchar **rut_split;
  3389. rut = g_strdup(gtk_entry_get_text(entry));
  3390. rut_split = g_strsplit(rut, "-", 2);
  3391. if (!(RutExist(rut)))
  3392. {
  3393. //the user with that rut does not exist so it is neccesary create a new client
  3394. gtk_window_set_modal(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(entry))), FALSE);
  3395. AddClient(NULL, NULL); //raise the window to add a proveedor
  3396. return;
  3397. }
  3398. q = g_strdup_printf("SELECT nombre, giro, direccion, telefono "
  3399. "FROM cliente WHERE rut = %s", rut_split[0]);
  3400. res = EjecutarSQL(q);
  3401. g_free (q);
  3402. g_strfreev (rut_split);
  3403. widget = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_invoice_name"));
  3404. gtk_label_set_text(GTK_LABEL(widget), PQvaluebycol(res, 0, "nombre"));
  3405. widget = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_invoice_giro"));
  3406. gtk_label_set_text(GTK_LABEL(widget), PQvaluebycol(res, 0, "giro"));
  3407. widget = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_direccion_factura"));
  3408. gtk_label_set_text(GTK_LABEL(widget), PQvaluebycol(res, 0, "giro"));
  3409. widget = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_telefono_factura"));
  3410. gtk_label_set_text(GTK_LABEL(widget), PQvaluebycol(res, 0, "giro"));
  3411. widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_make_invoice"));
  3412. gtk_widget_set_sensitive(widget, TRUE);
  3413. widget = GTK_WIDGET(gtk_builder_get_object(builder, "btn_make_guide"));
  3414. gtk_widget_set_sensitive(widget, TRUE);
  3415. */
  3416. search_client (GTK_WIDGET (entry), NULL);
  3417. }
  3418. /**
  3419. * Callback conected to the btn_sale_invoice button.
  3420. *
  3421. * This function setup the window and the show it
  3422. *
  3423. * @param button the button
  3424. * @param user_data the user data
  3425. */
  3426. void
  3427. on_btn_invoice_clicked (GtkButton *button, gpointer user_data)
  3428. {
  3429. GtkWidget *widget;
  3430. GtkEntryCompletion *completion;
  3431. GtkTreeModel *model;
  3432. GtkTreeIter iter;
  3433. PGresult *res;
  3434. gint i;
  3435. widget = GTK_WIDGET(gtk_builder_get_object(builder, "entry_invoice_rut"));
  3436. //only setup the completion if it wasn't configured previously
  3437. if (gtk_entry_get_completion(GTK_ENTRY(widget))== NULL)
  3438. {
  3439. completion = gtk_entry_completion_new();
  3440. gtk_entry_set_completion(GTK_ENTRY(widget), completion);
  3441. model = GTK_TREE_MODEL(gtk_list_store_new(1, G_TYPE_STRING));
  3442. gtk_entry_completion_set_model(completion, model);
  3443. gtk_entry_completion_set_text_column(completion, 0);
  3444. gtk_entry_completion_set_minimum_key_length(completion, 3);
  3445. }
  3446. else
  3447. model = gtk_entry_completion_get_model(gtk_entry_get_completion(GTK_ENTRY(widget)));
  3448. res = EjecutarSQL("select rut || '-' || dv from cliente order by rut asc");
  3449. gtk_list_store_clear (GTK_LIST_STORE(model));
  3450. for (i=0 ; i < PQntuples(res) ; i++)
  3451. {
  3452. gtk_list_store_append(GTK_LIST_STORE(model), &iter);
  3453. gtk_list_store_set(GTK_LIST_STORE(model), &iter,
  3454. 0, PQgetvalue(res, i, 0),
  3455. -1);
  3456. }
  3457. widget = GTK_WIDGET(gtk_builder_get_object(builder, "wnd_sale_invoice"));
  3458. gtk_widget_show_all(widget);
  3459. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_make_invoice")), FALSE);
  3460. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_make_guide")), FALSE);
  3461. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_invoice_rut")));
  3462. if (rizoma_get_value_boolean ("VENTA_SUSCRITO") && rut_cliente_pre_factura > 0)
  3463. {
  3464. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_invoice_rut")),
  3465. g_strdup_printf ("%d", rut_cliente_pre_factura));
  3466. on_entry_invoice_rut_activate (GTK_ENTRY (builder_get (builder, "entry_invoice_rut")),NULL);
  3467. search_client (GTK_WIDGET (builder_get (builder, "entry_search_client")),NULL);
  3468. on_btn_client_ok_clicked (GTK_BUTTON (builder_get (builder, "btn_client_ok")), NULL);
  3469. }
  3470. }
  3471. /**
  3472. * This callback is connected to the btn_make_invoice button.
  3473. *
  3474. * This function must take care of make the sale process using a invoice
  3475. *
  3476. * @param button the button
  3477. * @param data the user data
  3478. */
  3479. void
  3480. on_btn_make_invoice_clicked (GtkButton *button, gpointer data)
  3481. {
  3482. GtkWidget *widget;
  3483. gchar *str_rut;
  3484. gint rut;
  3485. gint vendedor;
  3486. //gint tipo_vendedor;
  3487. gint ticket;
  3488. gint monto;
  3489. gint maquina;
  3490. gchar *button_name;
  3491. gint tipo_documento;
  3492. button_name = g_strdup (gtk_buildable_get_name (GTK_BUILDABLE (button)));
  3493. //tipo_vendedor = rizoma_get_value_int ("VENDEDOR");
  3494. //amount
  3495. widget = GTK_WIDGET (builder_get (builder, "label_total"));
  3496. monto = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (widget)))));
  3497. //maquina
  3498. maquina = rizoma_get_value_int ("MAQUINA");
  3499. //salesman
  3500. vendedor = user_data->user_id;
  3501. //rut
  3502. widget = GTK_WIDGET(gtk_builder_get_object(builder, "entry_invoice_rut"));
  3503. str_rut = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
  3504. rut = atoi(strtok(g_strdup(str_rut),"-"));
  3505. if (!(RutExist(str_rut)))
  3506. {
  3507. gchar *motivo;
  3508. widget = gtk_widget_get_ancestor(GTK_WIDGET(button),GTK_TYPE_WINDOW);
  3509. motivo = g_strdup_printf("El rut %s no existe", str_rut);
  3510. AlertMSG(widget, motivo);
  3511. g_free (motivo);
  3512. return;
  3513. }
  3514. if (tiene_limite_credito ( atoi (strtok (g_strdup(str_rut),"-")) ) &&
  3515. LimiteCredito (str_rut) < (DeudaTotalCliente (rut) + monto))
  3516. {
  3517. widget = gtk_widget_get_ancestor(GTK_WIDGET(button),GTK_TYPE_WINDOW);
  3518. ErrorMSG (widget, "El cliente sobrepasa su limite de credito");
  3519. return;
  3520. }
  3521. if (g_str_equal (button_name, "btn_make_invoice")) {
  3522. tipo_documento = FACTURA;
  3523. ticket = get_ticket_number (FACTURA);
  3524. }
  3525. else if (g_str_equal (button_name, "btn_make_guide")) {
  3526. tipo_documento = GUIA;
  3527. ticket = get_ticket_number (GUIA);
  3528. }
  3529. SaveSell (monto, maquina, vendedor, CREDITO, str_rut, "0", ticket, tipo_documento,
  3530. NULL, FALSE, TRUE, FALSE);
  3531. //clean the interface
  3532. //restart the invoice dialog
  3533. widget = GTK_WIDGET(gtk_builder_get_object (builder, "entry_invoice_rut"));
  3534. gtk_entry_set_text (GTK_ENTRY(widget), "");
  3535. gtk_widget_grab_focus (widget);
  3536. gtk_list_store_clear(GTK_LIST_STORE(gtk_entry_completion_get_model(gtk_entry_get_completion(GTK_ENTRY(widget)))));
  3537. widget = GTK_WIDGET(gtk_builder_get_object (builder, "wnd_sale_invoice"));
  3538. clean_container (GTK_CONTAINER (widget));
  3539. gtk_widget_hide (widget);
  3540. //clean the main window
  3541. widget = GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry"));
  3542. gtk_widget_grab_focus (widget);
  3543. gtk_list_store_clear (venta->store);
  3544. CleanEntryAndLabelData();
  3545. ListClean ();
  3546. }
  3547. /**
  3548. * This function enters the sale when the amount
  3549. * entered is enough, else show the 'wnd_mixed_pay_step2'
  3550. * to complete. (signal-clicked)
  3551. *
  3552. * @param: GtkButton *button
  3553. * @param: gpointer data
  3554. */
  3555. void
  3556. on_btn_accept_mixed_pay_clicked (GtkButton *button, gpointer data)
  3557. {
  3558. gint total;
  3559. gint paga_con;
  3560. gchar *nombre_cliente, *rut_cliente, *paga_con_txt, *cod_chk_rest_gen;
  3561. gint maquina, vendedor, rut;
  3562. gint tipo_documento, ticket;
  3563. gchar **str_splited;
  3564. gboolean cheque_restaurant;
  3565. gboolean general;
  3566. //Widgets de la segunda ventana
  3567. GtkWidget *f_type_pay, *f_name, *f_rut, *f_amount, *f_code, *type_sell,
  3568. *s_name, *s_rut, *s_amount, *w_cr; //*diferencia
  3569. //Se obtienen todos los widget
  3570. f_type_pay = GTK_WIDGET (builder_get (builder, "lbl_mixed_pay_type"));
  3571. f_name = GTK_WIDGET (builder_get (builder, "lbl_mixed_pay_client_name"));
  3572. f_rut = GTK_WIDGET (builder_get (builder, "lbl_mixed_pay_client_rut"));
  3573. f_amount = GTK_WIDGET (builder_get (builder, "lbl_mixed_pay_first_amount"));
  3574. type_sell = GTK_WIDGET (builder_get (builder, "radio_btn_effective_pay"));
  3575. s_name = GTK_WIDGET (builder_get (builder, "lbl_name_mixed_pay_2"));
  3576. s_rut = GTK_WIDGET (builder_get (builder, "entry_rut_mixed_pay_2"));
  3577. s_amount = GTK_WIDGET (builder_get (builder, "entry_int_amount_mixed_pay2"));
  3578. //diferencia = GTK_WIDGET (builder_get (builder, "lbl_diff_amount2"));
  3579. w_cr = GTK_WIDGET (builder_get (builder, "radio_btn_cheques"));
  3580. f_code = GTK_WIDGET (builder_get (builder, "entry_int_code_mixed_pay"));
  3581. //Se recogen los datos de la primera ventana
  3582. nombre_cliente = g_strdup (gtk_label_get_text (GTK_LABEL (builder_get (builder, "lbl_name_mixed_pay"))));
  3583. rut_cliente = g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_rut_mixed_pay"))));
  3584. str_splited = parse_rut (rut_cliente);
  3585. rut = atoi (str_splited[0]);
  3586. g_free (str_splited);
  3587. //Se ve si se seleccionó el cheque de restaurant o el credito
  3588. cheque_restaurant = (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w_cr)) == TRUE) ? TRUE : FALSE;
  3589. //Se ve si se se paga a cheques de restaurant en el modo general o a detalle
  3590. general = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (builder_get (builder, "radio_btn_general")));
  3591. //Se recogen el monto total a pagar y el monto con el que se paga en la primera ventana
  3592. //total = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "label_total"))))));
  3593. total = llround (CalcularTotal (venta->header));
  3594. if (general)
  3595. paga_con = atoi (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_int_amount_mixed_pay"))));
  3596. else if (pago_chk_rest->header != NULL)
  3597. paga_con = lround (calcular_total_cheques (pago_chk_rest->header));
  3598. else
  3599. {
  3600. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_rut_mixed_pay")),
  3601. "Debe agregar cheques a la lista");
  3602. return;
  3603. }
  3604. /*Realiza algunas verificaciones antes de continuar con los pagos*/
  3605. //Si la venta es a crédito, verifica que tenga el saldo suficiente
  3606. if (cheque_restaurant == FALSE)
  3607. {
  3608. if (LimiteCredito (rut_cliente) < (DeudaTotalCliente (rut) + paga_con))
  3609. {
  3610. gtk_widget_show (GTK_WIDGET (builder_get (builder, "msg_credit_out")));
  3611. return;
  3612. }
  3613. }
  3614. else if (cheque_restaurant == TRUE && general == TRUE)
  3615. {
  3616. cod_chk_rest_gen = g_strdup (gtk_entry_get_text (GTK_ENTRY (f_code)));
  3617. if (g_str_equal (cod_chk_rest_gen, ""))
  3618. {
  3619. ErrorMSG (f_code, "Debe ingresar el código de transacción del cheque de restaurant");
  3620. return;
  3621. }
  3622. else if (DataExist (g_strdup_printf ("SELECT codigo FROM cheque_rest WHERE codigo = '%s'", cod_chk_rest_gen)))
  3623. {
  3624. ErrorMSG (f_code, g_strdup_printf ("El cheque de codigo %s ya fué ingresado, ingrese uno nuevo", cod_chk_rest_gen));
  3625. return;
  3626. }
  3627. //Se crea un cheque
  3628. add_chk_rest_to_list (cod_chk_rest_gen, "", paga_con);
  3629. }
  3630. paga_con_txt = PutPoints (g_strdup_printf ("%d", paga_con));
  3631. /* Si el total es mayor al primer pago, se pide que complete la compra con otra forma de pago */
  3632. if (total > paga_con)
  3633. {
  3634. //El pago no afecto debe ser menor o igual al total de los productos afectos
  3635. if (cheque_restaurant == TRUE)
  3636. {
  3637. gint monto_solo_afecto = lround (CalcularSoloAfecto (venta->header));
  3638. if (paga_con > monto_solo_afecto)
  3639. {
  3640. if (general == TRUE)
  3641. {
  3642. limpiar_lista (); //Se tiene que volver a crear el cheque, por lo tanto de saca de la lista.
  3643. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_int_amount_mixed_pay")),
  3644. g_strdup_printf ("El pago con cheque de restaurant debe ser menor o igual a %d", monto_solo_afecto));
  3645. }
  3646. else
  3647. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_int_code_detail_mp")),
  3648. g_strdup_printf ("El pago con cheque de restaurant debe ser menor o igual a %d", monto_solo_afecto));
  3649. return;
  3650. }
  3651. }
  3652. //Se limpia el treeview de los cheques seleccionados
  3653. gtk_list_store_clear (pago_chk_rest->store);
  3654. //Se llena la estructura de pago mixto
  3655. pago_mixto->tipo_pago1 = (cheque_restaurant) ? CHEQUE_RESTAURANT : CREDITO;
  3656. pago_mixto->check_rest1 = (cheque_restaurant) ? pago_chk_rest : NULL;
  3657. pago_mixto->rut_credito1 = (cheque_restaurant) ? NULL : rut_cliente;
  3658. pago_mixto->monto_pago1 = paga_con;
  3659. //Se rellenan y limpian los widgets según corresponda
  3660. gtk_label_set_markup (GTK_LABEL (f_type_pay), g_strdup_printf ("<b>%s</b>", (cheque_restaurant) ? "CHEQUE RESTAURANT" : "CREDITO"));
  3661. gtk_label_set_markup (GTK_LABEL (f_name), g_strdup_printf ("<b>%s</b>", nombre_cliente));
  3662. gtk_label_set_markup (GTK_LABEL (f_rut), g_strdup_printf ("<b>%s</b>", rut_cliente));
  3663. gtk_label_set_markup (GTK_LABEL (f_amount), g_strdup_printf ("<b>%s</b>", paga_con_txt));
  3664. gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (type_sell), TRUE);
  3665. gtk_entry_set_text (GTK_ENTRY (s_rut), "");
  3666. gtk_label_set_text (GTK_LABEL (s_name), "");
  3667. gtk_entry_set_text (GTK_ENTRY (s_amount), "");
  3668. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "lbl_diff_amount2")),
  3669. g_strdup_printf ("<span size=\"30000\"> %s </span> "
  3670. "<span size=\"15000\" color =\"red\">Faltante</span>",
  3671. PutPoints (g_strdup_printf ("%d", total-paga_con))));
  3672. gtk_widget_set_sensitive (s_rut, FALSE);
  3673. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_accept_mixed_pay2")), FALSE);
  3674. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_mixed_pay_step1")));
  3675. gtk_widget_show (GTK_WIDGET (builder_get (builder, "wnd_mixed_pay_step2")));
  3676. gtk_window_set_position (GTK_WINDOW (builder_get (builder, "wnd_mixed_pay_step2")),
  3677. GTK_WIN_POS_CENTER_ALWAYS);
  3678. gtk_widget_grab_focus (s_amount);
  3679. }
  3680. else
  3681. {
  3682. maquina = rizoma_get_value_int ("MAQUINA");
  3683. vendedor = user_data->user_id;
  3684. tipo_documento = SIMPLE;
  3685. switch (tipo_documento)
  3686. {
  3687. case SIMPLE: case VENTA:
  3688. if (total >= 180)
  3689. ticket = get_ticket_number (tipo_documento);
  3690. else
  3691. ticket = -1;
  3692. break;
  3693. default:
  3694. g_printerr("The document type could not be matched on %s", G_STRFUNC);
  3695. ticket = -1;
  3696. break;
  3697. }
  3698. //Si el pago es solamente con cheque de restaurant
  3699. if (cheque_restaurant == TRUE)
  3700. {
  3701. gint monto_solo_no_afecto = lround (CalcularSoloNoAfecto (venta->header));
  3702. gint monto_solo_afecto = lround (CalcularSoloAfecto (venta->header));
  3703. if (monto_solo_no_afecto > 0)
  3704. {
  3705. if (general == TRUE)
  3706. {
  3707. limpiar_lista (); //Se tiene que volver a crear el cheque, por lo tanto de saca de la lista.
  3708. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_int_amount_mixed_pay")),
  3709. g_strdup_printf ("El pago con cheque de restaurant debe ser menor o igual a %d", monto_solo_afecto));
  3710. }
  3711. else
  3712. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_int_code_detail_mp")),
  3713. g_strdup_printf ("El pago con cheque de restaurant debe ser menor o igual a %d", monto_solo_afecto));
  3714. return;
  3715. }
  3716. }
  3717. //printf ("%s", (cheque_restaurant) ? "cheque_restaurant" : "credito");
  3718. //Se registra la venta
  3719. SaveSell (total, maquina, vendedor, (cheque_restaurant) ? CHEQUE_RESTAURANT : CREDITO, rut_cliente, "0", ticket, tipo_documento,
  3720. NULL, FALSE, TRUE, FALSE);
  3721. //Se cierra y limpia todo
  3722. ListClean (); //Limpia la estructura de productos de venta
  3723. limpiar_lista (); //Limpia la estructura de cheques
  3724. //Se quitan los productos de la lista de venta
  3725. gtk_list_store_clear (venta->store);
  3726. gtk_list_store_clear (pago_chk_rest->store);
  3727. //Se limpian los label
  3728. CleanEntryAndLabelData();
  3729. //Se actualiza el numero de ticket de venta
  3730. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_ticket_number")),
  3731. g_strdup_printf ("<span size=\"15000\">%.6d</span>", get_ticket_number (SIMPLE)-1)); //antes get_last_sell_id ()
  3732. //Se cierra la ventana y se cambia el foco al entry de barcode
  3733. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_mixed_pay_step1")));
  3734. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  3735. }
  3736. }
  3737. /**
  3738. * This function enters the sale when the amount
  3739. * entered is enough, recording as MIXED pay
  3740. *
  3741. * @param: GtkButton *button
  3742. * @param: gpointer data
  3743. */
  3744. void
  3745. on_btn_accept_mixed_pay2_clicked (GtkButton *button, gpointer data)
  3746. {
  3747. gint total, paga_con, primer_pago;
  3748. gchar *rut_cuenta1, *rut_cuenta2;
  3749. gchar **str_splited;
  3750. gint rut1, rut2;
  3751. gchar *dv1; //*dv2;
  3752. gint maquina, vendedor;
  3753. gint tipo_documento, ticket;
  3754. gint tipo_pago1, tipo_pago2;
  3755. //gboolean afecto_impuesto1, afecto_impuesto2;
  3756. //total = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "label_total"))))));
  3757. total = llround (CalcularTotal (venta->header));
  3758. pago_mixto->total_a_pagar = total;
  3759. /*-- Primer Pago --*/
  3760. tipo_pago1 = pago_mixto->tipo_pago1;
  3761. //afecto_impuesto1 = (tipo_pago1 == CREDITO) ? TRUE : FALSE;
  3762. primer_pago = pago_mixto->monto_pago1;
  3763. //Primer rut
  3764. if (tipo_pago1 == CREDITO)
  3765. rut_cuenta1 = g_strdup (pago_mixto->rut_credito1);
  3766. else
  3767. rut_cuenta1 = g_strdup (pago_mixto->check_rest1->rut_emisor);
  3768. str_splited = parse_rut (rut_cuenta1);
  3769. rut1 = atoi (str_splited[0]);
  3770. dv1 = g_strdup (str_splited[1]);
  3771. g_free (str_splited);
  3772. printf ("%s, %d, %s\n", rut_cuenta1, rut1, dv1);
  3773. printf ("%d\n", primer_pago);
  3774. /*-- Segundo Pago --*/
  3775. paga_con = atoi (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_int_amount_mixed_pay2"))));
  3776. //Si el pago es a credito obtiene el 2do rut
  3777. if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (builder_get (builder, "radio_btn_effective_pay"))))
  3778. {
  3779. //Se asegura se tener seleccionado un cliente - TODO: agregar condición al calcular
  3780. if (g_str_equal (gtk_label_get_text (GTK_LABEL (builder_get (builder, "lbl_name_mixed_pay_2"))), ""))
  3781. {
  3782. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_rut_mixed_pay_2")), "Debe seleccionar un cliente");
  3783. return;
  3784. }
  3785. //Obtiene el segundo rut
  3786. rut_cuenta2 = g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_rut_mixed_pay_2"))));
  3787. //Obtiene el rut sin dígito verificador
  3788. str_splited = parse_rut (rut_cuenta2);
  3789. rut2 = atoi (str_splited[0]);
  3790. //dv2 = g_strdup (str_splited[1]);
  3791. g_free (str_splited);
  3792. //verifica que el cliente tenga cupo disponible
  3793. if (LimiteCredito (rut_cuenta2) < (DeudaTotalCliente (rut2) + paga_con))
  3794. {
  3795. gtk_widget_show (GTK_WIDGET (builder_get (builder, "msg_credit_out")));
  3796. return;
  3797. }
  3798. tipo_pago2 = CREDITO;
  3799. //afecto_impuesto2 = TRUE;
  3800. }
  3801. else //quiere decir que el segundo pago es en efectivo
  3802. {
  3803. rut_cuenta2 = g_strdup_printf ("0");
  3804. rut2 = 0;
  3805. //dv2 = g_strdup_printf ("0");
  3806. tipo_pago2 = CASH;
  3807. //afecto_impuesto2 = TRUE;
  3808. }
  3809. //Obtiene datos de la máquina y el vendedor
  3810. maquina = rizoma_get_value_int ("MAQUINA");
  3811. vendedor = user_data->user_id;
  3812. // TODO: ese monto mínimo para imprimir la boleta debe ser editable
  3813. tipo_documento = SIMPLE;
  3814. switch (tipo_documento)
  3815. {
  3816. case SIMPLE: case VENTA:
  3817. if (total >= 180)
  3818. ticket = get_ticket_number (tipo_documento);
  3819. else
  3820. ticket = -1;
  3821. break;
  3822. default:
  3823. g_printerr("The document type could not be matched on %s", G_STRFUNC);
  3824. ticket = -1;
  3825. break;
  3826. }
  3827. //Se guarda en la estructura pago_mixto, los datos del segundo pago
  3828. pago_mixto->tipo_pago2 = tipo_pago2;
  3829. pago_mixto->check_rest2 = NULL;
  3830. pago_mixto->rut_credito2 = (tipo_pago2 == CREDITO) ? rut_cuenta2 : NULL;
  3831. pago_mixto->monto_pago2 = paga_con;
  3832. /* Solo el cheque de restaurant se registra tal cual como se ingresa
  3833. (siendo igual o mayor al monto para liquidar la venta)
  3834. puesto que solo con éste no se da vuelto */
  3835. if (pago_mixto->tipo_pago2 != CHEQUE_RESTAURANT)
  3836. pago_mixto->monto_pago2 = pago_mixto->total_a_pagar - pago_mixto->monto_pago1;
  3837. //El pago no afecto debe ser menor o igual al total de los productos afectos
  3838. if (pago_mixto->tipo_pago2 == CHEQUE_RESTAURANT)
  3839. {
  3840. gint monto_solo_afecto = lround (CalcularSoloAfecto (venta->header));
  3841. if (pago_mixto->monto_pago2 > monto_solo_afecto)
  3842. {
  3843. limpiar_lista ();
  3844. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_int_amount_mixed_pay2")),
  3845. g_strdup_printf ("El pago con cheque de restaurant debe ser menor o igual a %d", monto_solo_afecto));
  3846. return;
  3847. }
  3848. }
  3849. //Se registra la venta -- TODO: solo se le esta pasando el primer cliente, ver bien el asunto cuando es mixto
  3850. SaveSell (total, maquina, vendedor, MIXTO, rut_cuenta1, "0", ticket, tipo_documento,
  3851. NULL, FALSE, TRUE, FALSE);
  3852. //Se cierra y limpia todo
  3853. CleanEntryAndLabelData();
  3854. ListClean (); //Se debe ejecutar antes de vaciar la lista de venta (la estructura)
  3855. limpiar_lista (); // vacía la lista de cheques de restaurant
  3856. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_ticket_number")),
  3857. g_strdup_printf ("<span size=\"15000\">%.6d</span>", get_ticket_number (SIMPLE)-1)); //antes get_last_sell_id ()
  3858. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  3859. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_mixed_pay_step2")));
  3860. //Se quitan los productos de la lista de venta (de la estructura)
  3861. gtk_list_store_clear (venta->store);
  3862. //Se limpian los labels
  3863. CleanEntryAndLabelData();
  3864. }
  3865. /**
  3866. * This function calculate the amount entered vs
  3867. * the total and shows the difference in the
  3868. * corresponding label.
  3869. * Also enable the corresponding widgets.
  3870. *
  3871. * @param: GtkEditable *editable
  3872. * @param: gchar *new_text
  3873. * @param: gint new_text_length
  3874. * @param: gint *position
  3875. * @param: gpointer user_data
  3876. */
  3877. void
  3878. calculate_amount (GtkEditable *editable,
  3879. gchar *new_text,
  3880. gint new_text_length,
  3881. gint *position,
  3882. gpointer user_data)
  3883. {
  3884. gchar *num;
  3885. gint paga_con;
  3886. gint total = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "label_total"))))));
  3887. gint resto;
  3888. gboolean primer_pago = gtk_widget_get_visible (GTK_WIDGET (builder_get (builder, "wnd_mixed_pay_step1")));
  3889. gboolean segundo_pago = gtk_widget_get_visible (GTK_WIDGET (builder_get (builder, "wnd_mixed_pay_step2")));
  3890. //Ve de donde sacar los montos de pago y el monto a completar
  3891. if (primer_pago == TRUE && pago_chk_rest->header != NULL) //Si es la primera ventana, y se vende con cheques resto
  3892. paga_con = lround (calcular_total_cheques (pago_chk_rest->header));
  3893. else if (primer_pago == TRUE) //Se es la primera ventana y se vende a credito
  3894. {
  3895. num = g_strdup_printf ("%s%s", gtk_entry_get_text (GTK_ENTRY (editable)), new_text);
  3896. paga_con = atoi (num);
  3897. }
  3898. else if (segundo_pago == TRUE) //Si es la segunda ventana
  3899. {
  3900. num = g_strdup_printf ("%s%s", gtk_entry_get_text (GTK_ENTRY (editable)), new_text);
  3901. paga_con = atoi (num);
  3902. total = total - atoi (CutPoints (g_strdup
  3903. (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "lbl_mixed_pay_first_amount"))))));
  3904. }
  3905. printf ("paga con: %d\n"
  3906. "total: %d\n", paga_con, total);
  3907. if (paga_con < total)
  3908. {
  3909. resto = total - paga_con;
  3910. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, (!segundo_pago) ? "lbl_diff_amount" : "lbl_diff_amount2")),
  3911. g_strdup_printf ("<span size=\"30000\"> %s </span> "
  3912. "<span size=\"15000\" color =\"red\">Faltante</span>",
  3913. PutPoints (g_strdup_printf ("%d", resto))));
  3914. }
  3915. else
  3916. {
  3917. resto = paga_con - total;
  3918. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, (!segundo_pago) ? "lbl_diff_amount" : "lbl_diff_amount2")),
  3919. g_strdup_printf ("<span size=\"30000\"> %s </span> "
  3920. "<span size=\"15000\" color =\"#04B404\">Sobrante</span>",
  3921. PutPoints (g_strdup_printf ("%d", resto))));
  3922. }
  3923. if (!segundo_pago)
  3924. {
  3925. if (resto == total ||
  3926. g_str_equal (gtk_label_get_text (GTK_LABEL (builder_get (builder, "lbl_name_mixed_pay"))), ""))
  3927. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_accept_mixed_pay")), FALSE);
  3928. else
  3929. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_accept_mixed_pay")), TRUE);
  3930. }
  3931. else
  3932. {
  3933. if (paga_con < total)
  3934. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_accept_mixed_pay2")), FALSE);
  3935. else
  3936. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_accept_mixed_pay2")), TRUE);
  3937. }
  3938. }
  3939. /**
  3940. * This function show the "wnd_mixed_pay_step1"
  3941. * window, clean their widgets, and grab focus
  3942. * on "entry_rut_mixed_pay" entry.
  3943. */
  3944. void
  3945. mixed_pay_window (void)
  3946. {
  3947. //GtkListStore *store;
  3948. //GtkTreeView *treeview;
  3949. GtkTreeViewColumn *column;
  3950. GtkCellRenderer *renderer;
  3951. // Se inicializan en ventas_win ()
  3952. /* pago_chk_rest = (PagoChequesRest *) g_malloc (sizeof (PagoChequesRest)); */
  3953. /* pago_chk_rest->header = NULL; */
  3954. /* pago_chk_rest->cheques = NULL; */
  3955. // Se inicializa al momento de rellenar el treeview.
  3956. //ChequesRestaurant *fill = pago_chk_rest->header;
  3957. gint total = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "label_total"))))));
  3958. if (venta->header == NULL)
  3959. {
  3960. ErrorMSG (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")), "No hay productos para vender");
  3961. return;
  3962. }
  3963. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_rut_mixed_pay")), "");
  3964. gtk_label_set_text (GTK_LABEL (builder_get (builder, "lbl_name_mixed_pay")), "");
  3965. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_int_amount_mixed_pay")), "");
  3966. gtk_label_set_text (GTK_LABEL (builder_get (builder, "lbl_diff_amount")), "");
  3967. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_int_code_mixed_pay")), "");
  3968. gtk_label_set_text (GTK_LABEL (builder_get (builder, "lbl_subtotal_mixed_pay")), "");
  3969. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "lbl_diff_amount")),
  3970. g_strdup_printf ("<span size=\"30000\"> %s </span> "
  3971. "<span size=\"15000\" color =\"red\">Faltante</span>",
  3972. PutPoints (g_strdup_printf ("%d", total))));
  3973. //Selecciones por defecto
  3974. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "radio_btn_cheques")), TRUE);
  3975. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "radio_btn_general")), TRUE);
  3976. gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (builder_get (builder, "radio_btn_credito")), TRUE);
  3977. gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (builder_get (builder, "radio_btn_general")), TRUE);
  3978. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_rut_mixed_pay")));
  3979. //Oculto por defecto
  3980. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "hbox3_detail_mixed_pay")));
  3981. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "scrolledwindow1_mixed_pay")));
  3982. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "hbox4_mixed_pay")));
  3983. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_accept_mixed_pay")), FALSE);
  3984. pago_chk_rest->treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_mixed_pay"));
  3985. //Se inicializa el treeview - gtk_tree_view_get_model (pago_chk_rest->treeview) == NULL
  3986. if (gtk_tree_view_get_model (pago_chk_rest->treeview) == NULL)
  3987. {
  3988. pago_chk_rest->treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_mixed_pay"));
  3989. // TreeView Providers
  3990. pago_chk_rest->store = gtk_list_store_new (3,
  3991. G_TYPE_STRING, //Codigo
  3992. G_TYPE_STRING, //fecha Vencimiento
  3993. G_TYPE_INT, //Monto
  3994. -1);
  3995. gtk_tree_view_set_model (pago_chk_rest->treeview, GTK_TREE_MODEL (pago_chk_rest->store));
  3996. renderer = gtk_cell_renderer_text_new ();
  3997. column = gtk_tree_view_column_new_with_attributes ("Codigo", renderer,
  3998. "text", 0,
  3999. NULL);
  4000. gtk_tree_view_append_column (pago_chk_rest->treeview, column);
  4001. gtk_tree_view_column_set_alignment (column, 0.5);
  4002. g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
  4003. gtk_tree_view_column_set_sort_column_id (column, 0);
  4004. gtk_tree_view_column_set_resizable (column, FALSE);
  4005. gtk_tree_view_column_set_min_width (column, 250);
  4006. renderer = gtk_cell_renderer_text_new ();
  4007. column = gtk_tree_view_column_new_with_attributes ("Fecha Vencimiento", renderer,
  4008. "text", 1,
  4009. NULL);
  4010. gtk_tree_view_append_column (pago_chk_rest->treeview, column);
  4011. gtk_tree_view_column_set_alignment (column, 0.5);
  4012. g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
  4013. gtk_tree_view_column_set_sort_column_id (column, 1);
  4014. gtk_tree_view_column_set_resizable (column, FALSE);
  4015. gtk_tree_view_column_set_min_width (column, 250);
  4016. renderer = gtk_cell_renderer_text_new ();
  4017. column = gtk_tree_view_column_new_with_attributes ("Monto", renderer,
  4018. "text", 2,
  4019. NULL);
  4020. gtk_tree_view_append_column (pago_chk_rest->treeview, column);
  4021. gtk_tree_view_column_set_alignment (column, 0.5);
  4022. g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);
  4023. gtk_tree_view_column_set_sort_column_id (column, 2);
  4024. gtk_tree_view_column_set_resizable (column, FALSE);
  4025. gtk_tree_view_column_set_cell_data_func (column, renderer, control_decimal, (gpointer)2, NULL);
  4026. }
  4027. limpiar_lista (); //Limpia la estructura de cheques
  4028. gtk_list_store_clear (pago_chk_rest->store); //limpia la lista de cheques
  4029. gtk_widget_show (GTK_WIDGET (builder_get (builder, "wnd_mixed_pay_step1")));
  4030. gtk_window_set_position (GTK_WINDOW (builder_get (builder, "wnd_mixed_pay_step1")),
  4031. GTK_WIN_POS_CENTER_ALWAYS);
  4032. }
  4033. /**
  4034. * This function shows (and hide) the corresponding widgets
  4035. * as the selection made.
  4036. *
  4037. * @param: GtkToggleButton *togglebutton
  4038. * @param: gpointer user_data
  4039. */
  4040. void
  4041. change_ingress_mode (GtkToggleButton *togglebutton, gpointer user_data)
  4042. {
  4043. //The general toggle button
  4044. if (gtk_toggle_button_get_active (togglebutton))
  4045. {
  4046. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_int_code_mixed_pay")));
  4047. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "hbox3_detail_mixed_pay")));
  4048. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "scrolledwindow1_mixed_pay")));
  4049. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "hbox4_mixed_pay")));
  4050. gtk_widget_show (GTK_WIDGET (builder_get (builder, "label1_cod_mixed_pay")));
  4051. gtk_widget_show (GTK_WIDGET (builder_get (builder, "label_amount_mixed_pay")));
  4052. gtk_widget_show (GTK_WIDGET (builder_get (builder, "entry_int_code_mixed_pay")));
  4053. gtk_widget_show (GTK_WIDGET (builder_get (builder, "entry_int_amount_mixed_pay")));
  4054. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "radio_btn_credito")), TRUE);
  4055. }
  4056. else
  4057. {
  4058. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_int_code_detail_mp")));
  4059. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_int_amount_mixed_pay")), "");
  4060. gtk_widget_show (GTK_WIDGET (builder_get (builder, "hbox3_detail_mixed_pay")));
  4061. gtk_widget_show (GTK_WIDGET (builder_get (builder, "scrolledwindow1_mixed_pay")));
  4062. gtk_widget_show (GTK_WIDGET (builder_get (builder, "hbox4_mixed_pay")));
  4063. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "label1_cod_mixed_pay")));
  4064. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "label_amount_mixed_pay")));
  4065. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "entry_int_code_mixed_pay")));
  4066. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "entry_int_amount_mixed_pay")));
  4067. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "radio_btn_credito")), FALSE);
  4068. calculate_amount (NULL, NULL, 0, NULL, NULL);
  4069. }
  4070. }
  4071. /**
  4072. * This function shows (and hide) the corresponding widgets
  4073. * as the selection made.
  4074. *
  4075. * @param: GtkToggleButton *togglebutton
  4076. * @param: gpointer user_data
  4077. */
  4078. void
  4079. change_pay_mode (GtkToggleButton *togglebutton, gpointer user_data)
  4080. {
  4081. //The "cheque restaurant" toggle button
  4082. if (gtk_toggle_button_get_active (togglebutton))
  4083. {
  4084. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_rut_mixed_pay")));
  4085. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "label1_cod_mixed_pay")), TRUE);
  4086. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "entry_int_code_mixed_pay")), TRUE);
  4087. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "radio_btn_detail")), TRUE);
  4088. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_rut_mixed_pay")), "");
  4089. gtk_label_set_text (GTK_LABEL (builder_get (builder, "lbl_name_mixed_pay")), "");
  4090. }
  4091. else
  4092. {
  4093. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_rut_mixed_pay")));
  4094. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "label1_cod_mixed_pay")), FALSE);
  4095. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "entry_int_code_mixed_pay")), FALSE);
  4096. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "radio_btn_detail")), FALSE);
  4097. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_rut_mixed_pay")), "");
  4098. gtk_label_set_text (GTK_LABEL (builder_get (builder, "lbl_name_mixed_pay")), "");
  4099. }
  4100. }
  4101. /**
  4102. * This function add the restaurant check to treeview and
  4103. * adds it to the "pago_chk_rest" list.
  4104. *
  4105. * @param: GtkButton *button
  4106. * @param: gpointer user_data
  4107. */
  4108. void
  4109. on_btn_add_chk_rest_clicked (GtkButton *button, gpointer user_data)
  4110. {
  4111. GtkTreeIter iter;
  4112. GtkWidget *codigo_w, *fecha_venc_w, *monto_w;
  4113. gchar *codigo, *fecha_venc, *monto, *fecha_valida;
  4114. gint subtotal;
  4115. codigo_w = GTK_WIDGET (builder_get (builder, "entry_int_code_detail_mp"));
  4116. fecha_venc_w = GTK_WIDGET (builder_get (builder, "entry_int_exp_date_mp"));
  4117. monto_w = GTK_WIDGET (builder_get (builder, "entry_int_amount_detail_mp"));
  4118. codigo = g_strdup (gtk_entry_get_text (GTK_ENTRY (codigo_w)));
  4119. fecha_venc = g_strdup (gtk_entry_get_text (GTK_ENTRY (fecha_venc_w)));
  4120. monto = g_strdup (gtk_entry_get_text (GTK_ENTRY (monto_w)));
  4121. fecha_valida = GetDataByOne (g_strdup_printf ("SELECT * FROM is_valid_date('%s','DDMMYY')", fecha_venc));
  4122. if (g_str_equal (codigo, ""))
  4123. ErrorMSG (codigo_w, "Debe ingresar un código");
  4124. else if (DataExist (g_strdup_printf ("SELECT codigo FROM cheque_rest WHERE codigo = '%s'", codigo)))
  4125. ErrorMSG (codigo_w, g_strdup_printf ("El cheque de codigo %s ya fué ingresado, ingrese uno nuevo", codigo));
  4126. else if (g_str_equal (fecha_venc, ""))
  4127. ErrorMSG (fecha_venc_w, "Debe ingresar la fecha de vencimiento");
  4128. else if (g_str_equal (fecha_valida, "f"))
  4129. ErrorMSG (fecha_venc_w, "Debe ingresar una fecha válida");
  4130. else if (g_str_equal (monto, ""))
  4131. ErrorMSG (monto_w, "Debe el monto del cheque de restaurant");
  4132. else
  4133. {
  4134. //Busca si ya se ha ingresado un cheque con ese codigo a la lista
  4135. if (pago_chk_rest->cheques != NULL)
  4136. pago_chk_rest->cheques_check = buscar_por_codigo (pago_chk_rest->header, codigo);
  4137. else
  4138. pago_chk_rest->cheques_check = NULL;
  4139. if (pago_chk_rest->cheques_check == NULL)
  4140. {
  4141. add_chk_rest_to_list (codigo, fecha_venc, atoi(monto));
  4142. gtk_list_store_insert_after (pago_chk_rest->store, &iter, NULL);
  4143. gtk_list_store_set (pago_chk_rest->store, &iter,
  4144. 0, pago_chk_rest->cheques->cheque->codigo,
  4145. 1, pago_chk_rest->cheques->cheque->fecha_vencimiento,
  4146. 2, pago_chk_rest->cheques->cheque->monto,
  4147. -1);
  4148. pago_chk_rest->cheques->cheque->iter = iter;
  4149. clean_container (GTK_CONTAINER (builder_get (builder, "hbox3_detail_mixed_pay")));
  4150. gtk_widget_grab_focus (codigo_w);
  4151. //Recalcular Sub TOTAL
  4152. subtotal = lround (calcular_total_cheques (pago_chk_rest->header));
  4153. printf ("Pase por aquí en agregar a la lista\n");
  4154. gtk_label_set_markup (GTK_LABEL (builder_get (builder, "lbl_subtotal_mixed_pay")),
  4155. g_strdup_printf ("<span size=\"23000\">%d</span>", subtotal));
  4156. calculate_amount (NULL, NULL, 0, NULL, NULL);
  4157. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "radio_btn_general")), FALSE);
  4158. }
  4159. else
  4160. ErrorMSG (codigo_w, g_strdup_printf ("El cheque de código %s ya está en la lista, ingrese uno nuevo", codigo));
  4161. }
  4162. }
  4163. /**
  4164. * This function add the restaurant check to treeview and
  4165. * adds it to the "pago_chk_rest" list.
  4166. *
  4167. * @param: GtkButton *button
  4168. * @param: gpointer user_data
  4169. */
  4170. void
  4171. on_btn_del_chk_rest_clicked (GtkButton *button, gpointer user_data)
  4172. {
  4173. GtkTreeIter iter;
  4174. GtkTreeSelection *selection;
  4175. gchar *codigo;
  4176. //gint position;
  4177. gint subtotal;
  4178. selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pago_chk_rest->treeview));
  4179. if (gtk_tree_selection_get_selected (selection, NULL, &iter) == TRUE)
  4180. {
  4181. gtk_tree_model_get (GTK_TREE_MODEL (pago_chk_rest->store), &iter,
  4182. 0, &codigo,
  4183. -1);
  4184. //Esta línea hace que haya un violación de segmento al momento de agregar un cheque a la lista o_Ó!! WTF!
  4185. //position = atoi (gtk_tree_model_get_string_from_iter (GTK_TREE_MODEL (pago_chk_rest->store), &iter));
  4186. del_chk_rest_from_list (codigo);
  4187. gtk_list_store_remove (GTK_LIST_STORE (pago_chk_rest->store), &iter);
  4188. subtotal = lround (calcular_total_cheques (pago_chk_rest->header));
  4189. printf ("Pase por aquí en quitar de la lista\n");
  4190. gtk_label_set_markup (GTK_LABEL (builder_get (builder, "lbl_subtotal_mixed_pay")),
  4191. g_strdup_printf ("<span size=\"23000\">%d</span>", subtotal));
  4192. calculate_amount (NULL, NULL, 0, NULL, NULL);
  4193. //Si subtotal = 0, significa que no hay cheques en la lista
  4194. if (subtotal == 0)
  4195. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "radio_btn_general")), TRUE);
  4196. }
  4197. //select_back_deleted_row ("treeview_mixed_pay", position);
  4198. }
  4199. /**
  4200. * Deriva al modo de venta correspondiente
  4201. */
  4202. void
  4203. modo_venta ()
  4204. {
  4205. if (rizoma_get_value_boolean ("MODO_MESERO"))
  4206. {
  4207. gtk_widget_show (GTK_WIDGET (builder_get (builder, "wnd_print_mesa")));
  4208. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "btn_print_mesa")));
  4209. }
  4210. else if (rizoma_get_value_boolean ("PREVENTA"))
  4211. {
  4212. on_btn_preventa_clicked (NULL, NULL);
  4213. }
  4214. else if (rizoma_get_value_boolean ("VENTA_SUSCRITO"))
  4215. {
  4216. on_btn_invoice_clicked (NULL,NULL);
  4217. }
  4218. else
  4219. TipoVenta (NULL, NULL);
  4220. }
  4221. /**
  4222. * Callback connected the key-press-event in the main window.
  4223. *
  4224. * This function must be simple, because can lead to a performance
  4225. * issues. It currently only handles the global keys that are
  4226. * associated to nothing.
  4227. *
  4228. * @param widget the widget that emits the signal
  4229. * @param event the event
  4230. * @param data the user data
  4231. *
  4232. * @return TRUE on key captured, FALSE to let the key pass.
  4233. */
  4234. gboolean
  4235. on_ventas_gui_key_press_event(GtkWidget *widget,
  4236. GdkEventKey *event,
  4237. gpointer data)
  4238. {
  4239. switch (event->keyval)
  4240. {
  4241. case GDK_F2:
  4242. if (atoi(rizoma_get_value("VENTA_DIRECTA"))) // Si VENTA_DIRECTA = 1
  4243. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "cantidad_entry")));
  4244. break;
  4245. //F3 - Cerrar Caja
  4246. case GDK_F4:
  4247. adm_reserva_win ();
  4248. break;
  4249. case GDK_F5:
  4250. if (user_data->user_id == 1)
  4251. nullify_sale_win ();
  4252. break;
  4253. case GDK_F6:
  4254. if (user_data->user_id == 1)
  4255. VentanaEgreso(0);
  4256. break;
  4257. case GDK_F7:
  4258. if (user_data->user_id == 1)
  4259. VentanaIngreso (0);
  4260. break;
  4261. case GDK_F8:
  4262. if (/*no_venta == FALSE &&*/ venta_reserva == FALSE && !rizoma_get_value_boolean ("PREVENTA"))
  4263. mixed_pay_window ();
  4264. break;
  4265. case GDK_F9:
  4266. modo_venta();
  4267. break;
  4268. //No se permiten ventas en modo PREVENTA o cuando las banderas VENTA_RESERVA o NO_VENTA esten en FALSE
  4269. case GDK_F10:
  4270. if (/*no_venta == FALSE &&*/ venta_reserva == FALSE && !rizoma_get_value_boolean ("PREVENTA"))
  4271. on_btn_credit_clicked (NULL, NULL);
  4272. // Si esta habilitada la opcion "CUENTA_RAPIDA" se selecciona automaticamente la cuenta especificada (si es valida)
  4273. if (!g_str_equal (rizoma_get_value ("CUENTA_RAPIDA"), "NONE") && !HaveCharacters (rizoma_get_value ("CUENTA_RAPIDA")))
  4274. {
  4275. //Si es CONTROL+F10
  4276. if (event->state & GDK_CONTROL_MASK)
  4277. on_btn_credit_clicked (NULL, NULL);
  4278. else //Si solo es F10
  4279. {
  4280. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_credit_rut")), rizoma_get_value ("CUENTA_RAPIDA"));
  4281. search_client (GTK_WIDGET (builder_get (builder, "entry_credit_rut")), NULL);
  4282. }
  4283. }
  4284. break;
  4285. case GDK_F11:
  4286. on_btn_get_preventa_clicked (NULL, NULL);
  4287. break;
  4288. //Realizar Pedido
  4289. case GDK_F12:
  4290. on_btn_realizar_pedido_clicked (NULL, NULL);
  4291. break;
  4292. default:
  4293. return FALSE;
  4294. }
  4295. return TRUE;
  4296. }
  4297. /**
  4298. * This function loads the nullify sale dialog.
  4299. *
  4300. * Here must stay all the configuration of the dialog that is needed
  4301. * when the dialog will be showed to the user.
  4302. */
  4303. void
  4304. nullify_sale_win (void)
  4305. {
  4306. GtkWidget *widget;
  4307. GtkCellRenderer *renderer;
  4308. GtkTreeViewColumn *column;
  4309. GtkTreeView *treeview_sales;
  4310. GtkTreeSelection *selection_sales;
  4311. GtkTreeView *treeview_details;
  4312. GtkListStore *store_sales;
  4313. GtkListStore *store_details;
  4314. // Comprueba que caja está habilitada
  4315. // Se deben poder hacer enulaciones de venatas sin caja habilitada
  4316. /*if (rizoma_get_value_boolean ("CAJA") == 0)
  4317. {
  4318. widget = GTK_WIDGET(gtk_builder_get_object(builder, "barcode_entry"));
  4319. AlertMSG (widget, "Debe habilitar caja para realizar anulaciones de venta");
  4320. return;
  4321. }*/
  4322. treeview_sales = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_nullify_sale"));
  4323. store_sales = GTK_LIST_STORE(gtk_tree_view_get_model(treeview_sales));
  4324. if (store_sales == NULL)
  4325. {
  4326. store_sales = gtk_list_store_new (4,
  4327. G_TYPE_INT, //id
  4328. G_TYPE_STRING, //date
  4329. G_TYPE_STRING, //salesman
  4330. G_TYPE_INT); //total amount
  4331. gtk_tree_view_set_model(treeview_sales, GTK_TREE_MODEL(store_sales));
  4332. selection_sales = gtk_tree_view_get_selection (treeview_sales);
  4333. gtk_tree_selection_set_mode (selection_sales, GTK_SELECTION_SINGLE);
  4334. g_signal_connect (G_OBJECT(selection_sales), "changed",
  4335. G_CALLBACK(on_selection_nullify_sales_change), NULL);
  4336. //ID
  4337. renderer = gtk_cell_renderer_text_new();
  4338. column = gtk_tree_view_column_new_with_attributes("ID", renderer,
  4339. "text", 0,
  4340. NULL);
  4341. gtk_tree_view_append_column (treeview_sales, column);
  4342. //Date
  4343. renderer = gtk_cell_renderer_text_new();
  4344. column = gtk_tree_view_column_new_with_attributes("Fecha", renderer,
  4345. "text", 1,
  4346. NULL);
  4347. gtk_tree_view_append_column (treeview_sales, column);
  4348. //Salesman
  4349. renderer = gtk_cell_renderer_text_new();
  4350. column = gtk_tree_view_column_new_with_attributes("Vendedor", renderer,
  4351. "text", 2,
  4352. NULL);
  4353. gtk_tree_view_append_column (treeview_sales, column);
  4354. //Total amount
  4355. renderer = gtk_cell_renderer_text_new();
  4356. column = gtk_tree_view_column_new_with_attributes("Monto Total", renderer,
  4357. "text", 3,
  4358. NULL);
  4359. gtk_tree_view_append_column (treeview_sales, column);
  4360. }
  4361. gtk_list_store_clear(store_sales);
  4362. treeview_details = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_nullify_sale_details"));
  4363. store_details = GTK_LIST_STORE(gtk_tree_view_get_model(treeview_details));
  4364. if (store_details == NULL)
  4365. {
  4366. store_details = gtk_list_store_new (7,
  4367. G_TYPE_INT, //barcode
  4368. G_TYPE_STRING, //description
  4369. G_TYPE_DOUBLE, //cantity
  4370. G_TYPE_DOUBLE, //price
  4371. G_TYPE_INT, //subtotal
  4372. G_TYPE_INT, //id (detail)
  4373. G_TYPE_INT); //id_venta
  4374. gtk_tree_view_set_model(treeview_details, GTK_TREE_MODEL(store_details));
  4375. gtk_tree_selection_set_mode (gtk_tree_view_get_selection (treeview_details), GTK_SELECTION_NONE);
  4376. //barcode
  4377. renderer = gtk_cell_renderer_text_new();
  4378. column = gtk_tree_view_column_new_with_attributes("Cod. Barras", renderer,
  4379. "text", 0,
  4380. NULL);
  4381. gtk_tree_view_append_column (treeview_details, column);
  4382. //description
  4383. renderer = gtk_cell_renderer_text_new();
  4384. column = gtk_tree_view_column_new_with_attributes("Descripcion", renderer,
  4385. "text", 1,
  4386. NULL);
  4387. gtk_tree_view_append_column (treeview_details, column);
  4388. //cantity
  4389. renderer = gtk_cell_renderer_text_new();
  4390. column = gtk_tree_view_column_new_with_attributes("Cantidad", renderer,
  4391. "text", 2,
  4392. NULL);
  4393. gtk_tree_view_append_column (treeview_details, column);
  4394. gtk_tree_view_column_set_cell_data_func (column, renderer, control_decimal, (gpointer)2, NULL);
  4395. //price
  4396. renderer = gtk_cell_renderer_text_new();
  4397. column = gtk_tree_view_column_new_with_attributes("Precio", renderer,
  4398. "text", 3,
  4399. NULL);
  4400. gtk_tree_view_append_column (treeview_details, column);
  4401. gtk_tree_view_column_set_cell_data_func (column, renderer, control_decimal, (gpointer)3, NULL);
  4402. //subtotal
  4403. renderer = gtk_cell_renderer_text_new();
  4404. column = gtk_tree_view_column_new_with_attributes("Subtotal", renderer,
  4405. "text", 4,
  4406. NULL);
  4407. gtk_tree_view_append_column (treeview_details, column);
  4408. }
  4409. gtk_list_store_clear(store_details);
  4410. widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_nullify_sale"));
  4411. gtk_widget_show_all (widget);
  4412. }
  4413. /**
  4414. * Callback connected to the search button of the nullify sale.
  4415. *
  4416. * This function fills the treeview of sale accordgin with the filters
  4417. * applied by the user.
  4418. *
  4419. * @param button the button that emited the signal
  4420. * @param data the user data
  4421. */
  4422. void
  4423. on_btn_nullify_search_clicked (GtkButton *button, gpointer data)
  4424. {
  4425. GtkTreeView *treeview;
  4426. GtkListStore *store_sales;
  4427. GtkTreeIter iter;
  4428. GtkEntry *entry;
  4429. gchar *sale_id;
  4430. gchar *barcode;
  4431. gchar *date;
  4432. gchar *amount;
  4433. gchar *q;
  4434. gchar *condition = "";
  4435. PGresult *res;
  4436. gint i;
  4437. gint tuples;
  4438. GDate *gdate;
  4439. gchar **date_splited;
  4440. gchar str_date[256];
  4441. entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_nullify_id"));
  4442. if (g_str_equal(gtk_entry_get_text(entry), ""))
  4443. sale_id = NULL;
  4444. else
  4445. sale_id = g_strdup(gtk_entry_get_text(entry));
  4446. entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_nullify_barcode"));
  4447. if (g_str_equal(gtk_entry_get_text(entry), ""))
  4448. barcode = NULL;
  4449. else
  4450. barcode = g_strdup(gtk_entry_get_text(entry));
  4451. entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_nullify_date"));
  4452. if (g_str_equal(gtk_entry_get_text(entry), ""))
  4453. date = NULL;
  4454. else
  4455. date = g_strdup(gtk_entry_get_text(entry));
  4456. entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_nullify_amount"));
  4457. if (g_str_equal(gtk_entry_get_text(entry), ""))
  4458. amount = NULL;
  4459. else
  4460. amount = g_strdup(gtk_entry_get_text(entry));
  4461. q = g_strdup ("SELECT id, date_trunc('day',fecha) as fecha, (select usuario from users where id=venta.vendedor) as usuario, monto FROM venta"
  4462. " WHERE id not in (select id_sale from venta_anulada where id_sale=venta.id) ");
  4463. if (sale_id != NULL)
  4464. {
  4465. if (atoi(sale_id) == 0)
  4466. {
  4467. AlertMSG(GTK_WIDGET(entry), "Debe ingresar un N° de Venta mayor a 0\nSi no sabe el numero de venta deje el campo vacío");
  4468. return;
  4469. }
  4470. else
  4471. condition = g_strconcat (condition, " AND id=", sale_id, NULL);
  4472. }
  4473. if (date != NULL)
  4474. {
  4475. GDate *date_aux;
  4476. gchar *str_date;
  4477. date_aux = g_date_new();
  4478. g_date_set_parse (date_aux, date);
  4479. str_date = g_strdup_printf("%d-%d-%d",
  4480. g_date_get_year(date_aux),
  4481. g_date_get_month(date_aux),
  4482. g_date_get_day(date_aux));
  4483. condition = g_strconcat (condition, " AND date_trunc('day', fecha)='", str_date, "'", NULL);
  4484. g_date_free (date_aux);
  4485. g_free (str_date);
  4486. }
  4487. if (barcode != NULL)
  4488. {
  4489. if (atoi(barcode) == 0)
  4490. {
  4491. AlertMSG(GTK_WIDGET(entry), "No puede ingresar un codigo de barras 0, o con caracteres\n"
  4492. "Si no sabe el código de barras deje el campo vacío");
  4493. return;
  4494. }
  4495. else
  4496. condition = g_strconcat(condition, " AND id in (select id_venta from venta_detalle where barcode=", barcode, ")", NULL);
  4497. }
  4498. if (amount != NULL)
  4499. {
  4500. if (atoi(amount) == 0)
  4501. {
  4502. AlertMSG(GTK_WIDGET(entry), "No puede ingresar un monto 0\nSi no sabe el monto puede dejar el campo vacio");
  4503. return;
  4504. }
  4505. else
  4506. condition = g_strconcat(condition, "AND monto=", amount, NULL);
  4507. }
  4508. if (!(g_str_equal(condition, "")))
  4509. {
  4510. q = g_strconcat (q, condition, NULL);
  4511. g_free (condition);
  4512. }
  4513. res = EjecutarSQL(q);
  4514. g_free (q);
  4515. tuples = PQntuples (res);
  4516. treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_nullify_sale_details"));
  4517. gtk_list_store_clear (GTK_LIST_STORE(gtk_tree_view_get_model(treeview)));
  4518. treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_nullify_sale"));
  4519. store_sales = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
  4520. gtk_list_store_clear (store_sales);
  4521. for (i=0 ; i < tuples ; i++)
  4522. {
  4523. date_splited = g_strsplit(PQvaluebycol(res, i, "fecha"), "-", -1);
  4524. gdate = g_date_new();
  4525. g_date_set_year(gdate, atoi(date_splited[0]));
  4526. g_date_set_month(gdate, atoi(date_splited[1]));
  4527. g_date_set_day(gdate, atoi(date_splited[2]));
  4528. g_date_strftime (str_date, sizeof(str_date), "%x", gdate);
  4529. g_strfreev(date_splited);
  4530. g_date_free(gdate);
  4531. gtk_list_store_append (store_sales, &iter);
  4532. gtk_list_store_set(store_sales, &iter,
  4533. 0, atoi(PQvaluebycol(res, i, "id")),
  4534. 1, str_date,
  4535. 2, PQvaluebycol(res, i, "usuario"),
  4536. 3, atoi(PQvaluebycol(res, i, "monto")),
  4537. -1);
  4538. }
  4539. }
  4540. /**
  4541. * Callback connected to 'changed' signal of the treeview that
  4542. * displays the sales in the nullify sale dialog.
  4543. *
  4544. * This function load the details of the selected sale in the treeview details.
  4545. *
  4546. * @param treeselection the tree selection that emited the signal
  4547. * @param data the user data
  4548. */
  4549. void
  4550. on_selection_nullify_sales_change (GtkTreeSelection *treeselection, gpointer data)
  4551. {
  4552. GtkListStore *store_sales;
  4553. GtkListStore *store_details;
  4554. GtkTreeView *treeview_sales;
  4555. GtkTreeView *treeview_details;
  4556. GtkTreeIter iter;
  4557. PGresult *res;
  4558. gint i;
  4559. gint tuples;
  4560. gchar *q;
  4561. gint sale_id;
  4562. treeview_sales = gtk_tree_selection_get_tree_view(treeselection);
  4563. store_sales = GTK_LIST_STORE(gtk_tree_view_get_model(treeview_sales));
  4564. treeview_details = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_nullify_sale_details"));
  4565. store_details = GTK_LIST_STORE(gtk_tree_view_get_model(treeview_details));
  4566. gtk_list_store_clear(store_details);
  4567. if (!(gtk_tree_selection_get_selected(treeselection, NULL, &iter))) return;
  4568. gtk_tree_model_get (GTK_TREE_MODEL(store_sales), &iter,
  4569. 0, &sale_id,
  4570. -1);
  4571. q = g_strdup_printf("select id, id_venta, barcode, cantidad, precio, (select descripcion from producto where barcode=venta_detalle.barcode) as descripcion, "
  4572. "(cantidad*precio) as subtotal from venta_detalle where id_venta=%d",
  4573. sale_id);
  4574. res = EjecutarSQL(q);
  4575. g_free (q);
  4576. tuples = PQntuples(res);
  4577. for (i=0 ; i<tuples ; i++)
  4578. {
  4579. gtk_list_store_append (store_details, &iter);
  4580. gtk_list_store_set (store_details, &iter,
  4581. 0, atoi(PQvaluebycol(res, i, "barcode")),
  4582. 1, PQvaluebycol(res, i, "descripcion"),
  4583. 2, strtod(PUT(PQvaluebycol(res, i, "cantidad")), (char **)NULL),
  4584. 3, strtod(PUT(PQvaluebycol(res, i, "precio")), (char **)NULL),
  4585. 4, atoi(PQvaluebycol(res, i, "subtotal")),
  4586. 5, atoi(PQvaluebycol(res, i, "id")),
  4587. 6, atoi(PQvaluebycol(res, i, "id_venta")),
  4588. -1);
  4589. }
  4590. }
  4591. /**
  4592. * Callback connected to cancel button in the nullify sale dialog.
  4593. *
  4594. * @param button the button that emited the signal
  4595. * @param data the user data
  4596. */
  4597. void
  4598. on_btn_nullify_cancel_clicked (GtkButton *button, gpointer data)
  4599. {
  4600. close_nullify_sale_dialog();
  4601. }
  4602. /**
  4603. * Callback connected to the delete-event of the nullify sale dialog.
  4604. *
  4605. * @param widget the widget that emited the signal
  4606. * @param event the event wich triggered the signal
  4607. * @param data the user data
  4608. *
  4609. * @return TRUE stop other handlers from being invoked
  4610. */
  4611. gboolean
  4612. on_wnd_nullify_sale_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
  4613. {
  4614. close_nullify_sale_dialog();
  4615. return TRUE;
  4616. }
  4617. /**
  4618. * This function show 'wnd_adm_pedido'
  4619. *
  4620. * Here must stay all the configuration of the dialog that is needed
  4621. * when the dialog will be showed to the user.
  4622. */
  4623. void
  4624. adm_reserva_win (void)
  4625. {
  4626. GtkWidget *widget;
  4627. GtkCellRenderer *renderer;
  4628. GtkTreeViewColumn *column;
  4629. GtkTreeView *treeview_pedido;
  4630. GtkTreeSelection *selection_pedido;
  4631. GtkTreeView *treeview_details;
  4632. GtkListStore *store_pedido;
  4633. GtkListStore *store_details;
  4634. // Comprueba que caja está habilitada
  4635. // Se deben poder hacer enulaciones de venatas sin caja habilitada
  4636. /*if (rizoma_get_value_boolean ("CAJA") == 0)
  4637. {
  4638. widget = GTK_WIDGET(gtk_builder_get_object(builder, "barcode_entry"));
  4639. AlertMSG (widget, "Debe habilitar caja para realizar anulaciones de venta");
  4640. return;
  4641. }*/
  4642. treeview_pedido = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_pedido"));
  4643. store_pedido = GTK_LIST_STORE(gtk_tree_view_get_model(treeview_pedido));
  4644. if (store_pedido == NULL)
  4645. {
  4646. store_pedido = gtk_list_store_new (7,
  4647. G_TYPE_INT, //id
  4648. G_TYPE_STRING, //nombre cliente
  4649. G_TYPE_STRING, //fecha pedido
  4650. G_TYPE_STRING, //fecha entrega
  4651. G_TYPE_INT, //monto pagado
  4652. G_TYPE_INT, //monto
  4653. G_TYPE_STRING); //rut cliente
  4654. gtk_tree_view_set_model (treeview_pedido, GTK_TREE_MODEL(store_pedido));
  4655. selection_pedido = gtk_tree_view_get_selection (treeview_pedido);
  4656. gtk_tree_selection_set_mode (selection_pedido, GTK_SELECTION_SINGLE);
  4657. g_signal_connect (G_OBJECT (selection_pedido), "changed",
  4658. G_CALLBACK (on_selection_pedido_change), NULL);
  4659. //ID
  4660. renderer = gtk_cell_renderer_text_new();
  4661. column = gtk_tree_view_column_new_with_attributes("ID", renderer,
  4662. "text", 0,
  4663. NULL);
  4664. gtk_tree_view_append_column (treeview_pedido, column);
  4665. //Client
  4666. renderer = gtk_cell_renderer_text_new();
  4667. column = gtk_tree_view_column_new_with_attributes("Cliente", renderer,
  4668. "text", 1,
  4669. NULL);
  4670. gtk_tree_view_append_column (treeview_pedido, column);
  4671. //Date
  4672. renderer = gtk_cell_renderer_text_new();
  4673. column = gtk_tree_view_column_new_with_attributes("Fecha", renderer,
  4674. "text", 2,
  4675. NULL);
  4676. gtk_tree_view_append_column (treeview_pedido, column);
  4677. //Date end
  4678. renderer = gtk_cell_renderer_text_new();
  4679. column = gtk_tree_view_column_new_with_attributes("Fecha Entrega", renderer,
  4680. "text", 3,
  4681. NULL);
  4682. gtk_tree_view_append_column (treeview_pedido, column);
  4683. //Monto Pagado
  4684. renderer = gtk_cell_renderer_text_new();
  4685. column = gtk_tree_view_column_new_with_attributes("Monto Pagado", renderer,
  4686. "text", 4,
  4687. NULL);
  4688. gtk_tree_view_append_column (treeview_pedido, column);
  4689. //Total amount
  4690. renderer = gtk_cell_renderer_text_new();
  4691. column = gtk_tree_view_column_new_with_attributes("Total Pedido", renderer,
  4692. "text", 5,
  4693. NULL);
  4694. gtk_tree_view_append_column (treeview_pedido, column);
  4695. }
  4696. gtk_list_store_clear(store_pedido);
  4697. treeview_details = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_pedido_detalle"));
  4698. store_details = GTK_LIST_STORE(gtk_tree_view_get_model(treeview_details));
  4699. if (store_details == NULL)
  4700. {
  4701. store_details = gtk_list_store_new (7,
  4702. G_TYPE_INT, //barcode
  4703. G_TYPE_STRING, //description
  4704. G_TYPE_DOUBLE, //cantity
  4705. G_TYPE_DOUBLE, //price
  4706. G_TYPE_INT, //subtotal
  4707. G_TYPE_INT, //id (detail)
  4708. G_TYPE_INT); //id_pedido
  4709. gtk_tree_view_set_model(treeview_details, GTK_TREE_MODEL(store_details));
  4710. gtk_tree_selection_set_mode (gtk_tree_view_get_selection (treeview_details), GTK_SELECTION_NONE);
  4711. //barcode
  4712. renderer = gtk_cell_renderer_text_new();
  4713. column = gtk_tree_view_column_new_with_attributes("Cod. Barras", renderer,
  4714. "text", 0,
  4715. NULL);
  4716. gtk_tree_view_append_column (treeview_details, column);
  4717. //description
  4718. renderer = gtk_cell_renderer_text_new();
  4719. column = gtk_tree_view_column_new_with_attributes("Descripcion", renderer,
  4720. "text", 1,
  4721. NULL);
  4722. gtk_tree_view_append_column (treeview_details, column);
  4723. //cantity
  4724. renderer = gtk_cell_renderer_text_new();
  4725. column = gtk_tree_view_column_new_with_attributes("Cantidad", renderer,
  4726. "text", 2,
  4727. NULL);
  4728. gtk_tree_view_append_column (treeview_details, column);
  4729. gtk_tree_view_column_set_cell_data_func (column, renderer, control_decimal, (gpointer)2, NULL);
  4730. //price
  4731. renderer = gtk_cell_renderer_text_new();
  4732. column = gtk_tree_view_column_new_with_attributes("Precio", renderer,
  4733. "text", 3,
  4734. NULL);
  4735. gtk_tree_view_append_column (treeview_details, column);
  4736. gtk_tree_view_column_set_cell_data_func (column, renderer, control_decimal, (gpointer)3, NULL);
  4737. //subtotal
  4738. renderer = gtk_cell_renderer_text_new();
  4739. column = gtk_tree_view_column_new_with_attributes("Subtotal", renderer,
  4740. "text", 4,
  4741. NULL);
  4742. gtk_tree_view_append_column (treeview_details, column);
  4743. }
  4744. gtk_list_store_clear(store_details);
  4745. widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_adm_pedido"));
  4746. gtk_widget_show_all (widget);
  4747. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_save_new_fecha_entrega")), FALSE);
  4748. }
  4749. /**
  4750. * Callback connected to the search button from 'wnd_adm_pedido' window.
  4751. *
  4752. * This function fills the treeview of sale accordgin with the filters
  4753. * applied by the user.
  4754. *
  4755. * @param button the button that emited the signal
  4756. * @param data the user data
  4757. */
  4758. void
  4759. on_btn_srch_adm_pedido_clicked (GtkButton *button, gpointer data)
  4760. {
  4761. GtkTreeView *treeview;
  4762. GtkListStore *store_pedido;
  4763. GtkTreeIter iter;
  4764. GtkEntry *entry;
  4765. gchar *id_reserva;
  4766. gchar *barcode;
  4767. gchar *date;
  4768. gchar *rut;
  4769. gchar *q;
  4770. gchar *condition = "";
  4771. PGresult *res;
  4772. gint i;
  4773. gint tuples;
  4774. GDate *gdate;
  4775. gchar **fecha_reserva, **fecha_entrega;
  4776. gchar str_date[256], str_date2[256];
  4777. entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_id_pedido"));
  4778. if (g_str_equal(gtk_entry_get_text(entry), ""))
  4779. id_reserva = NULL;
  4780. else
  4781. id_reserva = g_strdup(gtk_entry_get_text(entry));
  4782. entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_barcode_pedido"));
  4783. if (g_str_equal(gtk_entry_get_text(entry), ""))
  4784. barcode = NULL;
  4785. else
  4786. barcode = g_strdup(gtk_entry_get_text(entry));
  4787. entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_fecha_pedido"));
  4788. if (g_str_equal(gtk_entry_get_text(entry), ""))
  4789. date = NULL;
  4790. else
  4791. date = g_strdup(gtk_entry_get_text(entry));
  4792. entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_rut_pedido"));
  4793. if (g_str_equal(gtk_entry_get_text(entry), ""))
  4794. rut = NULL;
  4795. else
  4796. rut = g_strdup(gtk_entry_get_text(entry));
  4797. q = g_strdup ("SELECT id, monto, rut_cliente||(SELECT dv FROM cliente WHERE rut = rut_cliente) AS rut_cliente, "
  4798. " (SELECT nombre FROM cliente WHERE rut = rut_cliente) AS nombre_cliente, "
  4799. " DATE_TRUNC('day', fecha) AS fecha, DATE_TRUNC('day', fecha_entrega) AS fecha_entrega, "
  4800. " (SELECT COALESCE (SUM (monto_pagado),0) FROM pago_deuda_reserva WHERE id_deuda_reserva = (SELECT id FROM deuda_reserva WHERE id_reserva = reserva.id)) AS monto_pagado "
  4801. "FROM reserva "
  4802. "WHERE vendido = false ");
  4803. if (id_reserva != NULL)
  4804. {
  4805. if (atoi(id_reserva) == 0)
  4806. {
  4807. AlertMSG(GTK_WIDGET(entry), "Debe ingresar un N° de Pedido mayor a 0\nSi no sabe el numero de pedido deje el campo vacío");
  4808. return;
  4809. }
  4810. else
  4811. condition = g_strconcat (condition, " AND id=", id_reserva, NULL);
  4812. }
  4813. if (date != NULL)
  4814. {
  4815. GDate *date_aux;
  4816. gchar *str_date;
  4817. date_aux = g_date_new();
  4818. g_date_set_parse (date_aux, date);
  4819. str_date = g_strdup_printf("%d-%d-%d",
  4820. g_date_get_year(date_aux),
  4821. g_date_get_month(date_aux),
  4822. g_date_get_day(date_aux));
  4823. condition = g_strconcat (condition, " AND DATE_TRUNC('day', fecha)='", str_date, "'", NULL);
  4824. g_date_free (date_aux);
  4825. g_free (str_date);
  4826. }
  4827. if (barcode != NULL)
  4828. {
  4829. if (atoi(barcode) == 0)
  4830. {
  4831. AlertMSG(GTK_WIDGET(entry), "No puede ingresar un codigo de barras 0, o con caracteres\n"
  4832. "Si no sabe el código de barras deje el campo vacío");
  4833. return;
  4834. }
  4835. else
  4836. condition = g_strconcat(condition, " AND id IN (SELECT id_reserva FROM reserva_detalle WHERE barcode=", barcode, ")", NULL);
  4837. }
  4838. if (rut != NULL)
  4839. {
  4840. if (atoi(rut) == 0)
  4841. {
  4842. AlertMSG(GTK_WIDGET(entry), "No puede ingresar un monto 0\nSi no sabe el monto puede dejar el campo vacio");
  4843. return;
  4844. }
  4845. else
  4846. condition = g_strconcat(condition, " AND rut_cliente::varchar LIKE '", rut, "%%'", NULL);
  4847. }
  4848. if (!(g_str_equal(condition, "")))
  4849. {
  4850. q = g_strconcat (q, condition, NULL);
  4851. g_free (condition);
  4852. }
  4853. q = g_strconcat (q, "ORDER BY id ASC", NULL);
  4854. res = EjecutarSQL(q);
  4855. g_free (q);
  4856. tuples = PQntuples (res);
  4857. treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_pedido_detalle"));
  4858. gtk_list_store_clear (GTK_LIST_STORE(gtk_tree_view_get_model(treeview)));
  4859. treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_pedido"));
  4860. store_pedido = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
  4861. gtk_list_store_clear (store_pedido);
  4862. for (i=0 ; i < tuples ; i++)
  4863. {
  4864. fecha_reserva = g_strsplit(PQvaluebycol(res, i, "fecha"), "-", -1);
  4865. fecha_entrega = g_strsplit(PQvaluebycol(res, i, "fecha_entrega"), "-", -1);
  4866. gdate = g_date_new();
  4867. //Fecha reserva
  4868. g_date_set_year(gdate, atoi(fecha_reserva[0]));
  4869. g_date_set_month(gdate, atoi(fecha_reserva[1]));
  4870. g_date_set_day(gdate, atoi(fecha_reserva[2]));
  4871. g_date_strftime (str_date, sizeof(str_date), "%x", gdate);
  4872. //Fecha entrega
  4873. g_date_set_year(gdate, atoi(fecha_entrega[0]));
  4874. g_date_set_month(gdate, atoi(fecha_entrega[1]));
  4875. g_date_set_day(gdate, atoi(fecha_entrega[2]));
  4876. g_date_strftime (str_date2, sizeof(str_date2), "%x", gdate);
  4877. //Liberacion variables
  4878. g_strfreev(fecha_reserva);
  4879. g_date_free(gdate);
  4880. gtk_list_store_append (store_pedido, &iter);
  4881. gtk_list_store_set(store_pedido, &iter,
  4882. 0, atoi (PQvaluebycol (res, i, "id")),
  4883. 1, g_strdup (PQvaluebycol(res, i, "nombre_cliente")),
  4884. 2, str_date,
  4885. 3, str_date2,
  4886. 4, atoi (PQvaluebycol (res, i, "monto_pagado")),
  4887. 5, atoi (PQvaluebycol (res, i, "monto")),
  4888. 6, g_strdup (PQvaluebycol(res, i, "rut_cliente")),
  4889. -1);
  4890. }
  4891. }
  4892. /**
  4893. *
  4894. */
  4895. void
  4896. on_btn_save_new_fecha_entrega_clicked (GtkButton *button, gpointer data)
  4897. {
  4898. GtkTreeView *treeview = GTK_TREE_VIEW (builder_get (builder, "treeview_pedido"));
  4899. GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
  4900. GtkTreeModel *model = GTK_TREE_MODEL (gtk_tree_view_get_model (treeview));
  4901. GtkTreeIter iter;
  4902. gint reserva_id;
  4903. gchar *str_date;
  4904. GDate *date_aux;
  4905. if (! gtk_tree_selection_get_selected (selection, NULL, &iter)) return;
  4906. gtk_tree_model_get (model, &iter,
  4907. 0, &reserva_id,
  4908. -1);
  4909. if (reserva_id > 0)
  4910. {
  4911. str_date = g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_fecha_pedido_entrega"))));
  4912. if (g_str_equal (str_date, ""))
  4913. {
  4914. AlertMSG (GTK_WIDGET (builder_get (builder, "btn_fecha_pedido_entrega")),
  4915. "Debe seleccionar una fecha de entrega para este pedido");
  4916. return;
  4917. }
  4918. date_aux = g_date_new();
  4919. g_date_set_parse (date_aux, str_date);
  4920. actualizar_fecha_reserva (reserva_id, date_aux);
  4921. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_save_new_fecha_entrega")), FALSE);
  4922. on_btn_srch_adm_pedido_clicked (NULL, NULL);
  4923. }
  4924. }
  4925. /**
  4926. * Callback connected to 'changed' signal of 'treeview_pedido'.
  4927. *
  4928. * This function load the details of the selected order in the 'treeview_pedido_detalle'.
  4929. *
  4930. * @param treeselection the tree selection that emited the signal
  4931. * @param data the user data
  4932. */
  4933. void
  4934. on_selection_pedido_change (GtkTreeSelection *treeselection, gpointer data)
  4935. {
  4936. GtkListStore *store_pedido;
  4937. GtkListStore *store_details;
  4938. GtkTreeView *treeview_pedido;
  4939. GtkTreeView *treeview_details;
  4940. GtkTreeIter iter;
  4941. PGresult *res;
  4942. gint i;
  4943. gint tuples;
  4944. gchar *q;
  4945. gint reserva_id;
  4946. gchar *rut, *fecha_entrega;
  4947. treeview_pedido = gtk_tree_selection_get_tree_view(treeselection);
  4948. store_pedido = GTK_LIST_STORE(gtk_tree_view_get_model(treeview_pedido));
  4949. treeview_details = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_pedido_detalle"));
  4950. store_details = GTK_LIST_STORE(gtk_tree_view_get_model(treeview_details));
  4951. gtk_list_store_clear(store_details);
  4952. if (!(gtk_tree_selection_get_selected(treeselection, NULL, &iter))) return;
  4953. gtk_tree_model_get (GTK_TREE_MODEL(store_pedido), &iter,
  4954. 0, &reserva_id,
  4955. 3, &fecha_entrega,
  4956. 6, &rut,
  4957. -1);
  4958. gtk_label_set_text (GTK_LABEL (builder_get (builder, "lbl_rut_pedido")), formato_rut (rut));
  4959. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_fecha_pedido_entrega")), fecha_entrega);
  4960. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_save_new_fecha_entrega")), TRUE);
  4961. q = g_strdup_printf ("SELECT id, id_reserva, barcode, cantidad, precio, "
  4962. " (SELECT descripcion FROM producto WHERE barcode=reserva_detalle.barcode) AS descripcion, "
  4963. " (cantidad*precio) AS subtotal "
  4964. "FROM reserva_detalle WHERE id_reserva=%d", reserva_id);
  4965. res = EjecutarSQL(q);
  4966. g_free (q);
  4967. tuples = PQntuples(res);
  4968. for (i=0 ; i<tuples ; i++)
  4969. {
  4970. gtk_list_store_append (store_details, &iter);
  4971. gtk_list_store_set (store_details, &iter,
  4972. 0, atoi(PQvaluebycol(res, i, "barcode")),
  4973. 1, PQvaluebycol(res, i, "descripcion"),
  4974. 2, strtod(PUT(PQvaluebycol(res, i, "cantidad")), (char **)NULL),
  4975. 3, strtod(PUT(PQvaluebycol(res, i, "precio")), (char **)NULL),
  4976. 4, atoi(PQvaluebycol(res, i, "subtotal")),
  4977. 5, atoi(PQvaluebycol(res, i, "id")),
  4978. 6, atoi(PQvaluebycol(res, i, "id_reserva")),
  4979. -1);
  4980. }
  4981. }
  4982. /**
  4983. *
  4984. */
  4985. void
  4986. on_btn_adm_pedido_ok_clicked (GtkButton *button, gpointer data)
  4987. {
  4988. GtkTreeView *treeview = GTK_TREE_VIEW (builder_get (builder, "treeview_pedido"));
  4989. GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
  4990. GtkTreeModel *model = GTK_TREE_MODEL (gtk_tree_view_get_model (treeview));
  4991. GtkListStore *sell = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (builder_get (builder, "sell_products_list"))));
  4992. GtkTreeIter iter;
  4993. gint reserva_id;
  4994. guint32 total;
  4995. gdouble iva, otros;
  4996. PGresult *res;
  4997. gchar *q;
  4998. gint tuples, i;
  4999. gchar *rut_cliente;
  5000. gint monto, total_pagado;
  5001. if (! gtk_tree_selection_get_selected (selection, NULL, &iter)) return;
  5002. gtk_tree_model_get (model, &iter,
  5003. 0, &reserva_id,
  5004. 4, &total_pagado,
  5005. 5, &monto,
  5006. 6, &rut_cliente,
  5007. -1);
  5008. if (reserva_id > 0)
  5009. {
  5010. gtk_list_store_clear (sell);
  5011. CleanEntryAndLabelData ();
  5012. ListClean ();
  5013. /*Se llama a get_sale_detail con 'FALSE' para que entregue la venta tal cual como se hizo*/
  5014. //TODOOO: Se podrían obtener los productos directamente desde el treeview 'treeview_pedido_detalle' en vez de consultar a la BD
  5015. q = g_strdup_printf ("SELECT barcode, cantidad, precio FROM reserva_detalle WHERE id_reserva = %d", reserva_id);
  5016. res = EjecutarSQL (q);
  5017. g_free (q);
  5018. if (res != NULL && PQntuples (res) != 0)
  5019. {
  5020. tuples = PQntuples (res);
  5021. /*Se agregan las mercaderías independientemente de si tienen o no stock (al realizar el pago total de venta
  5022. ésta se finalizará y en ese proceso se debe exigir el stock suficiente de cada mercadería)*/
  5023. for (i = 0; i < tuples; i++)
  5024. {
  5025. AgregarALista (NULL, PQvaluebycol (res, i, "barcode"), strtod (PUT (PQvaluebycol (res, i, "cantidad")), (char **)NULL));
  5026. //Se reemplazan los 2 precios, para asegurarse que se venda con el precio puesto en el pedido, sin importar si la mercadería esta por mayor o no
  5027. venta->products->product->precio = strtod (PUT (PQvaluebycol (res, i, "precio")), (char **)NULL);
  5028. venta->products->product->precio_mayor = strtod (PUT (PQvaluebycol (res, i, "precio")), (char **)NULL);
  5029. iva = (gdouble)venta->products->product->iva / 100;
  5030. otros = (gdouble)venta->products->product->otros / 100;
  5031. venta->products->product->precio_neto = (venta->products->product->precio / (1 + otros + iva));
  5032. gtk_list_store_insert_after (sell, &iter, NULL);
  5033. gtk_list_store_set (sell, &iter,
  5034. 0, venta->products->product->codigo,
  5035. 1, g_strdup_printf ("%s %s %d %s",
  5036. venta->products->product->producto,
  5037. venta->products->product->marca,
  5038. venta->products->product->contenido,
  5039. venta->products->product->unidad),
  5040. 2, venta->products->product->cantidad,
  5041. 3, venta->products->product->precio_neto,
  5042. 4, lround (venta->products->product->cantidad * venta->products->product->precio_neto),
  5043. 5, venta->products->product->precio,
  5044. 6, lround (venta->products->product->cantidad * venta->products->product->precio),
  5045. 7, venta->products->product->stock,
  5046. 8, venta->products->product->cantidad_impresa,
  5047. 9, (venta->products->product->cantidad > venta->products->product->stock) ? "Red":"Black",
  5048. 10, TRUE,
  5049. -1);
  5050. venta->products->product->iter = iter;
  5051. }
  5052. total = llround (CalcularTotal (venta->header));
  5053. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")),
  5054. g_strdup_printf ("<span size=\"40000\">%s</span>",
  5055. PutPoints (g_strdup_printf ("%u", total))));
  5056. }
  5057. venta_reserva = TRUE;
  5058. venta->deuda_total = monto;
  5059. venta->total_pagado = total_pagado;
  5060. venta->rut_cliente = atoi (g_strndup (rut_cliente, (strlen(rut_cliente)-1)));
  5061. venta->id_reserva = reserva_id;
  5062. }
  5063. close_wnd_adm_pedido (NULL, NULL);
  5064. TipoVenta (NULL, NULL);
  5065. }
  5066. /**
  5067. *
  5068. */
  5069. gboolean
  5070. close_wnd_adm_pedido (GtkWidget *widget, gpointer data)
  5071. {
  5072. clean_container (GTK_CONTAINER (builder_get (builder, "wnd_adm_pedido")));
  5073. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_adm_pedido")));
  5074. return TRUE;
  5075. }
  5076. /**
  5077. *
  5078. */
  5079. gboolean
  5080. close_wnd_cliente_pre_factura (GtkWidget *widget, gpointer data)
  5081. {
  5082. clean_container (GTK_CONTAINER (builder_get (builder, "wnd_cliente_pre_factura")));
  5083. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_cliente_pre_factura")));
  5084. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_selectcli_pre_factura")), FALSE);
  5085. return TRUE;
  5086. }
  5087. /**
  5088. *
  5089. */
  5090. gboolean
  5091. on_btn_cliente_pre_factura_clicked (GtkWidget *widget, gpointer data)
  5092. {
  5093. gtk_widget_show (GTK_WIDGET (builder_get (builder, "wnd_cliente_pre_factura")));
  5094. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_rutcli_pre_factura")));
  5095. return TRUE;
  5096. }
  5097. /**
  5098. *
  5099. */
  5100. gboolean
  5101. on_btn_selectcli_pre_factura_clicked (GtkWidget *widget, gpointer data)
  5102. {
  5103. gchar *rut_cliente = g_strdup (gtk_entry_get_text (GTK_ENTRY (builder_get (builder, "entry_rutcli_pre_factura"))));
  5104. rut_cliente = g_strndup (rut_cliente, strlen (rut_cliente)-2);
  5105. if (rut_cliente == NULL || HaveCharacters (rut_cliente) || g_str_equal (rut_cliente, ""))
  5106. {
  5107. ErrorMSG (GTK_WIDGET (builder_get (builder, "entry_rutcli_pre_factura")),
  5108. g_strdup_printf ("Debe seleccionar un cliente"));
  5109. return FALSE;
  5110. }
  5111. rut_cliente_pre_factura = atoi (rut_cliente);
  5112. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "barcode_entry")), TRUE);
  5113. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "barcode_entry")));
  5114. gchar *nombre = g_strdup (gtk_label_get_text (GTK_LABEL (builder_get (builder,"lbl_nombrecli_pre_factura"))));
  5115. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "lbl_selected_client")),
  5116. g_strdup_printf ("<span size=\"15000\">%s</span>", nombre));
  5117. close_wnd_cliente_pre_factura (widget, data);
  5118. return TRUE;
  5119. }
  5120. /**
  5121. * Closes the nullify sale dialog and reset the data contained
  5122. *
  5123. */
  5124. void
  5125. close_nullify_sale_dialog(void)
  5126. {
  5127. GtkWidget *widget;
  5128. GtkListStore *store;
  5129. widget = GTK_WIDGET (gtk_builder_get_object(builder, "wnd_nullify_sale"));
  5130. gtk_widget_hide(widget);
  5131. widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_nullify_id"));
  5132. gtk_entry_set_text(GTK_ENTRY(widget), "");
  5133. gtk_widget_grab_focus(widget);
  5134. widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_nullify_barcode"));
  5135. gtk_entry_set_text(GTK_ENTRY(widget), "");
  5136. widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_nullify_amount"));
  5137. gtk_entry_set_text(GTK_ENTRY(widget), "");
  5138. widget = GTK_WIDGET (gtk_builder_get_object(builder, "entry_nullify_date"));
  5139. gtk_entry_set_text(GTK_ENTRY(widget), "");
  5140. widget = GTK_WIDGET (gtk_builder_get_object(builder, "treeview_nullify_sale"));
  5141. store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget)));
  5142. gtk_list_store_clear(store);
  5143. widget = GTK_WIDGET (gtk_builder_get_object(builder, "treeview_nullify_sale_details"));
  5144. store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget)));
  5145. gtk_list_store_clear(store);
  5146. }
  5147. /**
  5148. * Callback connected to the accept button of the nullify sale dialog
  5149. *
  5150. * This function get the selected sale and nullify it.
  5151. *
  5152. * @param button the button that emited the signal
  5153. * @param data the use data
  5154. */
  5155. void
  5156. on_btn_nullify_ok_clicked (GtkButton *button, gpointer data)
  5157. {
  5158. GtkTreeView *treeview = GTK_TREE_VIEW (builder_get (builder, "treeview_nullify_sale"));
  5159. GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
  5160. GtkTreeModel *model = GTK_TREE_MODEL (gtk_tree_view_get_model (treeview));
  5161. GtkListStore *sell = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (builder_get (builder, "sell_products_list"))));
  5162. GtkTreeIter iter;
  5163. gint sale_id;
  5164. gint monto;
  5165. gint tipo_venta, tipo_pago1, tipo_pago2;
  5166. gdouble iva, otros;
  5167. //gboolean is_credit_sell;
  5168. PGresult *res;
  5169. gchar *q;
  5170. gint tuples, i;
  5171. guint32 total;
  5172. if (! gtk_tree_selection_get_selected (selection, NULL, &iter)) return;
  5173. gtk_tree_model_get (model, &iter,
  5174. 0, &sale_id,
  5175. 3, &monto,
  5176. -1);
  5177. //Se ve el tipo de venta, de ser mixta se obtienen los tipos y montos de cada pago
  5178. tipo_venta = atoi (PQvaluebycol (EjecutarSQL (g_strdup_printf ("SELECT tipo_venta FROM venta WHERE id=%d", sale_id)), 0, "tipo_venta"));
  5179. if (tipo_venta == MIXTO)
  5180. {
  5181. tipo_pago1 = atoi (PQvaluebycol (EjecutarSQL (g_strdup_printf ("SELECT tipo_pago1 FROM pago_mixto WHERE id_sale=%d", sale_id)), 0, "tipo_pago1"));
  5182. tipo_pago2 = atoi (PQvaluebycol (EjecutarSQL (g_strdup_printf ("SELECT tipo_pago2 FROM pago_mixto WHERE id_sale=%d", sale_id)), 0, "tipo_pago2"));
  5183. if (tipo_pago1 == CASH)
  5184. monto = atoi (PQvaluebycol (EjecutarSQL (g_strdup_printf ("SELECT monto1 FROM pago_mixto WHERE id_sale=%d", sale_id)), 0, "monto1"));
  5185. else if (tipo_pago2 == CASH)
  5186. monto = atoi (PQvaluebycol (EjecutarSQL (g_strdup_printf ("SELECT monto2 FROM pago_mixto WHERE id_sale=%d", sale_id)), 0, "monto2"));
  5187. }
  5188. /*Se comprueba que el monto de la venta sea menor al dinero en caja*/ //TODO: Si no hay suficiente dinero, que devuelva lo que tiene
  5189. if ( (tipo_venta == CASH || (tipo_venta == MIXTO && (tipo_pago1 == CASH || tipo_pago2 == CASH)))
  5190. && rizoma_get_value_boolean ("CAJA") == TRUE //Si la caja esta habilitada se preocupa de ver el monto en caja
  5191. && monto > ArqueoCaja()) //Entra aquí si la venta fué en efectivo y no hay dinero para devolver
  5192. {
  5193. ErrorMSG (GTK_WIDGET (gtk_builder_get_object (builder, "treeview_nullify_sale")),
  5194. "No existe monto suficiente en caja para anular esta venta");
  5195. return;
  5196. }
  5197. if (nullify_sale (sale_id) == 0)
  5198. {
  5199. gtk_list_store_clear (sell);
  5200. CleanEntryAndLabelData ();
  5201. ListClean ();
  5202. /*Se llama a get_sale_detail con 'FALSE' para que entregue la venta tal cual como se hizo*/
  5203. q = g_strdup_printf ("SELECT * FROM get_sale_detail (%d, FALSE)", sale_id);
  5204. res = EjecutarSQL (q);
  5205. g_free (q);
  5206. if (res != NULL && PQntuples (res) != 0)
  5207. {
  5208. tuples = PQntuples (res);
  5209. for (i = 0; i < tuples; i++)
  5210. {
  5211. AgregarALista (NULL, PQvaluebycol (res, i, "barcode"), strtod (PUT (PQvaluebycol (res, i, "amount")), (char **)NULL));
  5212. venta->products->product->precio = strtod (PUT (PQvaluebycol (res, i, "price")), (char **)NULL);
  5213. iva = (gdouble)venta->products->product->iva / 100;
  5214. otros = (gdouble)venta->products->product->otros / 100;
  5215. venta->products->product->precio_neto = (venta->products->product->precio / (1 + otros + iva));
  5216. gtk_list_store_insert_after (sell, &iter, NULL);
  5217. gtk_list_store_set (sell, &iter,
  5218. 0, venta->products->product->codigo,
  5219. 1, g_strdup_printf ("%s %s %d %s",
  5220. venta->products->product->producto,
  5221. venta->products->product->marca,
  5222. venta->products->product->contenido,
  5223. venta->products->product->unidad),
  5224. 2, venta->products->product->cantidad,
  5225. 3, venta->products->product->precio_neto,
  5226. 4, lround (venta->products->product->cantidad * venta->products->product->precio_neto),
  5227. 5, venta->products->product->precio,
  5228. 6, lround (venta->products->product->cantidad * venta->products->product->precio),
  5229. 7, venta->products->product->stock,
  5230. 8, venta->products->product->cantidad_impresa,
  5231. 9, (venta->products->product->cantidad > venta->products->product->stock) ? "Red":"Black",
  5232. 10, TRUE,
  5233. -1);
  5234. venta->products->product->iter = iter;
  5235. }
  5236. total = llround (CalcularTotal (venta->header));
  5237. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_total")),
  5238. g_strdup_printf ("<span size=\"40000\">%s</span>",
  5239. PutPoints (g_strdup_printf ("%u", total))));
  5240. }
  5241. }
  5242. else if (rizoma_get_value_boolean("CAJA") == 0) // Si entra en este else if significa que nunca se ha habilitado caja. TODO: debería permitir anular sin caja!
  5243. {
  5244. // TODO: la ventana aparece atrás, se debe lograr que se sobreponga a la ventana wnd_sell
  5245. // Si es que no hay datos en caja, y CAJA = 0 en el .rizoma, entonces tiene que aparecer una ventana que diga:
  5246. AlertMSG (GTK_WIDGET (gtk_builder_get_object (builder, "wnd_sell")),"Para realizar una devolución es necesario habilitar e iniciar caja con anterioridad, asegúrese de habilitar caja en el .rizoma y vuelva a ejecutar rizoma-ventas");
  5247. }
  5248. close_nullify_sale_dialog ();
  5249. }
  5250. /**
  5251. * Es llamado por 'dialog_cash_box_opened', para abrir una nueva caja
  5252. * o cerrar la apliación.
  5253. */
  5254. void
  5255. on_dialog_cash_box_closed_response (GtkDialog *dialog, gint response_id, gpointer user_data)
  5256. {
  5257. GtkWidget *aux_widget;
  5258. switch (response_id)
  5259. {
  5260. /*Si quiere abrir una nueva caja y continuar*/
  5261. case -8:
  5262. open_caja (FALSE);
  5263. break;
  5264. case -9:
  5265. aux_widget = GTK_WIDGET (gtk_builder_get_object (builder, "quit_message"));
  5266. gtk_dialog_response (GTK_DIALOG(aux_widget), GTK_RESPONSE_YES);
  5267. break;
  5268. default:
  5269. break;
  5270. }
  5271. gtk_widget_hide (GTK_WIDGET (dialog));
  5272. }
  5273. /**
  5274. * Es llamado por 'dialog_cash_box_opened', para cerrar una caja o
  5275. * continuar con la que esta abierta.
  5276. */
  5277. void
  5278. on_dialog_cash_box_opened_response (GtkDialog *dialog, gint response_id, gpointer user_data)
  5279. {
  5280. switch (response_id)
  5281. {
  5282. case -8:
  5283. CerrarCajaWin ();
  5284. break;
  5285. case -9:
  5286. break;
  5287. default:
  5288. break;
  5289. }
  5290. gtk_widget_hide (GTK_WIDGET (dialog));
  5291. }
  5292. /**
  5293. * Es llamada cuando el boton "btn_devolver" es presionado (signal click).
  5294. *
  5295. * Esta Funcion visualiza la ventana "wnd_devolver" (ventana para realizar
  5296. * una devolucion de productos al proveedor).
  5297. *
  5298. * @param widget the widget that emits the signal
  5299. * @param data the user data
  5300. *
  5301. */
  5302. void
  5303. on_btn_devolver_clicked (GtkWidget *widget, gpointer data)
  5304. {
  5305. GtkWindow *window;
  5306. //reviza si no hay productos
  5307. if (venta->header == NULL)
  5308. {
  5309. ErrorMSG (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")), "No hay productos para devolver");
  5310. return;
  5311. }
  5312. window = GTK_WINDOW (gtk_builder_get_object (builder, "wnd_devolver"));
  5313. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_proveedor")));
  5314. clean_container (GTK_CONTAINER (window));
  5315. gtk_widget_show_all (GTK_WIDGET (window));
  5316. }
  5317. /**
  5318. * Es llamada cuando se presiona enter(signal actived) en el "entry_proveedor"
  5319. * de la ventana "wnd_devolver).
  5320. *
  5321. * Esta Funcion visualiza la ventana "wnd_srch_provider"(que es para buscar
  5322. * un proveedor) y ademas carga el tree_view para luego visualizar la
  5323. * busqueda de proveedores encontrados.
  5324. *
  5325. * @param entry the entry that emits the signal
  5326. *
  5327. */
  5328. void
  5329. on_entry_srch_provider_activate (GtkEntry *entry, gpointer user_data)
  5330. {
  5331. GtkListStore *store;
  5332. GtkTreeIter iter;
  5333. PGresult *res;
  5334. gint tuples, i;
  5335. gchar *str_schr = g_strdup (gtk_entry_get_text (entry));
  5336. gchar *str_axu;
  5337. gchar *q;
  5338. /*
  5339. consulta a la BD, para obtener los rut's con su correspondiente digito
  5340. verificador y los nombres de los proveedores
  5341. */
  5342. q = g_strdup_printf ("SELECT rut, dv, nombre "
  5343. "FROM buscar_proveedor ('%%%s%%')", str_schr);
  5344. g_free (str_schr);
  5345. res = EjecutarSQL (q);
  5346. g_free (q);
  5347. tuples = PQntuples (res);
  5348. store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_builder_get_object (builder, "tree_view_srch_provider"))));
  5349. gtk_list_store_clear (store);
  5350. /*
  5351. visualiza en treeView los proveedores
  5352. */
  5353. for (i = 0; i < tuples; i++)
  5354. {
  5355. str_axu = g_strconcat(PQvaluebycol (res, i, "rut"),"-",
  5356. PQvaluebycol (res, i, "dv"), NULL);
  5357. gtk_list_store_append (store, &iter);
  5358. gtk_list_store_set (store, &iter,
  5359. 0, PQvaluebycol (res, i, "nombre"),
  5360. 1, str_axu,
  5361. -1);
  5362. g_free (str_axu);
  5363. }
  5364. gtk_widget_grab_focus (GTK_WIDGET (GTK_TREE_VIEW (gtk_builder_get_object (builder, "tree_view_srch_provider"))));
  5365. gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (gtk_builder_get_object (builder, "tree_view_srch_provider"))), gtk_tree_path_new_from_string ("0"));
  5366. }
  5367. /**
  5368. *
  5369. */
  5370. void
  5371. on_sencillo_entry_activate (GtkEntry *entry, gpointer user_data)
  5372. {
  5373. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "sell_button")));
  5374. if (gtk_widget_get_sensitive (GTK_WIDGET (builder_get (builder, "sell_button"))))
  5375. {
  5376. gtk_widget_set_sensitive (GTK_WIDGET (builder_get (builder, "btn_close_win")), FALSE);
  5377. abrirGaveta();
  5378. }
  5379. }
  5380. /**
  5381. * Es llamada cuando se presiona enter(signal actived) en el "entry_proveedor"
  5382. * de la ventana "wnd_devolver".
  5383. *
  5384. * Esta Funcion visualiza la ventana "wnd_srch_provider"(que es para buscar
  5385. * un proveedor) y ademas carga el tree_view para luego visualizar la
  5386. * busqueda de proveedores encontrados.
  5387. *
  5388. * @param entry the entry that emits the signal
  5389. * @param data the user data
  5390. *
  5391. */
  5392. void
  5393. on_entry_provider_activate (GtkEntry *entry, gpointer user_data)
  5394. {
  5395. GtkWindow *window;
  5396. GtkTreeView *tree = GTK_TREE_VIEW (gtk_builder_get_object(builder, "tree_view_srch_provider"));
  5397. GtkListStore *store;
  5398. GtkCellRenderer *renderer;
  5399. GtkTreeViewColumn *column;
  5400. //gchar *srch_provider = g_strdup (gtk_entry_get_text (entry));
  5401. gchar *str_schr = g_strdup (gtk_entry_get_text (entry));
  5402. if (gtk_tree_view_get_model (tree) == NULL )
  5403. {
  5404. store = gtk_list_store_new (2,
  5405. G_TYPE_STRING,
  5406. G_TYPE_STRING);
  5407. gtk_tree_view_set_model (GTK_TREE_VIEW (tree), GTK_TREE_MODEL (store));
  5408. renderer = gtk_cell_renderer_text_new ();
  5409. column = gtk_tree_view_column_new_with_attributes ("Proveedor", renderer,
  5410. "text", 0,
  5411. NULL);
  5412. gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
  5413. gtk_tree_view_column_set_resizable (column, FALSE);
  5414. renderer = gtk_cell_renderer_text_new ();
  5415. column = gtk_tree_view_column_new_with_attributes ("Rut Proveedor", renderer,
  5416. "text", 1,
  5417. NULL);
  5418. gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
  5419. gtk_tree_view_column_set_resizable (column, FALSE);
  5420. }
  5421. window = GTK_WINDOW (gtk_builder_get_object (builder, "wnd_srch_provider"));
  5422. gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object(builder, "entry_srch_provider")), str_schr);
  5423. on_entry_srch_provider_activate(entry, NULL);
  5424. gtk_widget_show_all (GTK_WIDGET (window));
  5425. }
  5426. /**
  5427. * Es llamada cuando se presiona enter (signal actived) en el "entry_emisor"
  5428. * de la ventana "wnd_srch_emisor.
  5429. *
  5430. * Visualiza la ventana "wnd_srch_emisor" y realiza la
  5431. * busqueda de emisores.
  5432. *
  5433. * @param entry the entry that emits the signal
  5434. */
  5435. void
  5436. on_entry_srch_emisor_activate (GtkEntry *entry, gpointer user_data)
  5437. {
  5438. GtkListStore *store;
  5439. GtkTreeIter iter;
  5440. PGresult *res;
  5441. gint tuples, i;
  5442. gchar *str_schr = g_strdup (gtk_entry_get_text (entry));
  5443. gchar *str_axu;
  5444. gchar *q;
  5445. /*
  5446. consulta a la BD, para obtener los rut's con su correspondiente digito
  5447. verificador y los nombres de los proveedores
  5448. */
  5449. q = g_strdup_printf ("SELECT id, rut, dv, razon_social "
  5450. "FROM buscar_emisor ('%%%s%%')", str_schr);
  5451. g_free (str_schr);
  5452. res = EjecutarSQL (q);
  5453. g_free (q);
  5454. tuples = PQntuples (res);
  5455. store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_builder_get_object (builder, "tree_view_srch_emisor"))));
  5456. gtk_list_store_clear (store);
  5457. /*
  5458. visualiza en treeView los proveedores
  5459. */
  5460. for (i = 0; i < tuples; i++)
  5461. {
  5462. str_axu = g_strconcat (PQvaluebycol (res, i, "rut"),
  5463. PQvaluebycol (res, i, "dv"), NULL);
  5464. gtk_list_store_append (store, &iter);
  5465. gtk_list_store_set (store, &iter,
  5466. 0, atoi(PQvaluebycol (res, i, "id")),
  5467. 1, PQvaluebycol (res, i, "razon_social"),
  5468. 2, str_axu,
  5469. -1);
  5470. g_free (str_axu);
  5471. }
  5472. if (tuples > 0)
  5473. {
  5474. gtk_widget_grab_focus (GTK_WIDGET (GTK_TREE_VIEW (gtk_builder_get_object (builder, "tree_view_srch_emisor"))));
  5475. gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (builder_get (builder, "tree_view_srch_emisor"))),
  5476. gtk_tree_path_new_from_string ("0"));
  5477. }
  5478. else
  5479. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_srch_emisor")));
  5480. }
  5481. /**
  5482. * Es llamada cuando se presiona enter(signal actived) en el "entry_proveedor"
  5483. * de la ventana "wnd_devolver".
  5484. *
  5485. * Esta Funcion visualiza la ventana "wnd_srch_provider"(que es para buscar
  5486. * un proveedor) y ademas carga el tree_view para luego visualizar la
  5487. * busqueda de proveedores encontrados.
  5488. *
  5489. * @param entry the entry that emits the signal
  5490. * @param data the user data
  5491. *
  5492. */
  5493. void
  5494. show_srch_emisor (GtkEntry *entry, gpointer user_data)
  5495. {
  5496. GtkWindow *window;
  5497. GtkTreeView *tree = GTK_TREE_VIEW (gtk_builder_get_object(builder, "tree_view_srch_emisor"));
  5498. GtkListStore *store;
  5499. GtkCellRenderer *renderer;
  5500. GtkTreeViewColumn *column;
  5501. //gchar *srch_provider = g_strdup (gtk_entry_get_text (entry));
  5502. gchar *str_schr = g_strdup (gtk_entry_get_text (entry));
  5503. if (gtk_tree_view_get_model (tree) == NULL )
  5504. {
  5505. store = gtk_list_store_new (3,
  5506. G_TYPE_INT, //id
  5507. G_TYPE_STRING, //Razon Social
  5508. G_TYPE_STRING); //Rut
  5509. gtk_tree_view_set_model (GTK_TREE_VIEW (tree), GTK_TREE_MODEL (store));
  5510. renderer = gtk_cell_renderer_text_new ();
  5511. column = gtk_tree_view_column_new_with_attributes ("Emisor", renderer,
  5512. "text", 1,
  5513. NULL);
  5514. gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
  5515. gtk_tree_view_column_set_resizable (column, FALSE);
  5516. renderer = gtk_cell_renderer_text_new ();
  5517. column = gtk_tree_view_column_new_with_attributes ("Rut Emisor", renderer,
  5518. "text", 2,
  5519. NULL);
  5520. gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
  5521. gtk_tree_view_column_set_resizable (column, FALSE);
  5522. gtk_tree_view_column_set_cell_data_func (column, renderer, control_rut, (gpointer)2, NULL);
  5523. }
  5524. window = GTK_WINDOW (gtk_builder_get_object (builder, "wnd_srch_emisor"));
  5525. gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object (builder, "entry_srch_emisor")), str_schr);
  5526. on_entry_srch_emisor_activate (entry, NULL);
  5527. gtk_widget_show_all (GTK_WIDGET (window));
  5528. }
  5529. /**
  5530. * This function enters the sale when the amount
  5531. * entered is enough, else show the 'wnd_mixed_pay_step2'
  5532. * to complete. (signal-clicked)
  5533. *
  5534. * @param: GtkButton *button
  5535. * @param: gpointer data
  5536. */
  5537. void
  5538. on_entry_rut_mixed_pay_activate (GtkEntry *entry, gpointer data)
  5539. {
  5540. if (gtk_widget_get_visible (GTK_WIDGET (builder_get (builder,"wnd_mixed_pay_step1"))))
  5541. {
  5542. if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (builder_get (builder, "radio_btn_cheques"))))
  5543. show_srch_emisor (entry, data);
  5544. else
  5545. search_client (GTK_WIDGET (entry), data);
  5546. }
  5547. else if (gtk_widget_get_visible (GTK_WIDGET (builder_get (builder,"wnd_mixed_pay_step2"))))
  5548. search_client (GTK_WIDGET (entry), data);
  5549. }
  5550. void
  5551. on_btn_ok_srch_emisor_clicked (GtkButton *button, gpointer user_data)
  5552. {
  5553. GtkWidget *aux;
  5554. GtkListStore *store;
  5555. GtkTreeSelection *selection;
  5556. GtkTreeIter iter;
  5557. gchar *rut, *dv, *razon_social;
  5558. gint id;
  5559. //PGresult *res;
  5560. //gchar *q;
  5561. aux = GTK_WIDGET(gtk_builder_get_object(builder, "tree_view_srch_emisor"));
  5562. store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(aux)));
  5563. selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(aux));
  5564. if (!(gtk_tree_selection_get_selected(selection, NULL, &iter)))
  5565. {
  5566. aux = GTK_WIDGET(gtk_builder_get_object(builder, "entry_srch_emisor"));
  5567. AlertMSG (aux, "Debe seleccionar un cliente");
  5568. return;
  5569. }
  5570. //Obtengo los datos de la fila seleccionada
  5571. gtk_tree_model_get (GTK_TREE_MODEL(store), &iter,
  5572. 0, &id,
  5573. 1, &razon_social,
  5574. 2, &rut,
  5575. -1);
  5576. dv = invested_strndup (rut, strlen (rut)-1);
  5577. rut = g_strndup (rut, strlen (rut)-1);
  5578. rut = g_strconcat (rut, "-", dv, NULL);
  5579. //Cierro la ventana se búsqueda del emisor
  5580. aux = GTK_WIDGET(gtk_builder_get_object(builder, "wnd_srch_emisor"));
  5581. gtk_widget_hide(aux);
  5582. //Seteo la información obtenida en los entry's y labels correspondientes
  5583. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_rut_mixed_pay")), rut);
  5584. gtk_label_set_markup (GTK_LABEL (builder_get (builder, "lbl_name_mixed_pay")),
  5585. g_strdup_printf ("<b>%s</b>", razon_social));
  5586. pago_chk_rest->id_emisor = id;
  5587. pago_chk_rest->rut_emisor = g_strdup (rut);
  5588. if (gtk_widget_get_visible (GTK_WIDGET (builder_get (builder,"entry_int_code_mixed_pay"))))
  5589. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_int_code_mixed_pay")));
  5590. else
  5591. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_int_code_detail_mp")));
  5592. }
  5593. /**
  5594. * Es llamada por la funcion on_btn_ok_srch_provider_clicked() y recibe el
  5595. * parametro gchar rut.
  5596. *
  5597. * Esta funcion con el parametro de entrada rut realiza una consulta a la BD,
  5598. * para obtener el nombre del proveedor y luego visualiza (set text) los
  5599. * datos en los respctivas etiquetas (label)
  5600. *
  5601. * @param rut the rut of the proveedor
  5602. *
  5603. */
  5604. void
  5605. FillProveedorData (gchar *rut)
  5606. {
  5607. PGresult *res;
  5608. res = EjecutarSQL (g_strdup_printf ("SELECT nombre, rut FROM select_proveedor('%s')", rut));
  5609. gtk_entry_set_text (GTK_ENTRY (builder_get (builder, "entry_proveedor")), PQvaluebycol (res, 0, "nombre"));
  5610. gtk_label_set_markup (GTK_LABEL (builder_get (builder, "label_proveedor_rut")),
  5611. g_strdup_printf ("<span weight=\"ultrabold\">%s</span>", rut));
  5612. gtk_label_set_markup (GTK_LABEL (builder_get (builder, "label_proveedor_nom")),
  5613. g_strdup_printf ("<span weight=\"ultrabold\">%s</span>",
  5614. PQvaluebycol (res, 0, "nombre")));
  5615. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "btn_devolucion")));
  5616. }
  5617. /**
  5618. * Es llamada cuando el boton "btn_devolucion" es presionado (signal click).
  5619. *
  5620. * Esta funcion llama a la funcion SaveDevolucion()(que registra en la BD la
  5621. * devolucion(tablas devolucion y devolucion_detalle)) ademas de limpiar
  5622. * treeview de los productos vendidos, la etiqueta(label) total, y el numero
  5623. * de ventas.
  5624. *
  5625. * @param button the button
  5626. * @param user_data the user data
  5627. */
  5628. void
  5629. on_btn_devolucion_clicked (GtkButton *button, gpointer data)
  5630. {
  5631. gint monto = atoi (CutPoints (g_strdup (gtk_label_get_text
  5632. (GTK_LABEL (gtk_builder_get_object (builder, "label_total"))))));
  5633. gint rut = atoi (CutPoints (g_strdup (gtk_label_get_text
  5634. (GTK_LABEL (gtk_builder_get_object (builder, "label_proveedor_rut"))))));
  5635. if (g_str_equal(gtk_entry_get_text(GTK_ENTRY (gtk_builder_get_object (builder, "entry_proveedor"))), ""))
  5636. {
  5637. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_proveedor")));
  5638. AlertMSG (GTK_WIDGET (gtk_builder_get_object (builder, "wnd_devolver")),"No Ingreso un Proveedor");
  5639. //gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_proveedor")));
  5640. return;
  5641. }
  5642. if (!DataExist (g_strdup_printf ("SELECT rut FROM proveedor WHERE rut=%d",rut)))
  5643. {
  5644. gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_proveedor")));
  5645. AlertMSG (GTK_WIDGET (gtk_builder_get_object (builder, "wnd_devolver")),"El rut no existe");
  5646. //gtk_widget_grab_focus (GTK_WIDGET (builder_get (builder, "entry_proveedor")));
  5647. return;
  5648. }
  5649. else
  5650. {
  5651. SaveDevolucion (monto,rut);
  5652. gtk_widget_hide (gtk_widget_get_toplevel (GTK_WIDGET (button)));
  5653. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  5654. gtk_list_store_clear (venta->store);
  5655. CleanEntryAndLabelData ();
  5656. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_ticket_number")),
  5657. g_strdup_printf ("<span size=\"15000\">%.6d</span>", get_ticket_number (SIMPLE)-1)); //antes get_last_sell_id ()
  5658. ListClean ();
  5659. }
  5660. }
  5661. /**
  5662. * Es llamada por la funcion realizar_traspaso_Env()
  5663. *
  5664. * Esta funcion carga las etiquetas (labels) de la ventana
  5665. * "traspaso_enviar_win", ademas del combobox de destino, con los respectivos valores
  5666. *
  5667. */
  5668. void
  5669. DatosEnviar (void)
  5670. {
  5671. GtkWidget *combo;
  5672. GtkTreeIter iter;
  5673. GtkListStore *modelo;
  5674. gint tuples,i;
  5675. PGresult *res;
  5676. //gint venta_id;
  5677. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "comboboxDestino")));
  5678. //gint total = atoi (CutPoints (g_strdup (gtk_label_get_text (GTK_LABEL (gtk_builder_get_object (builder, "label_total"))))));
  5679. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_monto_total")),
  5680. g_strdup_printf ("%f",TotalPrecioCompra(venta->header)));
  5681. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_origen")),(gchar *)ReturnNegocio());
  5682. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "labelID")),g_strdup_printf ("%d",InsertIdTraspaso()+1));
  5683. gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "label_vendedor")),
  5684. g_strdup (gtk_label_get_text ( GTK_LABEL (gtk_builder_get_object (builder,"label_seller_name")))));
  5685. res = EjecutarSQL (g_strdup_printf ("SELECT id,nombre FROM bodega "
  5686. "WHERE nombre!=(SELECT nombre FROM negocio) AND estado=true"));
  5687. tuples = PQntuples (res);
  5688. combo = GTK_WIDGET (gtk_builder_get_object(builder, "comboboxDestino"));
  5689. modelo = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo)));
  5690. if (modelo == NULL)
  5691. {
  5692. GtkCellRenderer *cell;
  5693. modelo = gtk_list_store_new (2,
  5694. G_TYPE_INT,
  5695. G_TYPE_STRING);
  5696. gtk_combo_box_set_model(GTK_COMBO_BOX(combo), GTK_TREE_MODEL(modelo));
  5697. cell = gtk_cell_renderer_text_new();
  5698. gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(combo), cell, TRUE);
  5699. gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), cell,
  5700. "text", 1,
  5701. NULL);
  5702. }
  5703. gtk_list_store_clear(modelo);
  5704. for (i=0 ; i < tuples ; i++)
  5705. {
  5706. gtk_list_store_append(modelo, &iter);
  5707. gtk_list_store_set(modelo, &iter,
  5708. 0, atoi(PQvaluebycol(res, i, "id")),
  5709. 1, PQvaluebycol(res, i, "nombre"),
  5710. -1);
  5711. }
  5712. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "comboboxDestino")));
  5713. gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
  5714. }
  5715. /**
  5716. * Es llamada cuando se selecciona un proveedor del TreeView a traves de un
  5717. * enter (signal row-actived) o presionando el boton de la ventana "wnd_devolver"
  5718. * (signal clicked).
  5719. *
  5720. * Esta funcion extrae lo seleccionado en TreeView y lo carga en strs y se
  5721. * envia en la funcion FillProveedorData().
  5722. *
  5723. * @param TreeView the tree that emits the signal
  5724. *
  5725. */
  5726. void
  5727. on_btn_ok_srch_provider_clicked (GtkTreeView *tree)
  5728. {
  5729. GtkTreeSelection *selection = gtk_tree_view_get_selection (tree);
  5730. GtkTreeModel *model = gtk_tree_view_get_model (tree);
  5731. GtkTreeIter iter;
  5732. gchar *str;
  5733. gchar **strs;
  5734. if (gtk_tree_selection_get_selected (selection, NULL, &iter) == TRUE)
  5735. {
  5736. gtk_tree_model_get (model, &iter,
  5737. 1, &str,
  5738. -1);
  5739. strs = g_strsplit (str, "-", 2);
  5740. FillProveedorData (*strs);
  5741. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_srch_provider")));
  5742. }
  5743. }
  5744. /**
  5745. * Es llamada cuando el boton "btn_traspaso_enviar" es presionado (signal click).
  5746. *
  5747. * Esta funcion visualiza la ventana "traspaso_enviar_win" y ademas llama a
  5748. * la funcion DatosEnviar().
  5749. *
  5750. * @param widget the widget that emits the signal
  5751. * @param data the user data
  5752. *
  5753. */
  5754. void
  5755. realizar_traspaso_Env (GtkWidget *widget, gpointer data)
  5756. {
  5757. GtkWindow *window;
  5758. //gchar *tipo_vendedor = rizoma_get_value ("VENDEDOR");
  5759. /*Comprueba que hallan productos añadidos en el treView para traspasar */
  5760. if (venta->header == NULL)
  5761. {
  5762. ErrorMSG (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")), "No hay productos para traspasar");
  5763. return;
  5764. }
  5765. else
  5766. {
  5767. window = GTK_WINDOW (gtk_builder_get_object (builder, "traspaso_enviar_win"));
  5768. clean_container (GTK_CONTAINER (window));
  5769. gtk_widget_show_all (GTK_WIDGET (window));
  5770. DatosEnviar();
  5771. return;
  5772. }
  5773. }
  5774. /**
  5775. * Es llamada cuando el boton "traspaso_button" es presionado (signal click).
  5776. *
  5777. * Esta funcion visualiza la ventana "traspaso_enviar_win".
  5778. *
  5779. * @param widget the widget that emits the signal
  5780. * @param data the user data
  5781. *
  5782. */
  5783. void
  5784. on_enviar_button_clicked (GtkButton *button, gpointer data)
  5785. {
  5786. gint destino;
  5787. GtkTreeIter iter;
  5788. GtkWidget *combo;
  5789. GtkTreeModel *model;
  5790. gint active;
  5791. gint vendedor = user_data->user_id;
  5792. /*gint monto = atoi (CutPoints (g_strdup (gtk_label_get_text
  5793. (GTK_LABEL (gtk_builder_get_object (builder, "label_total"))))));*/
  5794. gint id_traspaso;
  5795. gchar *nombre_origen, *nombre_destino;
  5796. combo = GTK_WIDGET (gtk_builder_get_object(builder, "comboboxDestino"));
  5797. active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
  5798. nombre_origen = g_strdup (gtk_label_get_text (GTK_LABEL (builder_get (builder, "label_origen"))));
  5799. /* Verifica si se selecciono un destino del combobox*/
  5800. if (active == -1)
  5801. ErrorMSG (combo, "Debe Seleccionar un Destino");
  5802. else
  5803. {
  5804. model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
  5805. gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter);
  5806. gtk_tree_model_get (model, &iter,
  5807. 0, &destino,
  5808. 1, &nombre_destino,
  5809. -1);
  5810. id_traspaso = SaveTraspaso (TotalPrecioCompra(venta->header),
  5811. ReturnBodegaID(ReturnNegocio()),
  5812. vendedor,
  5813. destino,
  5814. TRUE);
  5815. PrintValeTraspaso (venta->header, id_traspaso, TRUE, nombre_origen, nombre_destino);
  5816. gtk_widget_hide (gtk_widget_get_toplevel (GTK_WIDGET (button)));
  5817. gtk_widget_hide (GTK_WIDGET(gtk_builder_get_object(builder, "traspaso_enviar_win")));
  5818. gtk_widget_grab_focus (GTK_WIDGET (gtk_builder_get_object (builder, "barcode_entry")));
  5819. gtk_list_store_clear (venta->store);
  5820. CleanEntryAndLabelData ();
  5821. gtk_label_set_markup (GTK_LABEL (gtk_builder_get_object (builder, "label_ticket_number")),
  5822. g_strdup_printf ("<span size=\"15000\">%.6d</span>", get_ticket_number (SIMPLE)-1)); //antes get_last_sell_id ()
  5823. ListClean ();
  5824. }
  5825. return;
  5826. }
  5827. /**
  5828. *
  5829. */
  5830. void
  5831. normalizar_treeview_venta ()
  5832. {
  5833. GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (builder_get (builder, "sell_products_list")));
  5834. GtkTreeIter iter;
  5835. gboolean valid;
  5836. gdouble cantidad, stock;
  5837. valid = gtk_tree_model_get_iter_first (model, &iter);
  5838. while (valid)
  5839. {
  5840. gtk_tree_model_get (model, &iter,
  5841. 2, &cantidad, // Se obtiene el codigo del producto
  5842. 7, &stock,
  5843. -1);
  5844. gtk_list_store_set (GTK_LIST_STORE (model), &iter,
  5845. 8, cantidad, //cantidad_impresa = cantidad
  5846. 9, (cantidad > stock) ? "Red" : "Black",
  5847. -1);
  5848. valid = gtk_tree_model_iter_next (model, &iter);
  5849. }
  5850. }
  5851. /**
  5852. *
  5853. *
  5854. * @param button the GtkButton that recieves the signal
  5855. * @param data the pointer passed to the callback
  5856. */
  5857. gint
  5858. on_btn_print_mesa_clicked (GtkButton *button, gpointer data)
  5859. {
  5860. if (get_treeview_length (GTK_TREE_VIEW (builder_get (builder, "sell_products_list"))) > 0)
  5861. PrintValeMesa (venta->header, venta->num_mesa);
  5862. gtk_widget_hide (GTK_WIDGET (builder_get (builder, "wnd_print_mesa")));
  5863. normalizar_treeview_venta ();
  5864. //Se reinicia rizoma
  5865. gtk_main_quit ();
  5866. system ("rizoma-ventas &");
  5867. return (0);
  5868. }