def generate_random_test_item(add_to_db=False): im = ItemManager() item = Item() item.id = None item.title = 'test - ' + string_nor(12) item.author = 'test - ' + string_nor(12) item.isbn = string_digits_nor(13) item.bid = string_digits_nor(10) item.lang = LangEnum(random.randint(1, 9)) item.material = MaterialEnum(random.randint(1, 7)) item.type = TypeEnum(random.randint(1, 15)) item.nature = NatureEnum(random.randint(1, 3)) item.cataloging_level = CatalogingLevel(random.randint(0, 1)) item.publication_date = datetime.today().date() item.publication_state = random.randint(0, 1) item.rack = random.randint(1, 100) item.shelf = string_nor(1) item.position = random.randint(1, 300) item.opac_visibility = random.randint(0, 1) item.price = random.random() * 100 item.quarantine_start_date = None item.quarantine_end_date = None item.discarded_date = None genres = im.get_genres() item.genre = [genres[random.randint(1, len(genres) - 1)]] item.inner_state = [SMUSIEnum(random.randint(0, len(SMUSIEnum) - 1))] item.external_state = [ExternalStateEnum(random.randint(1, len(ExternalStateEnum)))] item.note = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent varius in augue sodales semper." if add_to_db: item = im.add_item(item, return_item=True) return item
def __init__(self, widget, item, update_func): ''' CatalogingView script, handles CatalogingView behaviour which adds/edits an item :param widget: QWidget :param item: Item to edit ''' super(CatalogingView, self).__init__() loadUi("../designer/Items/CatalogingView.ui", self) self.update = update_func self.something_changed = False self.validators_status = None self.__field_with_validator = [] self.__dbms = DatabaseManager() self.__im = ItemManager() self.widget = widget self.item = item self.__qsd = None # data inizio quarantena self.__qed = None # data fine quarantena self.inner_state = CheckableComboBox( self.admin_frame) # make ComboBox a CheckableComboBox self.external_state = CheckableComboBox(self.admin_frame) self.genre = CheckableComboBox(self.cataloging_frame) self.inner_state.setGeometry(QRect(220, 30, 121, 21)) # position of the combobox self.external_state.setGeometry(QRect(220, 60, 121, 21)) self.genre.setGeometry(QRect(210, 180, 231, 21)) self.load_item(self.item) self.quarantine_start_button.clicked.connect(self.__start_quarantine) self.save_button.clicked.connect(self.__save_button) self.go_back_button.clicked.connect(self.close) self.title.textChanged.connect(self.check_qline_state) self.author.textChanged.connect(self.check_qline_state) self.bid.textChanged.connect(self.check_qline_state) self.isbn.textChanged.connect(self.check_qline_state) self.rack.textChanged.connect(self.check_qline_state) self.shelf.textChanged.connect(self.check_qline_state) self.position.textChanged.connect(self.check_qline_state) self.price.textChanged.connect(self.check_qline_state) self.title.textChanged.connect(self.something_changed_set) self.author.textChanged.connect(self.something_changed_set) self.bid.textChanged.connect(self.something_changed_set) self.isbn.textChanged.connect(self.something_changed_set) self.rack.textChanged.connect(self.something_changed_set) self.shelf.textChanged.connect(self.something_changed_set) self.position.textChanged.connect(self.something_changed_set) self.price.textChanged.connect(self.something_changed_set) self.quarantine_start_button.clicked.connect( self.something_changed_set) self.set_validators() self.check_validators()
def generate_random_item(): locale = "en_US" if random.randint(0, 10) < 5: locale = "it_IT" fake = Faker(locale=locale) im = ItemManager() item = Item() item.id = None item.title = fake.catch_phrase() item.author = fake.last_name() item.isbn = fake.isbn13().replace('-', '') item.bid = fake.isbn10().replace('-', '') item.lang = random.choice(list(LangEnum)) item.material = random.choice(list(MaterialEnum)) item.type = random.choice(list(TypeEnum)) item.nature = random.choice(list(NatureEnum)) item.cataloging_level = random.choice(list(CatalogingLevel)) item.publication_date = fake.date_time() item.publication_state = random.randint(0, 1) item.rack = random.randint(1, 100) item.shelf = string_nor(1) item.position = random.randint(1, 300) item.opac_visibility = random.randint(0, 1) item.price = random.random() * 100 item.availability = random.choice(list(AvailabilityEnum)) if item.availability.value == AvailabilityEnum.scartato: item.discarded_date = fake.date_time() elif item.availability == AvailabilityEnum.in_quarantena: item.quarantine_start_date = fake.date_between(datetime.today() - timedelta(4), datetime.today()) item.quarantine_end_date = item.quarantine_start_date + timedelta(4) genres = im.get_genres() item.genre = [genres[random.randint(1, len(genres) - 1)]] item.inner_state = [SMUSIEnum(random.randint(0, len(SMUSIEnum) - 1))] item.external_state = [ExternalStateEnum(random.randint(1, len(ExternalStateEnum)))] item.note = fake.sentence() return item
class MovementManager: db = DatabaseManager() itemM = ItemManager() def list(self): movements = self.db.get_movements() return movements def find(self, id): movements = self.db.find_movement_by_id(id) return movements def find_all(self, search_field_mov_type=None, search_mode=None, search_field=None): movements = self.db.find_movement(search_field_mov_type, search_mode, search_field) return movements def set(self, movement): self.db.set_movement(movement) def add(self, movement): self.db.insert_movement(movement) def delete(self, id): self.db.delete_movement(id) def get_items_available(self): self.items = self.itemM.get_items('', 0, False, False) self.items_available = [] for item in self.items: if item.availability.value == 1: self.items_available.append(item) return self.items_available def get_movements_by_date(self, date: datetime.date): return self.db.get_movements_by_date(date) def get_last_movement_id(self): ids_mov = self.db.get_movements_id() return ids_mov[0].id def delete(self, id): self.db.delete_movement(id)
def movement_generator(im: ItemManager, um: UserManager, mov=None): fake = Faker(locale="it_IT") movement = Movement() movement.id = 'null' if mov is not None: movement.user_id = mov.user_id movement.item_id = mov.item_id movement.mov_type = 2 movement.timestamp = mov.timestamp + timedelta(days=random.randint(3, 60)) movement.note = mov.note else: movement.mov_type = 1 movement.timestamp = fake.date_time() movement.item = im.convert_dbitem( im.dbms.query("SELECT * FROM items ORDER BY RAND() LIMIT 1;", returns=True)[0]) movement.item_id = movement.item.id movement.user = um.set_users_to_model(um.db.query("SELECT * FROM users ORDER BY RAND() LIMIT 1;", returns=True), True) movement.user_id = movement.user.id movement.note = fake.sentence() return movement
class MovementsView(QMainWindow): movementM = MovementManager() itemM = ItemManager() def __init__(self, widget): super(MovementsView, self).__init__() loadUi("../designer/Movements/MovementView.ui", self) self.widget = widget self.view = '' self.setup() def setup(self): self.style() self.loanButton.clicked.connect(lambda: self.new_loan()) self.consultationButton.clicked.connect( lambda: self.new_consultation()) self.infoButton.clicked.connect(lambda: self.movement_info()) self.backButton.clicked.connect(lambda: self.close()) self.givingbookButton.clicked.connect(lambda: self.giving()) self.deleteMovements.clicked.connect(lambda: self.delete()) self.loanRadio.setChecked(True) self.searchField.textChanged.connect(lambda: self.search()) self.loanRadio.toggled.connect(lambda: self.search()) self.consultationRadio.toggled.connect(lambda: self.search()) self.backRadio.toggled.connect(lambda: self.search()) self.load_data() def style(self): # Button Style self.loanButton.setStyleSheet( open("../designer/style/ButtonTheme.txt", "r").read()) self.consultationButton.setStyleSheet( open("../designer/style/ButtonTheme.txt", "r").read()) self.infoButton.setStyleSheet( open("../designer/style/ButtonTheme.txt", "r").read()) # Line Edit Style self.searchField.setStyleSheet( open("../designer/style/TextBoxTheme.txt", "r").read()) # Table Style self.movementTable.setStyleSheet( open("../designer/style/TableTheme.txt", "r").read()) def new_consultation(self): self.view = LoanView(self.widget, self.load_data, 0) self.view.show() def new_loan(self): self.view = LoanView(self.widget, self.load_data, 1) self.view.show() def movement_info(self): rowtable = self.movementTable.currentRow() if rowtable == -1: self.popUp = Popup("Selezionare prima un movimento!") self.popUp.show() else: movement = self.movements[rowtable] self.view = InfoView(self.widget, movement) #self.view = LoanView(self.widget, self.load_data, 1) self.view.show() def load_data(self): self.movements = self.movementM.find_all(self.radio_selection(), 5) self.load_table() def load_table(self): """ Questo metodo permette di rimpire la QTableWidget presente nella view con una lista di utenti :param users: :return: None """ row = 0 self.movementTable.setRowCount(len(self.movements)) for movement in self.movements: self.movementTable.setItem( row, 0, QtWidgets.QTableWidgetItem( movement.timestamp.strftime('%d/%m/%Y %H:%M:%S'))) self.movementTable.setItem( row, 1, QtWidgets.QTableWidgetItem(movement.item.isbn)) self.movementTable.setItem( row, 2, QtWidgets.QTableWidgetItem(movement.item.title)) self.movementTable.setItem( row, 3, QtWidgets.QTableWidgetItem(movement.user.fiscal_code)) self.movementTable.setItem( row, 4, QtWidgets.QTableWidgetItem(movement.user.name + " " + movement.user.surname)) self.movementTable.setItem( row, 5, QtWidgets.QTableWidgetItem(movement.user.first_cellphone)) row = row + 1 self.movementTable.setEditTriggers(QTableWidget.NoEditTriggers) def search(self): numSearchMode = 0 if self.searchField.text() != '': if self.searchMode.currentText() == 'In tutti i campi': numSearchMode = 0 elif self.searchMode.currentText() == 'Utente': numSearchMode = 1 elif self.searchMode.currentText() == 'Titolo': numSearchMode = 2 elif self.searchMode.currentText() == 'Data': numSearchMode = 3 elif self.searchMode.currentText() == 'ISBN': numSearchMode = 4 self.movements = self.movementM.find_all(self.radio_selection(), numSearchMode, self.searchField.text()) else: self.movements = self.movementM.find_all(self.radio_selection(), 5) self.load_table() def radio_selection(self): if self.consultationRadio.isChecked(): return 0 elif self.loanRadio.isChecked(): return 1 elif self.backRadio.isChecked(): return 2 def giving(self): rowtable = self.movementTable.currentRow() self.movements[ rowtable].item.availability = AvailabilityEnum.disponibile self.movements[rowtable].item.cataloging_level = CatalogingLevel.max self.movements[rowtable].item.publication_state = 0 self.movements[rowtable].mov_type = 2 self.movementM.set(self.movements[rowtable]) self.itemM.edit_item( self.movements[self.movementTable.currentRow()].item) self.load_data() #deleteMovements def delete(self): rowtable = self.movementTable.currentRow() if rowtable == -1: self.show_popup() else: text = "Sei sicuro di voler eliminare il movimento?" self.pop = DeletePopup(self.delete_movement, text) self.pop.show() def delete_movement(self): """ Questo metodo permette di rimuovere l'utente selezionato dal sistema :return: None """ row = self.movementTable.currentRow() self.movementM.delete(self.movements[row].id) self.movements.remove(self.movements[row]) self.movementTable.removeRow(row)
class TestItemManager(unittest.TestCase): im = ItemManager() item = Item() @classmethod def setUpClass(cls) -> None: cls.dbms = dbms("../config/db.json") def setUp(self) -> None: self.item = src.Utils.Tools.generate_random_test_item() self.item = self.im.add_item( self.item ) #gia questo permette di testare la funzione add_item, se fallisce qualcosa non va print(self.item) def test_get_item(self): self.assertEqual(self.im.get_item(self.item).id, self.item.id) def test_get_item_genres(self): self.assertEqual(self.im.get_item_genres(self.item.id), self.item.genre) def test_get_genres(self): self.assertEqual(len(self.im.get_genres()), 49) genres = self.im.get_genres([1, 49]) self.assertEqual(genres[0]['description'], "Mimo") self.assertEqual(genres[1]['description'], "Ucronia") del genres def test_get_inner_states(self): self.assertEqual(len(self.im.get_inner_states()), 5) def test_get_items(self): test_items = [] for i in range(1, 10): test_items.append( self.im.add_item(src.Utils.Tools.generate_random_test_item())) for item in test_items: for i, s in enumerate(self.im.get_items(item.title, 0)): self.assertEqual(s.id, item.id) for i, s in enumerate(self.im.get_items(item.title, 1)): self.assertEqual(s.id, item.id) for i, s in enumerate(self.im.get_items(item.author, 2)): self.assertEqual(s.id, item.id) self.assertNotEqual(len(self.im.get_items(test_items[1].isbn, 3)), 0) self.assertNotEqual(len(self.im.get_items(test_items[2].bid, 4)), 0) self.assertNotEqual(len(self.im.get_items(test_items[3].id, 5)), 0) self.assertNotEqual(len(self.im.get_items(test_items[4].note, 6)), 0) for it in test_items: self.im.delete_item(it) del test_items def test_edit_item(self): self.item.quarantine_start_date = datetime.today().date() self.item.quarantine_end_date = self.item.quarantine_start_date + timedelta( 4) self.item.availability = AvailabilityEnum.in_quarantena self.im.edit_item(self.item) self.assertEqual(self.item.quarantine_start_date, self.im.get_item(self.item).quarantine_start_date) self.assertEqual(self.item.quarantine_end_date, self.im.get_item(self.item).quarantine_end_date) self.assertEqual(self.item.availability, self.im.get_item(self.item).availability) self.assertEqual(self.item.discarded_date, self.im.get_item(self.item).discarded_date) genres = self.im.get_genres() self.item.genre = [ genres[random.randint(0, len(genres) - 1)], genres[random.randint(0, len(genres) - 1)] ] #inserisco un SMUSIEnum.nessuno per verificare che questo non venga aggiunto nel database self.item.inner_state = [ SMUSIEnum(0), SMUSIEnum(random.randint(1, len(SMUSIEnum) - 1)) ] self.item.external_state = [ ExternalStateEnum(random.randint(1, len(ExternalStateEnum) - 1)), ExternalStateEnum(random.randint(1, len(ExternalStateEnum) - 1)) ] self.im.edit_item(self.item) time.sleep(1) self.assertEqual(self.im.get_item_genres(self.item.id), self.item.genre) # quando si inserisce SMUSIEnum.nessuno (indice 0), questo non viene inserito nel database e # quando viene richiesto ritorna una lista vuota! self.assertEqual( self.im.get_item(self.item).inner_state, [self.item.inner_state[1]]) self.assertEqual( self.im.get_item(self.item).external_state, self.item.external_state) def tearDown(self) -> None: self.im.delete_item(self.item) @classmethod def tearDownClass(cls) -> None: for item in cls.dbms.get_items("test -", 0): cls.im.delete_item(item)
class InventoryView(QMainWindow): itmManager = ItemManager() __items = [] def __init__(self, widget, parent): super(InventoryView, self).__init__(parent) loadUi("../designer/Items/InventoryViewNew.ui", self) self.widget = widget self.show_item_view = ShowItemView(self.widget) self.cataloging_view = CatalogingView(self.widget, Item(), self.search) try: self.itemTable.setSelectionBehavior(QTableView.SelectRows) self.searchField.textChanged.connect(self.search) self.quarantineCheckBox.stateChanged.connect(self.search) self.discardedCheckBox.stateChanged.connect(self.search) self.addButton.clicked.connect(self.add_item) self.modifyButton.clicked.connect(self.edit_item) self.discardButton.clicked.connect(self.discard_item) self.returnButton.clicked.connect(self.__go_back) self.showItemButton.clicked.connect(self.show_item) self.searchMode.currentIndexChanged.connect(self.search) self.cataloging_view.go_back_button.connect(self.search) self.cataloging_view.save_button.connect(self.search) self.show_item_view.go_back_button.connect(self.search) except Exception as err: print(err) self.search() def search(self): self.__get_items() self.__update_table() def add_item(self): self.__go_to_cataloging_view(new=True) def discard_item(self): item = self.__get_selected_item() if item is None: ErrorMessage("Selezionare un elemento da scartare!").exec_() return discard = Dialog(f"Sei sicuro di voler scartare {item.title} di {item.author}?(Questa azione è irreversibile!)") ok = discard.exec_() if ok: if not self.__get_selected_item().availability == AvailabilityEnum.scartato: self.itmManager.discard_item(self.__get_selected_item()) self.search() def show_item(self): if self.__get_selected_item() is None: ErrorMessage("Selezionare un elemento per visualizzarlo!").exec_() else: self.__go_to_show_item_view() def edit_item(self): print(self.__get_selected_item()) if self.__get_selected_item() is None: ErrorMessage("Selezionare un elemento da modificare!").exec_() return self.__go_to_cataloging_view() # region Private def __get_items(self): self.__items = [] query = self.searchField.text() # if "\'" in query: # query.replace("\'", "\x27") self.__items = self.itmManager.get_items(query, self.searchMode.currentIndex(), self.quarantineCheckBox.isChecked(), self.discardedCheckBox.isChecked()) def __update_table(self): self.itemTable.clearSelection() self.__remove_rows() for item in self.__items: row = self.itemTable.rowCount() self.itemTable.insertRow(row) self.itemTable.setItem(row, 0, QTableWidgetItem(item.title)) self.itemTable.setItem(row, 1, QTableWidgetItem(item.author)) self.itemTable.setItem(row, 2, QTableWidgetItem(item.isbn)) self.itemTable.setItem(row, 3, QTableWidgetItem(item.bid)) self.itemTable.setItem(row, 4, QTableWidgetItem(str(item.availability.name).replace('_', " "))) self.itemTable.setItem(row, 5, QTableWidgetItem(item.note)) self.itemTable.setEditTriggers(QTableWidget.NoEditTriggers) def __get_selected_item(self): if self.itemTable.currentRow() != -1: return self.__items[self.itemTable.currentRow()] else: return None def __remove_rows(self): """ Remove all rows from table :return: """ for i in reversed(range(0, self.itemTable.rowCount())): self.itemTable.removeRow(i) def __go_back(self): # self.widget.setCurrentIndex(self.widget.currentIndex() - 1) self.close() def __go_to_cataloging_view(self, new=False): if not new: self.cataloging_view.item = self.__get_selected_item() else: self.cataloging_view.item = Item() self.cataloging_view.show() def __go_to_show_item_view(self): self.show_item_view.load_item(self.__get_selected_item()) self.show_item_view.show()
db = DatabaseManager() db.query("DELETE FROM users;") db.query("DELETE FROM items;") db.query("DELETE FROM movements;") db.query("DELETE FROM items_genres;") db.query("DELETE FROM items_inner_states;") db.query("DELETE FROM items_external_states;") def test_thread(): for i in range(0, 100): print("test") if __name__ == "__main__": im = ItemManager() um = UserManager() mm = MovementManager() sm = ServiceReservationManager() #delete_all_previous() generate_users(1000, um) generate_items(500, im) generate_movement(1000, im, um, mm) generate_service_reservations(200, sm) # _thread.start_new_thread(generate_items, (25000,)) # _thread.start_new_thread(generate_items, (25000,)) # # _thread.start_new_thread(generate_movement, (33000,))
class LoanView(QDialog): userM = UserManager() itemM = ItemManager() movementM = MovementManager() def __init__(self, widget, callback, flag): super(LoanView, self).__init__() ''' 0:Consultazione 1:Prestito 2:Rientro ''' loadUi("../designer/Movements/LoanView.ui", self) self.widget = widget self.users = self.userM.list() self.items = self.movementM.get_items_available() self.user = '' self.movement = Movement() self.callback = callback self.flag = flag # self.setModal(True) # self.widget = QtWidgets.QStackedWidget() # self.widget.addWidget(self) # self.widget.show() self.setup() #self.movementM = MovementManager() #self.movementM.findAll("tu", 1) if self.flag == 0: self.loantypeBox.hide() self.expirationEdit.hide() self.label_9.hide() self.label_10.hide() #self.frame_13.setGeometry(931,210) def setup(self): self.selectuserButton.clicked.connect(lambda: self.select_user()) self.selectuserButton.setDisabled(False) self.selectdocButton.clicked.connect(lambda: self.select_item()) self.selectdocButton.setDisabled(False) self.newuserButton.clicked.connect(lambda: self.new_user()) self.confirmButton.clicked.connect( lambda: self.save()) #salvataggio del movimento self.returnButton.clicked.connect(lambda: self.close()) self.userField.setReadOnly(True) self.fiscalcodeField.setReadOnly(True) self.cellField.setReadOnly(True) self.style() self.load_user_table() self.load_item_table(self.items) def style(self): self.userTable.setStyleSheet( open("../designer/style/TableTheme.txt", "r").read()) self.itemTable.setStyleSheet( open("../designer/style/TableTheme.txt", "r").read()) self.nameField.textChanged.connect(lambda: self.search_user()) self.surnameField.textChanged.connect(lambda: self.search_user()) self.itemField.textChanged.connect(lambda: self.search_item()) def select_user(self): if self.userTable.currentRow() == -1: self.pop = Popup("Selezionare un utente") self.pop.show() else: row = self.userTable.currentRow() self.user = self.users[row] # assegno l'id dello user al movimento self.movement.user_id = self.user.id self.userField.setText(self.user.name + " " + self.user.surname) self.fiscalcodeField.setText(self.user.fiscal_code) self.cellField.setText(self.user.first_cellphone) def select_item(self): if self.itemTable.currentRow() == -1: self.pop = Popup("Selezionare un Documento") self.pop.show() else: row = self.itemTable.currentRow() item = self.items[row] #assegno l'id dell'item al movimento self.movement.item_id = item.id self.isbnField.setText(item.isbn) self.titleField.setText(item.title) def new_user(self): self.view = UserCardView(self.widget, None, self.load_user_table) self.view.show() # region Table def load_user_table(self, users=None): if users is None: self.users = self.userM.list() else: self.users = users if self.users is not None: row = 0 self.userTable.setRowCount(len(self.users)) for user in self.users: self.userTable.setItem(row, 0, QtWidgets.QTableWidgetItem(user.name)) self.userTable.setItem( row, 1, QtWidgets.QTableWidgetItem(user.surname)) self.userTable.setItem( row, 2, QtWidgets.QTableWidgetItem(user.fiscal_code)) row = row + 1 self.userTable.setEditTriggers(QTableWidget.NoEditTriggers) def load_item_table(self, items): self.items = items row = 0 self.itemTable.setRowCount(len(self.items)) for item in self.items: self.itemTable.setItem(row, 0, QtWidgets.QTableWidgetItem(item.title)) self.itemTable.setItem(row, 1, QtWidgets.QTableWidgetItem(item.author)) self.itemTable.setItem(row, 2, QtWidgets.QTableWidgetItem(item.isbn)) row = row + 1 self.itemTable.setEditTriggers(QTableWidget.NoEditTriggers) # endregion # region Search def search_user(self): try: if (self.nameField.text() == '') and (self.surnameField.text() == ''): self.load_user_table(self.userM.list()) elif (self.nameField.text() != '') and (self.surnameField.text() == ''): #print(self.userM.findName(self.nameField.text(), False)) self.load_user_table(self.userM.findName( self.nameField.text())) elif (self.nameField.text() == '') and (self.surnameField.text() != ''): self.load_user_table( self.userM.findSurname(self.surnameField.text())) elif (self.nameField.text() != '') and (self.surnameField.text() != ''): self.load_user_table( self.userM.findNameSurname(self.nameField.text(), self.surnameField.text())) except FileNotFoundError as err: src.Utils.UI.ErrorMessage(err).show() def search_item(self): self.load_item_table(self.itemM.get_items(self.itemField.text(), 1)) # endregion # region Save_and_back def save(self): row = self.itemTable.currentRow() if self.movement.user_id is None or self.movement.item_id is None: self.pop = Popup("Selezionare sia un Utente sia un Documento") self.pop.show() else: if self.flag == 1: self.movement.mov_type = 1 else: self.movement.mov_type = 0 self.movement.timestamp = date.today() self.movementM.add(self.movement) self.movement = self.movementM.find( self.movementM.get_last_movement_id()) newpath = os.path.expanduser("~/Desktop/Moduli Prestito") if not os.path.exists(newpath): os.makedirs(newpath) self.reportM = ReportManager(self.movement, newpath) self.reportM.set_report() self.back() self.items[row].availability = AvailabilityEnum.in_prestito self.itemM.edit_item(self.items[row]) def back(self): self.callback() self.close()
class CatalogingView(QMainWindow): """ CatalogingView script """ def __init__(self, widget, item, update_func): ''' CatalogingView script, handles CatalogingView behaviour which adds/edits an item :param widget: QWidget :param item: Item to edit ''' super(CatalogingView, self).__init__() loadUi("../designer/Items/CatalogingView.ui", self) self.update = update_func self.something_changed = False self.validators_status = None self.__field_with_validator = [] self.__dbms = DatabaseManager() self.__im = ItemManager() self.widget = widget self.item = item self.__qsd = None # data inizio quarantena self.__qed = None # data fine quarantena self.inner_state = CheckableComboBox( self.admin_frame) # make ComboBox a CheckableComboBox self.external_state = CheckableComboBox(self.admin_frame) self.genre = CheckableComboBox(self.cataloging_frame) self.inner_state.setGeometry(QRect(220, 30, 121, 21)) # position of the combobox self.external_state.setGeometry(QRect(220, 60, 121, 21)) self.genre.setGeometry(QRect(210, 180, 231, 21)) self.load_item(self.item) self.quarantine_start_button.clicked.connect(self.__start_quarantine) self.save_button.clicked.connect(self.__save_button) self.go_back_button.clicked.connect(self.close) self.title.textChanged.connect(self.check_qline_state) self.author.textChanged.connect(self.check_qline_state) self.bid.textChanged.connect(self.check_qline_state) self.isbn.textChanged.connect(self.check_qline_state) self.rack.textChanged.connect(self.check_qline_state) self.shelf.textChanged.connect(self.check_qline_state) self.position.textChanged.connect(self.check_qline_state) self.price.textChanged.connect(self.check_qline_state) self.title.textChanged.connect(self.something_changed_set) self.author.textChanged.connect(self.something_changed_set) self.bid.textChanged.connect(self.something_changed_set) self.isbn.textChanged.connect(self.something_changed_set) self.rack.textChanged.connect(self.something_changed_set) self.shelf.textChanged.connect(self.something_changed_set) self.position.textChanged.connect(self.something_changed_set) self.price.textChanged.connect(self.something_changed_set) self.quarantine_start_button.clicked.connect( self.something_changed_set) self.set_validators() self.check_validators() def load_item(self, item) -> None: """ this method loads item :param item: :return: """ self.bid.setText(str(item.bid)) self.isbn.setText(str(item.isbn)) self.title.setText(item.title) self.author.setText(item.author) if item.publication_date is not None: self.publication_date.setDate(item.publication_date) if item.id is None: self.id.setText('') else: self.id.setText(str(item.id)) if item.shelf is None: self.shelf.setText('') else: self.shelf.setText(str(item.shelf)) if item.rack is None: self.rack.setText('') else: self.rack.setText(str(item.rack)) if item.position is None: self.position.setText('') else: self.position.setText(str(item.position)) self.price.setText(str(item.price)) self.note.setText(item.note) if item.quarantine_start_date is not None: if item.quarantine_end_date is not None: self.quarantine_due_time.setText( str(item.quarantine_end_date - item.quarantine_start_date)) self.quarantine_end_date.setText(str(item.quarantine_end_date)) genre_list = [] self.genre.clear() for i in self.__dbms.get_genres(): genre_list.append(i.description) for index, element in enumerate(genre_list): self.genre.addItem(element) nitem = self.genre.model().item(index, 0) nitem.setCheckState(Qt.Unchecked) for k in range(0, len(item.genre)): for index, element in enumerate(genre_list): if element == self.item.genre[k]['description']: nitem = self.genre.model().item(index, 0) nitem.setCheckState(Qt.Checked) self.__fill_checkable_with_enum(SMUSIEnum, self.inner_state, item.inner_state, starts_at=0) self.__fill_checkable_with_enum(ExternalStateEnum, self.external_state, item.external_state) self.__fill_with_enum(TypeEnum, self.type) self.__fill_with_enum(MaterialEnum, self.material) self.__fill_with_enum(NatureEnum, self.nature) self.__fill_with_enum(LangEnum, self.lang) self.__fill_with_enum(CatalogingLevel, self.cataloging_level, starts_at=0) self.__fill_with_enum(AvailabilityEnum, self.availability) self.cataloging_level.setCurrentIndex(item.cataloging_level.value) self.material.setCurrentIndex(item.material.value) self.nature.setCurrentIndex(item.nature.value - 1) self.type.setCurrentIndex(item.type.value - 1) self.opac_visibility.setCurrentIndex(item.opac_visibility) self.availability.setCurrentIndex(item.availability.value - 1) self.publication_state.setCurrentIndex(item.publication_state) self.lang.setCurrentIndex(item.lang.value - 1) if len(item.genre) > 0: self.genre.setCurrentIndex(item.genre[0]['id'] - 1) if len(item.inner_state) > 0: self.inner_state.setCurrentIndex(item.inner_state[0].value) if len(item.external_state) > 0: self.external_state.setCurrentIndex(item.external_state[0].value - 1) self.opac_visibility.clear() self.opac_visibility.addItem("Non Visibile") self.opac_visibility.addItem("Visibile") self.publication_state.clear() self.publication_state.addItem("Non Pubblicato") self.publication_state.addItem("Pubblicato") self.something_changed = False def check_qline_state(self, *args, **kwargs): sender = self.sender() validator = sender.validator() state = validator.validate(sender.text(), 0)[0] if sender.property("isUpper"): sender.setText(sender.text().upper()) if state == PyQt5.QtGui.QValidator.Acceptable: color = 'background-color:rgba(23, 28, 78, 100); color:rgba(255, 255, 255); border-radius: 20px;' \ 'border-style: solid; border:none; text-align: center;' # green' elif state == PyQt5.QtGui.QValidator.Intermediate: color = 'background-color:rgba(255, 255, 0, 200); color:rgba(0, 0, 0); border-radius: 20px;' \ 'border-style: solid; border:none; text-align: center;' # yellow else: color = 'background-color:rgba(255, 0, 0, 100); color:rgb(0, 0, 0); border-radius: 20px;' \ 'border-style: solid; border:none; text-align: center;' # red sender.setStyleSheet('QLineEdit { %s }' % color) def set_validators(self): self.__field_with_validator = [] self.title.setValidator( QRegExpValidator( QRegExp('^[\\w\\s\'\*\.\-,!`?@"\[\]{}=_+():]{1,150}$'))) self.author.setValidator( QRegExpValidator( QRegExp('^[\\w\\s\'\*\.\-,!`?@"\[\]{}=_+():]{1,150}$'))) self.bid.setValidator(QRegExpValidator(QRegExp('^\\w{10}$'))) self.isbn.setValidator(QRegExpValidator(QRegExp('^\\w{13}$'))) self.rack.setValidator(QRegExpValidator(QRegExp('^\\d{1,4}$'))) self.shelf.setValidator(QRegExpValidator(QRegExp('^[a-zA-Z]{1}$'))) self.position.setValidator(QRegExpValidator(QRegExp('^\\d{1,3}$'))) self.price.setValidator( QRegExpValidator(QRegExp('^(\\d+)\.(\\d{0,2})$'))) self.__field_with_validator.append(self.title) self.__field_with_validator.append(self.author) self.__field_with_validator.append(self.bid) self.__field_with_validator.append(self.isbn) self.__field_with_validator.append(self.rack) self.__field_with_validator.append(self.shelf) self.__field_with_validator.append(self.position) self.__field_with_validator.append(self.price) # self.quarantine_due_time.setValidator(QRegExpValidator(QRegExp('^\\d{1,4}$'))) # self.quarantine_end_date.setValidator(QRegExpValidator(QRegExp('^\\d{1,4}$'))) # QRegExpValidator(QRegExp('^[a-zA-Z]*$')) @staticmethod def __fill_with_enum(enum, obj, starts_at=1, selected_index=None) -> None: obj.clear() en_list = [] en_id = [] for i in range(starts_at, len(enum) + starts_at): en_list.append(enum(i).name.capitalize().replace("_", " ")) en_id.append(enum(i).value) for index, element in enumerate(en_list): obj.addItem(element) @staticmethod def __fill_checkable_with_enum(enum, obj, item_list, starts_at=1) -> None: obj.clear() en_list = [] en_id = [] for i in range(starts_at, len(enum) + starts_at): en_list.append(enum(i).name.replace('_', ' ').capitalize()) en_id.append(enum(i).value) for index, element in enumerate(en_list): obj.addItem(element) obj.model().item(index, 0).setCheckState(Qt.Unchecked) if len(item_list) > 0: for index, element in enumerate(en_id): for k in item_list: if element - starts_at == k.value: obj.model().item(index, 0).setCheckState(Qt.Checked) def __get_from_view(self): new_item = self.item new_item.title = self.title.text() new_item.author = self.author.text() # if len(new_item.title) == 0 or len(new_item.author) == 0: # self.title.setStyleSheet('border-color:rgb(255,0,0)') # self.author.setStyleSheet('border-color:rgb(255,0,0)') new_item.material = MaterialEnum(self.material.currentIndex() + 1) # if self.material.currentIndex() < 0: # self.material.setStyleSheet('border-color:rgb(255,0,0)') new_item.type = TypeEnum(self.type.currentIndex() + 1) # if self.type.currentIndex() < 0: # self.material.setStyleSheet('border-color:rgb(255,0,0)') new_item.nature = NatureEnum(self.nature.currentIndex() + 1) # if self.nature.currentIndex() < 0: # self.nature.setStyleSheet('border-color:rgb(255,0,0)') new_item.publication_date = self.publication_date.dateTime().toString( "yyyy-MM-dd") new_item.isbn = self.isbn.text() # if len(new_item.isbn) != 13: # self.isbn.setStyleSheet('border-color:rgb(255,0,0') new_item.bid = self.bid.text() new_item.price = self.price.text() new_item.lang = LangEnum(self.lang.currentIndex() + 1) new_item.quarantine_start_date = self.__qsd new_item.quarantine_end_date = self.__qed new_item.rack = self.rack.text() new_item.shelf = self.shelf.text() new_item.position = self.position.text() new_item.availability = AvailabilityEnum( self.availability.currentIndex() + 1) new_item.cataloging_level = CatalogingLevel( self.cataloging_level.currentIndex()) new_item.publication_state = self.publication_state.currentIndex() new_item.opac_visibility = self.opac_visibility.currentIndex() new_item.note = self.note.toPlainText() new_item.genre = self.__im.get_genres(self.genre.checkedItems(1)) # if self.genre.checkedItems() == []: # self.genre.setStyleSheet('border-color:rgb(255,0,0)') new_item.inner_state = self.__im.get_inner_states( self.inner_state.checkedItems()) new_item.external_state = self.__im.get_external_states( self.external_state.checkedItems()) return new_item def __start_quarantine(self) -> None: self.__qsd = datetime.today().date() self.__qed = self.__qsd + timedelta(days=4) self.quarantine_due_time.setText(str(self.__qed - self.__qsd)) self.quarantine_end_date.setText(str(self.__qed)) self.availability.setCurrentIndex( AvailabilityEnum.in_quarantena.value - 1) def __save_button(self) -> None: if len(self.bid.text()) < 10 and len(self.bid.text()) > 0 and len( self.isbn.text()) < 13 and len(self.isbn.text()) > 0: src.Utils.UI.ErrorMessage("ISBN e BID troppo corti").exec_() return if len(self.isbn.text()) < 13 and len(self.isbn.text()) > 0: src.Utils.UI.ErrorMessage("ISBN troppo corto").exec_() return if len(self.bid.text()) < 10 and len(self.bid.text()) > 0: src.Utils.UI.ErrorMessage("BID troppo corto").exec_() return self.check_validators() if self.something_changed: if self.validators_status: if self.item.id is not None: self.__im.edit_item(self.__get_from_view()) else: self.__im.add_item(self.__get_from_view()) self.close() else: src.Utils.UI.ErrorMessage( "Non sono stati riempiti tutti i campi obbligatori! Ricontrollare." ).exec_() else: self.close() def check_validators(self): self.validators_status = None for validator in self.__field_with_validator: status = validator.validator().validate(validator.text(), 0) if validator.property( "isMandatory") and self.validators_status is not False: if status[0] == 2: self.validators_status = True else: self.validators_status = False def close(self) -> bool: self.item = None self.update() return super(CatalogingView, self).close() def something_changed_set(self): self.something_changed = True def show(self): self.load_item(self.item) super(CatalogingView, self).show()