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 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 __init__(self, parent=None): super(CreateComponentDialog, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint) title = QtWidgets.QLabel("Crear componente") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet(generic_title_style) self.compname_field = AutocapField("Componente a crear...") self.compname_field.setFixedWidth(150) self.compname_field.setFocus() self.initstock_field = StockNumberField("Stock inicial...") self.initstock_field.setFixedWidth(80) back_button = QtWidgets.QPushButton("« Volver") back_button.setShortcut("Alt+v") self.execute_button = QtWidgets.QPushButton("Ejecutar »") self.execute_button.setDefault(True) line_edits_layout = QtWidgets.QHBoxLayout() line_edits_layout.addWidget(self.compname_field) line_edits_layout.addWidget(self.initstock_field) bottom_section = QtWidgets.QHBoxLayout() bottom_section.addWidget(back_button) bottom_section.addWidget(self.execute_button) layout = QtWidgets.QVBoxLayout() layout.addWidget(title) layout.addLayout(line_edits_layout) layout.addLayout(bottom_section) self.setLayout(layout) back_button.clicked.connect(self.close) self.execute_button.clicked.connect(self.create_component)
def add_critical_holder(self): single_holder_layout = QtWidgets.QHBoxLayout() component_field = AutocapField("Componente...") component_field.setFixedWidth(175) component_field.setFocus() single_holder_layout.addWidget(component_field) value_field = StockNumberField("Valor...") value_field.setFixedWidth(65) single_holder_layout.addWidget(value_field) close_button = QtWidgets.QPushButton("×") close_button.setFixedWidth(20) single_holder_layout.addWidget(close_button) close_button.clicked.connect(self.remove_critical_holder) self.criticals_holder_layout.addLayout(single_holder_layout) for l in self.criticals_holder_layout.children(): each_component_field = l.itemAt(0).widget() each_component_field.set_completer(source="comps in stock")
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 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 __init__(self, parent=None): super(EditInputDialog, self).__init__(parent) self.setWindowTitle("Nuevo nombre") self.setWindowFlags( QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint ) self.comp_being_edited = self.parent().comp_being_edited title = QtWidgets.QLabel("Editar componente:") title.setAlignment(QtCore.Qt.AlignCenter) subtitle = QtWidgets.QLabel(self.comp_being_edited) subtitle.setAlignment(QtCore.Qt.AlignCenter) subtitle.setStyleSheet(edit_input_dialog_subtitle_style) self.new_name_field = AutocapField("Nuevo nombre...") bottom_section = QtWidgets.QHBoxLayout() 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.addWidget(back_button) bottom_section.addWidget(execute_button) layout = QtWidgets.QVBoxLayout() layout.addWidget(title) layout.addWidget(subtitle) layout.addWidget(self.new_name_field) layout.addLayout(bottom_section) self.layout().addLayout(layout, 0, 0, 0, 0, QtCore.Qt.AlignCenter) self.setStyleSheet(generic_messagebox_style) back_button.clicked.connect(self.close) execute_button.clicked.connect(lambda: EditConfirmationBox(self).exec_())
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_()
def __init__(self, parent=None): super(CreateRecipeDialog, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint) title = QtWidgets.QLabel("Crear receta") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet(generic_title_style) self.product_field = AutocapField("Producto a crear...") self.product_field.setFixedWidth(200) self.model_field = AutocapField("Modelo de producto...") self.model_field.setFixedWidth(200) fields_layout = QtWidgets.QHBoxLayout() fields_layout.addWidget(self.product_field) fields_layout.addWidget(self.model_field) groupbox = QtWidgets.QGroupBox("Componentes y cantidades") groupbox.setStyleSheet(generic_groupbox_normal_style) groupbox.setMinimumWidth(333) add_component_button = QtWidgets.QPushButton("+ Agregar componente") add_component_button.setShortcut("Alt+a") self.comps_holder_section = QtWidgets.QVBoxLayout() groupbox_inner_section = QtWidgets.QVBoxLayout() groupbox_inner_section_1 = QtWidgets.QHBoxLayout() groupbox_inner_section_1.addWidget(add_component_button) groupbox_inner_section_2 = QtWidgets.QHBoxLayout() groupbox_inner_section_2.addLayout(self.comps_holder_section) groupbox_inner_section.addLayout(groupbox_inner_section_1) groupbox_inner_section.addLayout(groupbox_inner_section_2) groupbox.setLayout(groupbox_inner_section) groupbox_section = QtWidgets.QHBoxLayout() groupbox_section.addStretch() groupbox_section.addWidget(groupbox) groupbox_section.addStretch() back_button = QtWidgets.QPushButton("« Volver") back_button.setShortcut("Alt+v") back_button.setFixedWidth(200) execute_button = QtWidgets.QPushButton("Ejecutar »") execute_button.setShortcut("Alt+e") execute_button.setFixedWidth(200) bottom_layout = QtWidgets.QHBoxLayout() bottom_layout.addWidget(back_button) bottom_layout.addWidget(execute_button) layout = QtWidgets.QVBoxLayout() layout.addWidget(title) layout.addLayout(fields_layout) layout.addLayout(groupbox_section) layout.addStretch(1) layout.addLayout(bottom_layout) layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize) self.setLayout(layout) back_button.clicked.connect(self.close) add_component_button.clicked.connect(self.add_line) execute_button.clicked.connect(self.create_recipe)
class CreateRecipeDialog(QtWidgets.QDialog): def __init__(self, parent=None): super(CreateRecipeDialog, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint) title = QtWidgets.QLabel("Crear receta") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet(generic_title_style) self.product_field = AutocapField("Producto a crear...") self.product_field.setFixedWidth(200) self.model_field = AutocapField("Modelo de producto...") self.model_field.setFixedWidth(200) fields_layout = QtWidgets.QHBoxLayout() fields_layout.addWidget(self.product_field) fields_layout.addWidget(self.model_field) groupbox = QtWidgets.QGroupBox("Componentes y cantidades") groupbox.setStyleSheet(generic_groupbox_normal_style) groupbox.setMinimumWidth(333) add_component_button = QtWidgets.QPushButton("+ Agregar componente") add_component_button.setShortcut("Alt+a") self.comps_holder_section = QtWidgets.QVBoxLayout() groupbox_inner_section = QtWidgets.QVBoxLayout() groupbox_inner_section_1 = QtWidgets.QHBoxLayout() groupbox_inner_section_1.addWidget(add_component_button) groupbox_inner_section_2 = QtWidgets.QHBoxLayout() groupbox_inner_section_2.addLayout(self.comps_holder_section) groupbox_inner_section.addLayout(groupbox_inner_section_1) groupbox_inner_section.addLayout(groupbox_inner_section_2) groupbox.setLayout(groupbox_inner_section) groupbox_section = QtWidgets.QHBoxLayout() groupbox_section.addStretch() groupbox_section.addWidget(groupbox) groupbox_section.addStretch() back_button = QtWidgets.QPushButton("« Volver") back_button.setShortcut("Alt+v") back_button.setFixedWidth(200) execute_button = QtWidgets.QPushButton("Ejecutar »") execute_button.setShortcut("Alt+e") execute_button.setFixedWidth(200) bottom_layout = QtWidgets.QHBoxLayout() bottom_layout.addWidget(back_button) bottom_layout.addWidget(execute_button) layout = QtWidgets.QVBoxLayout() layout.addWidget(title) layout.addLayout(fields_layout) layout.addLayout(groupbox_section) layout.addStretch(1) layout.addLayout(bottom_layout) layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize) self.setLayout(layout) back_button.clicked.connect(self.close) add_component_button.clicked.connect(self.add_line) execute_button.clicked.connect(self.create_recipe) 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 create_recipe(self): for i in [ self.test_if_product_or_model_fields_are_empty, self.test_if_there_are_recipe_data, self.test_if_there_are_duplicates, self.test_if_there_are_unrecognized_components, ]: if i(): return self.insert_new_recipe_into_db() def test_if_product_or_model_fields_are_empty(self): if self.product_field.text() == "": WarningBox("Producto faltante", "Ingresar producto\nantes de ejecutar.").exec_() self.product_field.setFocus() return True elif self.model_field.text() == "": WarningBox("Modelo faltante", "Ingresar modelo\nantes de ejecutar.").exec_() self.model_field.setFocus() return True else: return False def test_if_there_are_recipe_data(self): contents = utils.get_line_items_contents(self.comps_holder_section) empty_strings_exist = tests.test_if_empty_string_in_line_items_contents( contents) if self.comps_holder_section.children() and empty_strings_exist: WarningBox( "Sin componentes", "Completar o borrar campos\nvacíos antes de ejecutar.", ).exec_() return True else: return False def test_if_there_are_duplicates(self): contents = utils.get_line_items_contents(self.comps_holder_section) if tests.test_if_duplicated_first_value_in_line_items_contents( contents): WarningBox("Componentes duplicados", "Borrar uno de los componentes duplicados.").exec_() return True else: return False def test_if_there_are_unrecognized_components(self): contents = utils.get_line_items_contents(self.comps_holder_section) incoming_components = contents[0::2] db = db_manager.DB_Manager() existing_comps = db.get_all_display_names_for_components() db.close_connection() if not set(incoming_components).issubset(existing_comps): WarningBox( "Componente extraño", "Componente no reconocido. Cargar el\ncomponente desde el autocompletado.", ).exec_() return True else: return False def insert_new_recipe_into_db(self): recipe_being_created_display = (self.product_field.text() + "-" + self.model_field.text()) recipe_being_created_sql = utils.format_display_name_into_sql_name( recipe_being_created_display) fields_contents = utils.get_line_items_contents( self.comps_holder_section) components = fields_contents[0::2] amounts = fields_contents[1::2] recipe_contents = dict(zip(components, amounts)) db = db_manager.DB_Manager() db.create_recipe(recipe_being_created_sql) db.populate_recipe(recipe_being_created_sql, recipe_contents) db.log_new_config_record(config="Creación de receta", details=recipe_being_created_display) db.close_connection() admin_window = self.parent().parent().parent() admin_window.statusbar.show_quick_message("Receta creada: " + recipe_being_created_display) self.close()
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)
class ProductionReport(QtWidgets.QDialog): def __init__(self, parent=None): super(ProductionReport, self).__init__(parent) self.setWindowFlags( QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint ) self.setFixedWidth(410) self.entered_products_and_amounts = {} self.needed_comps_and_amounts = {} title = QtWidgets.QLabel("Informe de producción") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet(generic_title_style) code_label = QtWidgets.QLabel("Código:") self.code_field = AutocapField("K12345...") code_regex = QtCore.QRegExp("^[KBTkbt]{1}[0-9]{1,7}") code_validator = QtGui.QRegExpValidator(code_regex, self.code_field) self.code_field.setValidator(code_validator) self.code_field.setFixedWidth(110) self.code_field.setFocus() code_section = QtWidgets.QHBoxLayout() code_section.addStretch() code_section.addWidget(code_label) code_section.addWidget(self.code_field) code_section.addStretch() groupbox = QtWidgets.QGroupBox("Productos a fabricar") groupbox.setStyleSheet(generic_groupbox_normal_style) groupbox.setMinimumWidth(252) self.add_button = QtWidgets.QPushButton("+ Agregar producto") self.add_button.setShortcut("Alt+a") self.products_holder_section = QtWidgets.QVBoxLayout() groupbox_inner_section = QtWidgets.QVBoxLayout() groupbox_inner_section_1 = QtWidgets.QHBoxLayout() groupbox_inner_section_1.addWidget(self.add_button) groupbox_inner_section_2 = QtWidgets.QHBoxLayout() groupbox_inner_section_2.addLayout(self.products_holder_section) groupbox_inner_section.addLayout(groupbox_inner_section_1) groupbox_inner_section.addLayout(groupbox_inner_section_2) groupbox.setLayout(groupbox_inner_section) groupbox_section = QtWidgets.QHBoxLayout() groupbox_section.addStretch() groupbox_section.addWidget(groupbox) groupbox_section.addStretch() self.execute_button = QtWidgets.QPushButton("Calcular »") self.execute_button.setShortcut("Alt+c") self.execute_button.setFixedWidth(150) self.back_button = QtWidgets.QPushButton("« Volver") self.back_button.setShortcut("Alt+v") self.back_button.setFixedWidth(150) self.bottom_section = QtWidgets.QHBoxLayout() self.bottom_section.addWidget(self.back_button) self.bottom_section.addWidget(self.execute_button) self.layout = QtWidgets.QVBoxLayout() self.layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize) self.layout.addWidget(title) self.layout.addLayout(code_section) self.layout.addLayout(groupbox_section) self.layout.addLayout(self.bottom_section) self.setLayout(self.layout) self.add_button.clicked.connect(self.add_line_item) self.back_button.clicked.connect(self.close) self.execute_button.clicked.connect(self.on_execute_clicked) 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 on_execute_clicked(self): if self.execute_button.text() == "Calcular »": if self.test_if_there_are_no_products(): return if self.test_if_there_are_duplicates(): return if self.test_if_there_are_unrecognized_products(): return self.preview_calculation() elif self.execute_button.text() == "Generar informe »": if self.test_if_code_missing(): return self.generate_production_report() def test_if_there_are_no_products(self): no_line_items = not self.products_holder_section.children() contents = utils.get_line_items_contents(self.products_holder_section) empty_string = tests.test_if_empty_string_in_line_items_contents(contents) if no_line_items or empty_string: WarningBox( "Sin productos", "Completar o borrar campos\nvacíos antes de ejecutar." ).exec_() return True else: return False def test_if_there_are_duplicates(self): contents = utils.get_line_items_contents(self.products_holder_section) duplicates = tests.test_if_duplicated_first_value_in_line_items_contents( contents ) if duplicates: WarningBox( "Componentes duplicados", "Borrar uno de los componentes duplicados." ).exec_() return True else: return False def test_if_there_are_unrecognized_products(self): contents = utils.get_line_items_contents(self.products_holder_section) products = contents[0::2] db = db_manager.DB_Manager() existing_recipes = db.get_all_recipes_as_display() db.close_connection() unrecognized_products = not set(products).issubset(existing_recipes) if unrecognized_products: WarningBox( "Componente extraño", "Componente no reconocido. Cargar el\ncomponente desde el autocompletado.", ).exec_() return True else: return False def test_if_code_missing(self): code_missing = self.code_field.text() == "" if code_missing: WarningBox("Código faltante", "Ingresar código\nantes de generar.").exec_() return True else: return False def preview_calculation(self): table = QtWidgets.QTableWidget() table.setFixedWidth(360) table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) table.verticalHeader().setVisible(False) table.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) table.setFocusPolicy(QtCore.Qt.NoFocus) table.setColumnCount(2) table.setHorizontalHeaderLabels(["Componente", "Necesidad"]) table.horizontalHeaderItem(0).setTextAlignment(QtCore.Qt.AlignHCenter) table.horizontalHeaderItem(1).setTextAlignment(QtCore.Qt.AlignHCenter) table.horizontalHeader().setDefaultSectionSize(70) table.horizontalHeader().setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) table.horizontalHeader().setSectionResizeMode(1, QtWidgets.QHeaderView.Fixed) table_section = QtWidgets.QVBoxLayout() table_section.addWidget(table) self.layout.addLayout(table_section) self.add_button.setEnabled(False) utils.delete_layout(self.bottom_section) self.back_button = QtWidgets.QPushButton("« Volver") self.back_button.setShortcut("Alt+v") self.execute_button = QtWidgets.QPushButton("Calcular »") self.execute_button.setShortcut("Alt+c") self.bottom_section = QtWidgets.QHBoxLayout() self.bottom_section.addWidget(self.back_button) self.bottom_section.addWidget(self.execute_button) self.back_button.clicked.connect(self.close) self.add_button.clicked.connect(self.add_line_item) self.execute_button.clicked.connect(self.on_execute_clicked) self.layout.addLayout(self.bottom_section) self.entered_products_and_amounts = utils.get_line_items_contents( self.products_holder_section, as_dictionary=True ) series_for_production = [] db = db_manager.DB_Manager() for ( product_to_be_manufactured, amount_to_be_manufactured, ) in self.entered_products_and_amounts.items(): recipe_sql = utils.format_display_name_into_sql_name( product_to_be_manufactured ) product_recipe = db.get_recipe_contents(recipe_sql) for comp_name, comp_amount in product_recipe.items(): product_recipe[comp_name] = comp_amount * amount_to_be_manufactured series_for_production.append(product_recipe) db.close_connection() dd = defaultdict(list) for single_recipe in series_for_production: for component, amount in single_recipe.items(): dd[component].append(amount) for key, value in dd.items(): for _ in value: dd[key] = sum(value) self.needed_comps_and_amounts = dict(dd) table.setRowCount(len(self.needed_comps_and_amounts)) utils.populate_table_column_with_list_of_strings( table=table, col_num=0, input_list=self.needed_comps_and_amounts.keys() ) utils.populate_table_column_with_list_of_integers( table=table, col_num=1, input_list=self.needed_comps_and_amounts.values() ) custom_height = table.rowCount() * 30 + 25 if table.rowCount() <= 3: table.setMaximumHeight(custom_height) table.setFixedHeight(custom_height) elif table.rowCount() > 4: table.setMaximumHeight(205) table.setFixedHeight(205) self.execute_button.setText("Generar informe »") self.execute_button.setShortcut("Alt+g") self.code_field.setFocus() for l in self.products_holder_section.children(): l.itemAt(0).widget().setDisabled(True) l.itemAt(1).widget().setDisabled(True) self.add_button.clicked.disconnect() def generate_production_report(self): code = self.code_field.text() path = os.getcwd() + "\\src\\main\\resources\\production_report_template.xlsx" wb = load_workbook(path) ws = wb["Informe"] for product_name, product_amount in self.entered_products_and_amounts.items(): for cell in ws["B"][3:]: if cell.value is None: cell.value = product_name break for cell in ws["C"][3:]: if cell.value is None: cell.value = utils.format_number_for_display(product_amount) break db = db_manager.DB_Manager() df = db.make_needs_and_stocks_df(self.needed_comps_and_amounts) db.close_connection() assembler = code[0] fmt = utils.format_number_for_display for i in range(len(df)): for cell in ws["D"][3:]: if cell.value is None: cell.value = df["comp"][i] break for cell in ws["E"]: if cell.value is None: cell.value = fmt(df["need"][i]) break for cell in ws["F"]: if cell.value is None: if df["need"][i] <= df[assembler][i] + df["V"][i]: cell.value = "Sí" else: diff = fmt(df["need"][i] - (df[assembler][i] + df["V"][i])) cell.value = f"No, faltan {diff} unidades." break for cell in ws["G"]: if cell.value is None: cell.value = fmt(max(0, df["need"][i] - df[assembler][i])) break for cell in ws["H"]: if cell.value is None: cell.value = "0" break ws["B2"] = code ws["F2"] = datetime.now().strftime("%d/%m/%Y") if code.startswith("K"): ws["H2"] = "Karina" elif code.startswith("B"): ws["H2"] = "Brid" elif code.startswith("T"): ws["H2"] = "Tercero" current_date_hyphens = datetime.now().strftime("%d-%m-%Y") filepath_and_name = ( f"output\\INFORME DE PRODUCCIÓN {code} {current_date_hyphens}.xlsx" ) wb.save(filepath_and_name) wb.close() os.startfile( f"output\\INFORME DE PRODUCCIÓN {code} {current_date_hyphens}.xlsx" ) self.close()
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)
class CreateComponentDialog(QtWidgets.QDialog): def __init__(self, parent=None): super(CreateComponentDialog, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint) title = QtWidgets.QLabel("Crear componente") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet(generic_title_style) self.compname_field = AutocapField("Componente a crear...") self.compname_field.setFixedWidth(150) self.compname_field.setFocus() self.initstock_field = StockNumberField("Stock inicial...") self.initstock_field.setFixedWidth(80) back_button = QtWidgets.QPushButton("« Volver") back_button.setShortcut("Alt+v") self.execute_button = QtWidgets.QPushButton("Ejecutar »") self.execute_button.setDefault(True) line_edits_layout = QtWidgets.QHBoxLayout() line_edits_layout.addWidget(self.compname_field) line_edits_layout.addWidget(self.initstock_field) bottom_section = QtWidgets.QHBoxLayout() bottom_section.addWidget(back_button) bottom_section.addWidget(self.execute_button) layout = QtWidgets.QVBoxLayout() layout.addWidget(title) layout.addLayout(line_edits_layout) layout.addLayout(bottom_section) self.setLayout(layout) back_button.clicked.connect(self.close) self.execute_button.clicked.connect(self.create_component) def create_component(self): if self.compname_field.text() == "": message_boxes.WarningBox( "Sin nombre", "Dar nombre al componente\nantes de ejecutar.").exec_() self.compname_field.setFocus() return db = db_manager.DB_Manager() component_names_display = db.get_all_display_names_for_components() if self.compname_field.text() in component_names_display: message_boxes.WarningBox( "Nombre ya existente", "El nombre tiene que ser\ndiferente de los existentes.", ).exec_() self.compname_field.clear() self.compname_field.setFocus() return newcomp_display_name = self.compname_field.text() newcomp_sql_name = utils.format_display_name_into_sql_name( newcomp_display_name) initstock = 0 if self.initstock_field.text() != "": initstock = utils.format_number_for_calculation( self.initstock_field.text()) db.create_new_component(newcomp_sql_name, newcomp_display_name, initstock) db.log_new_config_record(config="Creación de componente", details=newcomp_display_name) db.close_connection() admin_window = self.parent().parent().parent() admin_window.statusbar.show_quick_message("Componente creado: " + newcomp_display_name) admin_window.start_screen.rebuild_main_section() QtWidgets.QApplication.processEvents() # enables scrolling table = admin_window.start_screen.main_section.table utils.scroll_to_row_in_table(table, newcomp_display_name) self.compname_field.clear() self.initstock_field.clear() self.close()
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)
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_()
def __init__(self, parent=None): super(ProductionReport, self).__init__(parent) self.setWindowFlags( QtCore.Qt.Dialog | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint ) self.setFixedWidth(410) self.entered_products_and_amounts = {} self.needed_comps_and_amounts = {} title = QtWidgets.QLabel("Informe de producción") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet(generic_title_style) code_label = QtWidgets.QLabel("Código:") self.code_field = AutocapField("K12345...") code_regex = QtCore.QRegExp("^[KBTkbt]{1}[0-9]{1,7}") code_validator = QtGui.QRegExpValidator(code_regex, self.code_field) self.code_field.setValidator(code_validator) self.code_field.setFixedWidth(110) self.code_field.setFocus() code_section = QtWidgets.QHBoxLayout() code_section.addStretch() code_section.addWidget(code_label) code_section.addWidget(self.code_field) code_section.addStretch() groupbox = QtWidgets.QGroupBox("Productos a fabricar") groupbox.setStyleSheet(generic_groupbox_normal_style) groupbox.setMinimumWidth(252) self.add_button = QtWidgets.QPushButton("+ Agregar producto") self.add_button.setShortcut("Alt+a") self.products_holder_section = QtWidgets.QVBoxLayout() groupbox_inner_section = QtWidgets.QVBoxLayout() groupbox_inner_section_1 = QtWidgets.QHBoxLayout() groupbox_inner_section_1.addWidget(self.add_button) groupbox_inner_section_2 = QtWidgets.QHBoxLayout() groupbox_inner_section_2.addLayout(self.products_holder_section) groupbox_inner_section.addLayout(groupbox_inner_section_1) groupbox_inner_section.addLayout(groupbox_inner_section_2) groupbox.setLayout(groupbox_inner_section) groupbox_section = QtWidgets.QHBoxLayout() groupbox_section.addStretch() groupbox_section.addWidget(groupbox) groupbox_section.addStretch() self.execute_button = QtWidgets.QPushButton("Calcular »") self.execute_button.setShortcut("Alt+c") self.execute_button.setFixedWidth(150) self.back_button = QtWidgets.QPushButton("« Volver") self.back_button.setShortcut("Alt+v") self.back_button.setFixedWidth(150) self.bottom_section = QtWidgets.QHBoxLayout() self.bottom_section.addWidget(self.back_button) self.bottom_section.addWidget(self.execute_button) self.layout = QtWidgets.QVBoxLayout() self.layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize) self.layout.addWidget(title) self.layout.addLayout(code_section) self.layout.addLayout(groupbox_section) self.layout.addLayout(self.bottom_section) self.setLayout(self.layout) self.add_button.clicked.connect(self.add_line_item) self.back_button.clicked.connect(self.close) self.execute_button.clicked.connect(self.on_execute_clicked)
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")
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()