def add_line(self): single_line_section = QtWidgets.QHBoxLayout() component_field = AutocapField("Componente...") component_field.setFixedWidth(200) component_field.setFocus() component_field.set_completer(source="comps in stock") value_field = StockNumberField("Cantidad...") value_field.setFixedWidth(80) close_button = LineItemCloseButton(holder=self.comps_holder_section) single_line_section.addWidget(component_field) single_line_section.addWidget(value_field) single_line_section.addWidget(close_button) self.comps_holder_section.addLayout(single_line_section)
def add_line_item(self): product_field = AutocapField("Producto...") product_field.setFixedWidth(120) product_field.set_completer(source="recipes") product_field.setFocus() value_field = StockNumberField("Cantidad...") value_field.setFixedWidth(80) close_button = LineItemCloseButton(holder=self.products_holder_section) single_line_section = QtWidgets.QHBoxLayout() single_line_section.addWidget(product_field) single_line_section.addWidget(value_field) single_line_section.addWidget(close_button) self.products_holder_section.addLayout(single_line_section)
def add_recipe_item_line(self): searchbar_recipe_component = AutocapField("Componente...") searchbar_recipe_component.setFixedWidth(130) searchbar_recipe_component.set_completer(source="comps in stock") searchbar_recipe_amount = StockNumberField("Cantidad...") searchbar_recipe_amount.setFixedWidth(85) close_button = QtWidgets.QPushButton("×") close_button.setFixedWidth(20) close_button.clicked.connect(self.remove_recipe_item_via_close_button) recipe_item_line_layout = QtWidgets.QHBoxLayout() recipe_item_line_layout.addWidget(searchbar_recipe_component) recipe_item_line_layout.addWidget(searchbar_recipe_amount) recipe_item_line_layout.addWidget(close_button) self.comps_holder_section.addLayout(recipe_item_line_layout)
class DeleteComponentDialog(QtWidgets.QDialog): def __init__(self, parent=None): super(DeleteComponentDialog, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint) self.setFixedWidth(200) self.comp_being_deleted_display_name = "" title = QtWidgets.QLabel("Borrar componente") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet(generic_title_style) self.search_field = AutocapField("Buscar componente a borrar...") self.search_field.setFocus() self.search_field.set_completer(source="comps in stock") back_button = QtWidgets.QPushButton("« Volver") back_button.setShortcut("Alt+v") execute_button = QtWidgets.QPushButton("Ejecutar »") execute_button.setShortcut("Alt+e") execute_button.setDefault(True) bottom_section = QtWidgets.QHBoxLayout() bottom_section.addWidget(back_button) bottom_section.addWidget(execute_button) layout = QtWidgets.QVBoxLayout() layout.addWidget(title) layout.addWidget(self.search_field) layout.addLayout(bottom_section) self.setLayout(layout) self.search_field.returnPressed.connect(self.delete_component) execute_button.clicked.connect(self.delete_component) back_button.clicked.connect(self.close) def test_if_there_are_unrecognized_components(self): db = db_manager.DB_Manager() existing_comps = db.get_all_display_names_for_components() db.close_connection() if self.search_field.text() not in existing_comps: WarningBox( "Componente extraño", "Componente no reconocido. Cargar el\ncomponente desde el autocompletado.", ).exec_() return True else: return False def delete_component(self): if self.test_if_there_are_unrecognized_components(): return self.comp_being_deleted_display_name = self.search_field.text() main_section_table = self.parent().parent().main_section.table utils.scroll_to_row_in_table( main_section_table, (self.comp_being_deleted_display_name), keep_light_blue_color=True, ) DeletionConfirmationBox(parent=self).exec_()
class EditComponentDialog(QtWidgets.QDialog): def __init__(self, parent=None): super(EditComponentDialog, self).__init__(parent) self.setWindowFlags( QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint ) self.setFixedWidth(200) self.setFixedHeight(250) self.comp_being_edited = "" title = QtWidgets.QLabel("Editar componente") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet(generic_title_style) self.searchbar = AutocapField("Buscar componente a editar...") self.searchbar.set_completer(source="comps in stock") self.comps_table = QtWidgets.QTableWidget() self.comps_table.setColumnCount(1) self.comps_table.setHorizontalHeaderLabels(["Componente"]) self.comps_table.setFocusPolicy(QtCore.Qt.NoFocus) self.comps_table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.comps_table.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) self.comps_table.verticalHeader().setVisible(False) self.comps_table.horizontalHeaderItem(0).setTextAlignment( QtCore.Qt.AlignHCenter ) self.comps_table.horizontalHeader().setSectionResizeMode( 0, QtWidgets.QHeaderView.Stretch ) db = db_manager.DB_Manager() self.existing_comps = db.get_all_display_names_for_components() self.comps_table.setRowCount(len(self.existing_comps)) utils.populate_table_column_with_list_of_strings( table=self.comps_table, col_num=0, input_list=self.existing_comps ) self.comps_table.setSortingEnabled(True) self.comps_table.horizontalHeader().setSortIndicator( 0, QtCore.Qt.AscendingOrder ) self.comps_table.horizontalHeader().setSortIndicatorShown(False) back_button = QtWidgets.QPushButton("« Volver") back_button.setShortcut("Alt+v") layout = QtWidgets.QVBoxLayout() layout.addWidget(title) layout.addWidget(self.searchbar) layout.addWidget(self.comps_table) layout.addWidget(back_button) self.setLayout(layout) self.searchbar.returnPressed.connect(self.on_searchbar_return_pressed) self.comps_table.cellDoubleClicked.connect(self.on_table_item_double_clicked) back_button.clicked.connect(self.close) if not self.existing_comps: InformationBox("Sin componentes", "No hay componentes para editar.").exec_() QtCore.QTimer.singleShot(1, self.close) def on_searchbar_return_pressed(self): if self.searchbar.text() not in self.existing_comps: return utils.scroll_to_row_in_table(self.comps_table, self.searchbar.text()) self.comp_being_edited = self.searchbar.text() EditInputDialog(parent=self).exec_() def on_table_item_double_clicked(self, row): self.comp_being_edited = self.comps_table.item(row, 0).text() EditInputDialog(parent=self).exec_()
class EditRecipeDialog(QtWidgets.QDialog): def __init__(self, parent=None): super(EditRecipeDialog, self).__init__(parent) self.recipe_being_edited_display = "" self.recipe_being_edited_sql = "" self.stored_recipe_contents = {} self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint) self.setFixedWidth(200) self.setFixedHeight(250) title = QtWidgets.QLabel("Editar receta") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet(generic_title_style) self.searchbar = AutocapField("Buscar receta a editar...") self.searchbar.set_completer(source="recipes") self.table = QtWidgets.QTableWidget() self.table.setFocusPolicy(QtCore.Qt.NoFocus) self.table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.table.verticalHeader().setVisible(False) self.table.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) self.table.setColumnCount(1) self.table.setHorizontalHeaderLabels(["Producto"]) self.table.horizontalHeaderItem(0).setTextAlignment( QtCore.Qt.AlignHCenter) self.table.horizontalHeader().setSectionResizeMode( 0, QtWidgets.QHeaderView.Stretch) db = db_manager.DB_Manager() self.all_recipes_display = db.get_all_recipes_as_display() db.close_connection() self.table.setRowCount(len(self.all_recipes_display)) utils.populate_table_column_with_list_of_strings( table=self.table, col_num=0, input_list=self.all_recipes_display) back_button = QtWidgets.QPushButton("« Volver") back_button.setShortcut("Alt+v") layout = QtWidgets.QVBoxLayout() layout.addWidget(title) layout.addWidget(self.searchbar) layout.addWidget(self.table) layout.addWidget(back_button) self.setLayout(layout) back_button.clicked.connect(self.close) self.searchbar.returnPressed.connect(self.on_searchbar_return_pressed) self.table.cellDoubleClicked.connect(self.on_table_item_double_clicked) if not self.all_recipes_display: InformationBox("Sin recetas", "No hay recetas para editar.").exec_() QtCore.QTimer.singleShot(1, self.close) def on_searchbar_return_pressed(self): if self.searchbar.text() not in self.all_recipes_display: return utils.scroll_to_row_in_table(self.table, self.searchbar.text()) self.recipe_being_edited_display = self.searchbar.text() RecipeDetailsDialog(parent=self).exec_() def on_table_item_double_clicked(self, row, col): self.recipe_being_edited_display = self.table.item(row, col).text() RecipeDetailsDialog(parent=self).exec_()
class MainSection(QtWidgets.QWidget): def __init__(self): super(MainSection, self).__init__() self.selected_comp_display = "" self.selected_comp_SQL = "" title = QtWidgets.QLabel("Resumen de componentes") title.setStyleSheet(main_section_title_style) title.setAlignment(QtCore.Qt.AlignCenter) self.searchbar = AutocapField("Buscar componente...") self.searchbar.set_completer(source="comps in stock") sb_shortcut = QtWidgets.QShortcut(QtGui.QKeySequence("Alt+b"), self.searchbar) sb_shortcut.activated.connect(self.searchbar.setFocus) self.update_button = QtWidgets.QPushButton("Actualizado") self.update_button.setShortcut("Alt+a") self.update_button.setFixedWidth(110) self.update_button.setEnabled(False) primary_button = QtWidgets.QToolButton() primary_button.setIcon(qta.icon("mdi.view-list")) primary_button.setText("Cuadro de inventario") primary_button.setShortcut("Alt+p") secondary_button = QtWidgets.QToolButton() secondary_button.setIcon(qta.icon("mdi.file-tree")) secondary_button.setText("Cuadros secundarios") secondary_button.setShortcut("Alt+s") for i in [primary_button, secondary_button]: i.setIconSize(QtCore.QSize(42, 42)) i.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) i.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) i.setPopupMode(QtWidgets.QToolButton.InstantPopup) i.setFixedHeight(70) i.setFixedWidth(126) primary_menu = QtWidgets.QMenu() primary_menu_item_1 = primary_menu.addAction("Resaltar críticos") primary_menu_item_2 = primary_menu.addAction("Resaltar excluidos") primary_menu_item_3 = primary_menu.addAction("Exportar datos") primary_menu.setStyleSheet(main_section_menu_style) primary_button.setMenu(primary_menu) secondary_menu = QtWidgets.QMenu() secondary_menu.setStyleSheet(main_section_menu_style) secondary_menu_item_1 = secondary_menu.addAction("Movimientos") secondary_menu_item_2 = secondary_menu.addAction("Configuraciones") secondary_button.setMenu(secondary_menu) horizontal_section_layout = QtWidgets.QHBoxLayout() horizontal_section_layout.addWidget(self.searchbar) horizontal_section_layout.addWidget(self.update_button) table_layout = QtWidgets.QVBoxLayout() self.table = QtWidgets.QTableWidget() self.table.setStyleSheet(main_section_table_style) self.table.setColumnCount(6) self.table.setFixedHeight(355) self.table.setFocusPolicy(QtCore.Qt.NoFocus) self.table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.table.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) self.table.verticalHeader().setVisible(False) self.main_section_header_labels = [ "Componente", "Total", "Depósito", "Karina", "Brid", "Tercero", ] self.table.setHorizontalHeaderLabels(self.main_section_header_labels) self.table.horizontalHeader().setDefaultSectionSize(70) self.table.horizontalHeader().setSectionResizeMode( 0, QtWidgets.QHeaderView.Stretch) self.table.horizontalHeader().setSectionResizeMode( 1, QtWidgets.QHeaderView.Fixed) self.table.horizontalHeader().setSectionResizeMode( 2, QtWidgets.QHeaderView.Fixed) self.table.horizontalHeader().setSectionResizeMode( 3, QtWidgets.QHeaderView.Fixed) self.table.horizontalHeader().setSectionResizeMode( 4, QtWidgets.QHeaderView.Fixed) self.table.horizontalHeader().setSectionResizeMode( 5, QtWidgets.QHeaderView.Fixed) for i in range(6): self.table.horizontalHeaderItem(i).setTextAlignment( QtCore.Qt.AlignHCenter) table_layout.addWidget(self.table) layout = QtWidgets.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) header_layout = QtWidgets.QHBoxLayout() header_left_layout = QtWidgets.QVBoxLayout() header_right_layout = QtWidgets.QHBoxLayout() header_left_layout.addWidget(title) header_left_layout.addLayout(horizontal_section_layout) header_right_layout.addWidget(primary_button) header_right_layout.addWidget(secondary_button) header_layout.addLayout(header_left_layout) header_layout.addLayout(header_right_layout) layout.addLayout(header_layout) layout.addLayout(table_layout) self.setLayout(layout) db = db_manager.DB_Manager() total_table_count = db.get_total_table_count() stocks_1 = db.get_stocks_for_owner("stock_valdenegro") stocks_2 = db.get_stocks_for_owner("stock_karina") stocks_3 = db.get_stocks_for_owner("stock_brid") stocks_4 = db.get_stocks_for_owner("stock_tercero") self.all_components_display = db.get_all_display_names_for_components() self.stored_criticals = db.get_stored_criticals() self.unused_comps = db.get_components_not_in_use() db.close_connection() settings = QtCore.QSettings("solutronic", "admin_stock") self.excluded_state = settings.value("excluded_checkbox") stocks_g = [] for i in range(total_table_count): result = stocks_1[i] + stocks_2[i] + stocks_3[i] + stocks_4[i] stocks_g.append(result) self.table.setRowCount(total_table_count) stocks_g_display = [ utils.format_number_for_display(i) for i in stocks_g ] stocks_1_display = [ utils.format_number_for_display(i) for i in stocks_1 ] stocks_2_display = [ utils.format_number_for_display(i) for i in stocks_2 ] stocks_3_display = [ utils.format_number_for_display(i) for i in stocks_3 ] stocks_4_display = [ utils.format_number_for_display(i) for i in stocks_4 ] for count, value in enumerate([ self.all_components_display, stocks_g_display, stocks_1_display, stocks_2_display, stocks_3_display, stocks_4_display, ]): utils.populate_table_column_with_list_of_strings(table=self.table, col_num=count, input_list=value) utils.color_criticals_in_orange_in_main_section( self.table, self.stored_criticals) utils.color_zeros_in_grey_in_main_section(self.table, self.stored_criticals) utils.color_excluded_in_yellow_in_main_section(self.table, self.excluded_state, self.unused_comps) self.searchbar.returnPressed.connect(self.get_searched_component) primary_menu_item_1.triggered.connect( lambda: CriticalCompsDialog(self).exec_()) primary_menu_item_2.triggered.connect( lambda: ExcludedCompsDialog(self).exec_()) primary_menu_item_3.triggered.connect(self.export_to_spreadsheet) secondary_menu_item_1.triggered.connect( lambda: MovementsDialog(self).exec_()) secondary_menu_item_2.triggered.connect( lambda: ConfigsDialog(self).exec_()) self.table.horizontalHeader().sortIndicatorChanged.connect( self.sort_components_alphabetically) self.table.cellDoubleClicked.connect(self.open_component_details) def get_searched_component(self): if self.searchbar.text() not in self.all_components_display: return for i in range(self.table.rowCount()): for j in range(self.table.columnCount()): if self.table.item( i, 0).background().color() != QtGui.QColor("orange"): if self.table.item( i, 0).background().color() != QtGui.QColor("yellow"): self.table.item(i, j).setBackground(QtGui.QColor("white")) found_item_list = self.table.findItems(self.searchbar.text(), QtCore.Qt.MatchExactly) found_item = found_item_list[0] self.table.scrollToItem(found_item, QtWidgets.QAbstractItemView.PositionAtTop) utils.give_light_blue_color_to_found_item_row(self.table, found_item) def export_to_spreadsheet(self): from pandas import DataFrame, ExcelWriter from datetime import datetime num_rows = self.table.rowCount() num_cols = self.table.columnCount() df = DataFrame(columns=self.main_section_header_labels, index=range(num_rows)) for i in range(num_rows): for j in range(num_cols): df.iloc[(i, j)] = self.table.item(i, j).text() date = datetime.now().strftime("%d-%m-%Y") filepath_and_name = f"output\\RESUMEN DE STOCK {date}.xlsx" writer = ExcelWriter(filepath_and_name) df.to_excel(writer, "Hoja1", index=False) writer.sheets["Hoja1"].column_dimensions["A"].width = 30 writer.save() os.startfile(filepath_and_name) statusbar = self.parent().parent().statusbar statusbar.show_quick_message("Resumen exportado") def sort_components_alphabetically(self, logical_index): if logical_index == 0: self.table.setSortingEnabled(True) self.table.horizontalHeader().setSortIndicatorShown(False) if logical_index != 0: self.table.setSortingEnabled(False) def open_component_details(self, row, col): if col == 0: self.selected_comp_display = self.table.item(row, col).text() db = db_manager.DB_Manager() self.selected_comp_SQL = db.get_SQL_name_for_component( self.selected_comp_display) db.close_connection() ComponentDetailsDialog(self).exec_()
class DeleteRecipeDialog(QtWidgets.QDialog): def __init__(self, parent=None): super(DeleteRecipeDialog, self).__init__(parent) self.recipe_being_deleted_display = "" self.recipe_being_deleted_sql = "" self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint) self.setFixedWidth(200) self.setFixedHeight(250) title = QtWidgets.QLabel("Borrar receta") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet(generic_title_style) self.searchbar = AutocapField("Buscar receta a borrar...") self.searchbar.set_completer(source="recipes") self.table = QtWidgets.QTableWidget() self.table.setFocusPolicy(QtCore.Qt.NoFocus) self.table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.table.verticalHeader().setVisible(False) self.table.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) self.table.setColumnCount(1) self.table.setHorizontalHeaderLabels(["Producto"]) self.table.horizontalHeaderItem(0).setTextAlignment( QtCore.Qt.AlignHCenter) self.table.horizontalHeader().setSectionResizeMode( 0, QtWidgets.QHeaderView.Stretch) db = db_manager.DB_Manager() self.all_recipes_display = db.get_all_recipes_as_display() db.close_connection() self.table.setRowCount(len(self.all_recipes_display)) utils.populate_table_column_with_list_of_strings( table=self.table, col_num=0, input_list=self.all_recipes_display) back_button = QtWidgets.QPushButton("« Volver") back_button.setShortcut("Alt+v") layout = QtWidgets.QVBoxLayout() layout.addWidget(title) layout.addWidget(self.searchbar) layout.addWidget(self.table) layout.addWidget(back_button) self.setLayout(layout) back_button.clicked.connect(self.close) self.searchbar.returnPressed.connect(self.on_searchbar_return_pressed) self.table.cellDoubleClicked.connect(self.on_table_item_double_clicked) if not self.all_recipes_display: InformationBox("Sin recetas", "No hay recetas para borrar.").exec_() QtCore.QTimer.singleShot(1, self.close) def on_searchbar_return_pressed(self): if self.searchbar.text() not in self.all_recipes_display: return utils.scroll_to_row_in_table(self.table, self.searchbar.text()) self.recipe_being_deleted_display = self.searchbar.text() self.delete_recipe_from_db() def on_table_item_double_clicked(self, row, col): self.recipe_being_deleted_display = self.table.item(row, col).text() self.delete_recipe_from_db() def delete_recipe_from_db(self): self.recipe_being_deleted_sql = utils.format_display_name_into_sql_name( self.recipe_being_deleted_display) box = QuestionBox( "Confirmación", f"¿Borrar receta {self.recipe_being_deleted_display}?") box.exec_() if box.clickedButton() == box.button(QtWidgets.QMessageBox.No): pass elif box.clickedButton() == box.button(QtWidgets.QMessageBox.Yes): db = db_manager.DB_Manager() db.delete_recipe(self.recipe_being_deleted_sql) db.log_new_config_record(config="Borrado de receta", details=self.recipe_being_deleted_display) db.close_connection() admin_window = self.parent().parent().parent() admin_window.statusbar.show_quick_message( "Receta borrada: " + self.recipe_being_deleted_display) admin_window.start_screen.rebuild_main_section() self.close()
class MovementsDialog(QtWidgets.QDialog): def __init__(self, parent=None): super(MovementsDialog, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setFixedWidth(800) self.setFixedHeight(403) self.df = "" self.title = QtWidgets.QLabel("Historial de movimientos") self.title.setStyleSheet(movements_dialog_title_style) self.title.setAlignment(QtCore.Qt.AlignCenter) self.groupbox = QtWidgets.QGroupBox("Filtros") self.groupbox.setStyleSheet(generic_groupbox_normal_style) self.groupbox.setMinimumWidth(400) self.date_button = QtWidgets.QPushButton("Período") self.date_button.setMaximumHeight(22) self.date_button.setFocusPolicy(QtCore.Qt.NoFocus) self.mov_combobox = QtWidgets.QComboBox() self.mov_combobox.addItem("Movimiento") self.mov_combobox.addItem("Ingreso") self.mov_combobox.addItem("Egreso") self.mov_combobox.setFixedWidth(85) self.comp_field = AutocapField("Componente...") self.comp_field.setFixedWidth(300) self.comp_field.set_completer(source="comps in movements") self.comp_field.setFocus() self.dest_combobox = QtWidgets.QComboBox() self.dest_combobox.addItem("Destino") destinations = ["Depósito", "Karina", "Brid", "Tercero", "Uso interno"] for destination in destinations: self.dest_combobox.addItem(destination) self.user_combobox = QtWidgets.QComboBox() self.user_combobox.addItem("Usuario") self.db = db_manager.DB_Manager() users = self.db.get_all_admin_users() for user in users: self.user_combobox.addItem(user) self.user_combobox.setFixedWidth(100) filters_layout = QtWidgets.QHBoxLayout() filters_layout.addWidget(self.date_button) filters_layout.addWidget(self.mov_combobox) filters_layout.addWidget(self.comp_field) filters_layout.addWidget(self.dest_combobox) filters_layout.addWidget(self.user_combobox) groupbox_inner_section = QtWidgets.QVBoxLayout() groupbox_inner_section.addLayout(filters_layout) self.groupbox.setLayout(groupbox_inner_section) groupbox_section = QtWidgets.QHBoxLayout() groupbox_section.addStretch() groupbox_section.addWidget(self.groupbox) groupbox_section.addStretch() back_button = QtWidgets.QPushButton("« Volver") back_button.setShortcut("Alt+v") back_button.setFocusPolicy(QtCore.Qt.NoFocus) self.delete_button = QtWidgets.QPushButton("× Borrar historial") self.delete_button.setShortcut("Alt+b") self.delete_button.setFocusPolicy(QtCore.Qt.NoFocus) self.export_button = QtWidgets.QPushButton("Exportar historial »") self.export_button.setShortcut("Alt+x") self.export_button.setFocusPolicy(QtCore.Qt.NoFocus) bottom_section = QtWidgets.QHBoxLayout() bottom_section.addWidget(back_button) bottom_section.addWidget(self.delete_button) bottom_section.addWidget(self.export_button) table_layout = QtWidgets.QVBoxLayout() self.table_view = QtWidgets.QTableView() self.table_view.verticalHeader().setVisible(False) table_layout.addWidget(self.table_view) layout = QtWidgets.QVBoxLayout() layout.addWidget(self.title) layout.addLayout(groupbox_section) layout.addLayout(table_layout) layout.addLayout(bottom_section) self.setLayout(layout) self.build_table_view() back_button.clicked.connect(self.close) self.delete_button.clicked.connect(self.delete_movements) self.export_button.clicked.connect(self.export_to_spreadsheet) self.date_button.clicked.connect(self.create_date_selection_subdialog) self.comp_field.returnPressed.connect(self.on_comp_field_return_press) self.mov_combobox.currentIndexChanged.connect(self.on_combobox_change) self.dest_combobox.currentIndexChanged.connect(self.on_combobox_change) self.user_combobox.currentIndexChanged.connect(self.on_combobox_change) def create_date_selection_subdialog(self): self.date_selection_subdialog = DateSelectionSubdialog(self) self.date_selection_subdialog.exec_() def build_table_view(self): self.df = self.db.get_movements_as_dataframe() self.db.close_connection() widgets = [ self.delete_button, self.export_button, self.date_button, self.mov_combobox, self.dest_combobox, self.user_combobox, self.comp_field, ] if self.df.empty: for i in widgets: i.setDisabled(True) return row_count = len(self.df.index) col_count = len(self.df.columns) self.model = QtGui.QStandardItemModel(row_count, col_count) self.model.setHorizontalHeaderLabels(self.df.columns) self.table_view.setModel(self.model) for count, df_col_name in enumerate(self.df): utils.populate_model_column_with_list_of_items( model=self.model, col_num=count, input_list=self.df[df_col_name]) text_and_color = { "Ingreso": QtGui.QColor("#a3be8c"), "Egreso": QtGui.QColor("#ff91a4"), } for text, color in text_and_color.items(): for x in range(self.model.rowCount()): for y in range(self.model.columnCount()): if self.model.item(x, 2).text() == text: self.model.item(x, y).setBackground(color) self.table_view.setColumnWidth(0, 95) self.table_view.setColumnWidth(1, 65) self.table_view.horizontalHeader().setSectionResizeMode( 3, QtWidgets.QHeaderView.Stretch) self.table_view.setColumnWidth(2, 90) self.table_view.setColumnWidth(4, 80) self.table_view.setColumnWidth(5, 120) self.table_view.setColumnWidth(6, 100) self.table_view.setSelectionMode( QtWidgets.QAbstractItemView.NoSelection) self.table_view.setEditTriggers( QtWidgets.QAbstractItemView.NoEditTriggers) self.table_view.setFocusPolicy(QtCore.Qt.NoFocus) self.table_view.setStyleSheet(movements_dialog_table_view_style) def clear_all_filters(self): self.date_button.setText("Período") self.comp_field.clear() self.mov_combobox.setCurrentIndex(0) self.dest_combobox.setCurrentIndex(0) self.user_combobox.setCurrentIndex(0) self.table_view.setModel(self.model) self.groupbox.setTitle("Filtros") self.groupbox.setStyleSheet(generic_groupbox_normal_style) def clear_all_filters_except(self, chosen_filter): comboboxes = [ self.mov_combobox, self.dest_combobox, self.user_combobox ] if isinstance(chosen_filter, QtWidgets.QComboBox): self.date_button.setText("Período") self.comp_field.clear() for i in comboboxes: if i != chosen_filter: i.setCurrentIndex(0) elif isinstance(chosen_filter, QtWidgets.QLineEdit): self.date_button.setText("Período") for i in comboboxes: i.setCurrentIndex(0) elif isinstance(chosen_filter, QtWidgets.QPushButton): self.comp_field.clear() for i in comboboxes: i.setCurrentIndex(0) def apply_filter_based_on_item(self, chosen_filter, chosen_item): filter_proxy_model = self.get_filter_proxy_model(chosen_filter) filter_proxy_model.setSourceModel(self.model) filter_proxy_model.setFilterFixedString(chosen_item) self.table_view.setModel(filter_proxy_model) self.groupbox.setTitle("Filtro activado") self.groupbox.setStyleSheet( movements_dialog_groupbox_filter_selected_style) def get_filter_proxy_model(self, chosen_filter): filter_proxy_model = QtCore.QSortFilterProxyModel() if chosen_filter in ("Movimiento", "Destino", "Usuario"): filter_and_column = {"Movimiento": 2, "Destino": 5, "Usuario": 6} filter_proxy_model.setFilterKeyColumn( filter_and_column[chosen_filter]) elif chosen_filter == "Componente": filter_proxy_model.setFilterRegExp( QtCore.QRegExp(self.comp_field.text())) filter_proxy_model.setFilterKeyColumn(3) return filter_proxy_model def on_combobox_change(self): combobox = self.sender() chosen_filter = combobox.itemText(0) chosen_item = combobox.currentText() self.clear_all_filters_except(combobox) if chosen_item in ("Movimiento", "Destino", "Usuario"): self.clear_all_filters() else: self.apply_filter_based_on_item(chosen_filter, chosen_item) def on_comp_field_return_press(self): user_input = self.comp_field.text() self.clear_all_filters_except(self.comp_field) if not user_input: self.clear_all_filters() elif user_input: self.apply_filter_based_on_item("Componente", user_input) def on_date_selected(self): selected_date = self.date_selection_subdialog.selected_date self.date_button.setText(selected_date) self.clear_all_filters_except(self.date_button) self.apply_filter_based_on_item("Fecha", selected_date) def delete_movements(self): box = QuestionBox("Confirmación", "¿Borrar historial de movimientos?") box.exec_() if box.clickedButton() == box.button(QtWidgets.QMessageBox.Yes): db = db_manager.DB_Manager() db.delete_all_movements() db.close_connection() self.close() statusbar = self.parent().parent().parent().parent().statusbar statusbar.show_quick_message("Historial de movimientos borrado") elif box.clickedButton() == box.button(QtWidgets.QMessageBox.No): pass def export_to_spreadsheet(self): self.export_button.setText("Esperar...") current_date = datetime.now().strftime("%d-%m-%Y") filepath_and_name = f"output\\Historial de movimientos {current_date}.xlsx" writer = ExcelWriter(filepath_and_name) self.df.to_excel(writer, "Hoja1", index=False) writer.sheets["Hoja1"].column_dimensions["A"].width = 13 writer.sheets["Hoja1"].column_dimensions["B"].width = 8 writer.sheets["Hoja1"].column_dimensions["C"].width = 15 writer.sheets["Hoja1"].column_dimensions["D"].width = 30 writer.sheets["Hoja1"].column_dimensions["E"].width = 10 writer.sheets["Hoja1"].column_dimensions["F"].width = 15 writer.sheets["Hoja1"].column_dimensions["G"].width = 15 writer.save() os.startfile(filepath_and_name) self.export_button.setText("Exportar historial »") self.close() statusbar = self.parent().parent().parent().parent().statusbar statusbar.show_quick_message("Historial de movimientos exportado")