PageRenderTime 60ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/src/ventas.c

#
C | 7178 lines | 4781 code | 1293 blank | 1104 comment | 632 complexity | 0fe42238b99186b58a80fbcbc7c58742 MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  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

Large files files are truncated, but you can click here to view the full file