def __init__(self, main): super(ProveedoresFactory, self).__init__() self.main = main builder = gtk.Builder() builder.add_from_file("pro_frame.glade") self.content = builder.get_object("vbox_content") builder.connect_signals(self) self.content.reparent(self) self.content.show() self.form_builder = FormBuilder(builder, 'Proveedor')
class FiltroFecha: def __init__(self, on_aceptar_handler): self.on_aceptar_handler = on_aceptar_handler builder = gtk.Builder() builder.add_from_file('filtro_fecha_frame.glade') builder.connect_signals(self) self.form_builder = FormBuilder(builder, 'Venta') start_date = datetime.today() - relativedelta(days=15) end_date = datetime.today() self.form_builder.load_widget_value('fecha_inicio', [start_date.year, start_date.month - 1, start_date.day]) self.form_builder.load_widget_value('fecha_fin', [end_date.year, end_date.month - 1, end_date.day]) self.window = builder.get_object('fecha_filtro_window') self.window.show() def on_aceptar_btn_clicked(self, widget): self.window.destroy() self.on_aceptar_handler(self.form_builder.get_widget_value('fecha_inicio'), self.form_builder.get_widget_value('fecha_fin')) def on_cancelar_btn_clicked(self, widget): self.window.destroy()
def __init__(self, main): super(VentasFactory, self).__init__() self.main = main self.builder = gtk.Builder() self.builder.add_from_file("ventas_frame.glade") self.builder.connect_signals(self) content = self.builder.get_object("vbox_content") content.reparent(self) content.show() self.form_builder = FormBuilder(self.builder, 'Producto') self.producto_model = self.form_builder.get_model() self.venta_model = DataModel('Venta') self.venta_detalle_model = DataModel('VentaDetalle') self.ventas_grid = self.builder.get_object('ventas_grid') self._load_ventas_grid() self.form_builder.load_widget_value('fecha_hora_label', datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")) self.idevent = gobject.timeout_add(1000, self._update_fecha_hora)
class ProveedoresFactory(gtk.Frame): def __init__(self, main): super(ProveedoresFactory, self).__init__() self.main = main builder = gtk.Builder() builder.add_from_file("pro_frame.glade") self.content = builder.get_object("vbox_content") builder.connect_signals(self) self.content.reparent(self) self.content.show() self.form_builder = FormBuilder(builder, 'Proveedor') def get_content(self): return self.content def on_nuevo_button_clicked(self, widget): self.form_builder.clear_form() def on_guardar_button_clicked(self, widget): self.form_builder.save_entity() def on_eliminar_button_clicked(self, widget): self.form_builder.delete_entity() def on_cancelar_button_clicked(self, widget): page = self.parent.get_current_page() self.parent.remove_page(page) del self.main.pages[page] def _load_entity_from_search(self, value): self.form_builder.get_entity(int(value)) def on_buscar_button_clicked(self, widget): busqueda = BusquedaWindow('Proveedor', self._load_entity_from_search, search_fields={'id': 'match', 'nombre': 'like'})
class ProductosFactory(gtk.Frame): def __init__(self, main): super(ProductosFactory, self).__init__() self.main = main builder = gtk.Builder() builder.add_from_file("prod_frame.glade") self.content = builder.get_object("vbox_content") self.proveedor = builder.get_object("proveedor") builder.connect_signals(self) self.content.reparent(self) self.content.show() self.form_builder = FormBuilder(builder, 'Producto') self._load_proveedor_combobox() def _load_proveedor_combobox(self): model = DataModel('Proveedor') proveedores = model.get_records() combo_model = gtk.ListStore(int, str) for row in proveedores: combo_model.append([int(row['id']), row['nombre']]) self.proveedor.set_model(combo_model) self.proveedor.show() def get_content(self): return self.content def on_nuevo_button_clicked(self, widget): self.form_builder.clear_form() def on_guardar_button_clicked(self, widget): error = '' try: precio_compra = float(self.form_builder.get_widget_value('precio_compra')) except: error = 'El precio de compra debe ser un valor unicamente numerico' try: precio_venta = float(self.form_builder.get_widget_value('precio_venta')) except: error = 'El precio de venta debe ser un valor unicamente numerico' try: existencia = int(self.form_builder.get_widget_value('existencia')) except: error = 'La existencia debe ser un valor unicamente numerico' if error == '': self.form_builder.save_entity(upsert=True, custom_id=True) else: self._show_error_message(error) def on_eliminar_button_clicked(self, widget): self.form_builder.delete_entity() def on_cancelar_button_clicked(self, widget): page = self.parent.get_current_page() self.parent.remove_page(page) del self.main.pages[page] def _load_entity_from_search(self, value): self.form_builder.get_entity(value) def on_buscar_button_clicked(self, widget): busqueda = BusquedaWindow('Producto', self._load_entity_from_search, search_fields={'id': 'match', 'nombre': 'like'}, display_fields = ['id', 'nombre', 'precio_compra', 'precio_venta', 'existencia']) def _show_error_message(self, message): dialog = gtk.MessageDialog(self.parent.parent.parent, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, message) dialog.run() dialog.destroy()
class VentasFactory(gtk.Frame): __id_venta = 0 def __init__(self, main): super(VentasFactory, self).__init__() self.main = main self.builder = gtk.Builder() self.builder.add_from_file("ventas_frame.glade") self.builder.connect_signals(self) content = self.builder.get_object("vbox_content") content.reparent(self) content.show() self.form_builder = FormBuilder(self.builder, 'Producto') self.producto_model = self.form_builder.get_model() self.venta_model = DataModel('Venta') self.venta_detalle_model = DataModel('VentaDetalle') self.ventas_grid = self.builder.get_object('ventas_grid') self._load_ventas_grid() self.form_builder.load_widget_value('fecha_hora_label', datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")) self.idevent = gobject.timeout_add(1000, self._update_fecha_hora) def on_buscar_producto_button_clicked(self, widget): if self.__id_venta != 0: self._show_error_message('Esta visualizando el detalle de una venta realizada, de click en el boton nuevo para realizar una nueva venta') return busqueda = BusquedaWindow('Producto', self._load_producto, search_fields={'id': 'match', 'nombre': 'like'}, display_fields=['id', 'nombre', 'precio_venta', 'existencia']) def on_buscar_button_clicked(self, widget): busqueda = BusquedaWindow('Venta', self._load_venta, search_fields={'id': 'match', 'fecha_sistema': 'match'}, display_fields=['id', 'fecha_sistema', 'sub_total', 'impuesto', 'total']) def on_agregar_button_clicked(self, widget): if self.__id_venta != 0: self._show_error_message('Esta visualizando el detalle de una venta realizada, de click en el boton nuevo para realizar una nueva venta') return id_producto = self.form_builder.get_widget_value('id_producto') if id_producto == '' or id_producto == '0': self._show_error_message('Escriba un código de producto valido') return nombre_producto = self.form_builder.get_widget_value('nombre_producto') if nombre_producto.strip() == '': self._show_error_message('Escriba una descripción del producto') return precio_producto = self.form_builder.get_widget_value('precio_producto') try: precio_producto = Decimal(precio_producto) if precio_producto < 0: raise NameError('Precio no valido') except: self._show_error_message('Escriba un precio valido') return cantidad_producto = self.form_builder.get_widget_value('cantidad_producto') try: cantidad_producto = int(cantidad_producto) if cantidad_producto == 0: raise NameError('Cantidad no valida') except: self._show_error_message('Escriba una cantidad valida') return append = True producto = self.producto_model.get_record(id_producto) if producto: if producto['existencia'] < cantidad_producto: self._show_error_message('No existe la cantidad necesaria del producto en inventario') return for row in self.ventas_grid_model: if row[0] == id_producto: row[2] = int(row[2]) + cantidad_producto row[4] = str(round(int(row[2]) * Decimal(row[3]), 2)) append = False break if append: self.ventas_grid_model.append([str(id_producto), nombre_producto, str(cantidad_producto), str(round(precio_producto, 2)), str(round(cantidad_producto * precio_producto, 2))]) self._clear_producto(True) self._ensure_ventas_grid() self._calcular_totales() gobject.source_remove(self.idevent) else: self._show_error_message('El codigo de producto no existe') def on_eliminar_butto_clicked(self, widget): if self.__id_venta != 0: self._show_error_message('Esta visualizando el detalle de una venta realizada, de click en el boton nuevo para realizar una nueva venta') return selection = self.ventas_grid.get_selection() model, treeiter = selection.get_selection_selected() if treeiter: del model[treeiter] self._ensure_ventas_grid() self._calcular_totales() def on_iva_check_toggled(self, widget): self._calcular_totales() def _load_producto(self, value): self.form_builder.load_widget_value('id_producto', value) def id_producto_key_release_event_cb(self, widget, ev, data=None): if ev.keyval == 65293: producto_id = widget.get_text() producto = self.producto_model.get_record(producto_id) self._clear_producto() if producto: self._load_producto_information(producto) def on_nuevo_button_clicked(self, widget): self.__id_venta = 0 self._clear_producto(True) self._clear_venta() self.ventas_grid_model.clear() self._ensure_ventas_grid() self._update_fecha_hora() def on_guardar_button_clicked(self, widget, upsert=False): total = self.form_builder.get_widget_value('total_label').replace(',', '').strip() cambio = 0 pago_recibido = self.form_builder.get_widget_value('pago_recibido').replace(',', '').strip() try: pago_recibido = float(pago_recibido) total_numero = float(total) if pago_recibido <= 0 or pago_recibido < total_numero: raise NameError('Cantidad no valida') else: cambio = pago_recibido - total_numero except: self._show_error_message('La cantidad recibida de pago no es valida') return if self.__id_venta == 0: if self._show_save_continue() != -9: fecha_hora = datetime.datetime.now().strftime("%Y%m%d%H%M%S") fecha_sistema = datetime.datetime.now().strftime("%Y/%m/%d") sub_total = self.form_builder.get_widget_value('subtotal_label').replace(',', '') impuesto = self.form_builder.get_widget_value('iva_label').replace(',', '') id_venta = self.venta_model.create_record({'fecha_hora': fecha_hora, 'sub_total': sub_total, 'impuesto': impuesto, 'total': total, 'fecha_sistema': fecha_sistema, 'pago_recibido': str(pago_recibido).strip(), 'cambio': str(cambio).strip()}) if id_venta: for row in self.ventas_grid_model: producto = self.producto_model.get_record(row[0]) if producto: self.venta_detalle_model.create_record({'venta_id': str(id_venta), 'producto_id': row[0].strip(), 'producto_precio': row[3].strip(), 'producto_cantidad': row[2].strip(), 'subtotal': row[4].strip(), 'nombre': row[1].strip()}) self.producto_model.update_record({ 'existencia': str(self.normalizar_existencia(producto['existencia']) - int(row[2].strip()))}, row[0].strip()) self._show_error_message('El cambio es de %s' % '{:20,.2f}'.format(float(cambio))) if not upsert: self._clear_producto(True) self._clear_venta() self.ventas_grid_model.clear() self._ensure_ventas_grid() self.idevent = gobject.timeout_add(1000, self._update_fecha_hora) else: return id_venta else: return 0 else: self._show_error_message('Esta visualizando el detalle de una venta realizada, de click en el boton nuevo para realizar una nueva venta') def on_cancelar_button_clicked(self, widget): page = self.parent.get_current_page() self.parent.remove_page(page) del self.main.pages[page] def on_imprimir_ticket_button_clicked(self, widget): if self.__id_venta == 0: self.__id_venta = self.on_guardar_button_clicked(widget, True) ticket = Ticket(self.__id_venta) if not ticket.imprimir(): self._show_error_message('No se pudo imprimir ticket, asegurese de que la venta exista') def _calcular_totales(self): subtotal = 0.00 impuesto = 0.00 total = 0.00 for row in self.ventas_grid_model: precio = Decimal(row[3]) * int(row[2]) subtotal += round(precio, 2) if self.form_builder.get_widget_value('iva_check'): impuesto = round(subtotal * 0.16, 2) self.form_builder.load_widget_value('iva_label', '{:20,.2f}'.format(impuesto)) else: self.form_builder.load_widget_value('iva_label', '0.00') total = round(subtotal + impuesto, 2) self.form_builder.load_widget_value('subtotal_label', '{:20,.2f}'.format(subtotal)) self.form_builder.load_widget_value('total_label', '{:20,.2f}'.format(total)) def _load_ventas_grid(self): self.ventas_grid_model = gtk.ListStore(str, str, str, str, str) count = 0 columns = ['Id Producto', 'Producto', 'Cantidad', 'Precio', 'Subtotal'] sizes = [50, 200, 60, 100, 100] for column in columns: render = gtk.CellRendererText() column_instance = gtk.TreeViewColumn(column, render, text=count) column_instance.set_min_width(sizes[count]) self.ventas_grid.append_column(column_instance) count += 1 self._ensure_ventas_grid() def _ensure_ventas_grid(self): self.ventas_grid.set_model(self.ventas_grid_model) self.ventas_grid.show() def _load_producto_information(self, row): self.form_builder.load_widget_value('nombre_producto', row['nombre']) self.form_builder.load_widget_value('precio_producto', row['precio_venta']) self.form_builder.load_widget_value('cantidad_producto', '0') self.builder.get_object('cantidad_producto').grab_focus() def _clear_producto(self, clear_id=False): if clear_id: self.form_builder.load_widget_value('id_producto', '') self.form_builder.load_widget_value('nombre_producto', '') self.form_builder.load_widget_value('precio_producto', '0.00') self.form_builder.load_widget_value('cantidad_producto', '0') def _clear_venta(self): self.form_builder.load_widget_value('subtotal_label', '0.00') self.form_builder.load_widget_value('total_label', '0.00') self.form_builder.load_widget_value('iva_label', '0.00') self.form_builder.load_widget_value('pago_recibido', '0.00') def _show_error_message(self, message): dialog = gtk.MessageDialog(self.parent.parent.parent, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, message) dialog.run() dialog.destroy() def _show_save_continue(self): dialog = gtk.MessageDialog(self.parent.parent.parent, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, '¿Desea guardad la venta actual?') response = dialog.run() dialog.destroy() return response def _update_fecha_hora(self): self.form_builder.load_widget_value('fecha_hora_label', datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")) self.idevent = gobject.timeout_add(1000, self._update_fecha_hora) def _load_venta(self, value): venta = self.venta_model.get_record(int(value)) if venta: self._clear_producto(True) self._clear_venta() self.ventas_grid_model.clear() self._ensure_ventas_grid() self.__id_venta = venta['id'] self.form_builder.load_widget_value('subtotal_label', '{:20,.2f}'.format(float(venta['sub_total']))) self.form_builder.load_widget_value('iva_label', '{:20,.2f}'.format(float(venta['impuesto']))) self.form_builder.load_widget_value('total_label', '{:20,.2f}'.format(float(venta['total']))) self.form_builder.load_widget_value('pago_recibido', '{:20,.2f}'.format(float(venta['pago_recibido']))) gobject.source_remove(self.idevent) self.form_builder.load_widget_value('fecha_hora_label', self._parse_fecha(str(venta['fecha_hora']))) items = self.venta_detalle_model.get_records(venta_id=venta['id']) if len(items) > 0: for item in items: self.ventas_grid_model.append([str(item['id']), item['nombre'].strip(), str(item['producto_cantidad']).strip(), str(round(item['producto_precio'], 2)).strip(), str(round(item['producto_cantidad'] * item['producto_precio'], 2)).strip()]) else: self._show_error_message('La venta seleccionada no existe') def _parse_fecha(self, fecha): year = fecha[:4] month = fecha[4:6] day = fecha[6:8] hour = fecha[8:10] minutes = fecha[10:12] seconds = fecha[12:14] return "%s/%s/%s %s:%s:%s" % (year, month, day, hour, minutes, seconds) def normalizar_existencia(self, existencia): try: existencia = int(existencia) except: if isinstance(existencia, str): number = re.match(r"\d", existencia) if number: existencia = number.group(0) else: existencia = 0 else: existencia = 0 return existencia