def set_new_file_location(self): ans = ask_user( self, "This will let 'B Z M A N' set a new path to your exisiting company database. " + "This means you will be able to open files that you have moved to a new location after saving them.\n\n" + "If you want to continue, click 'Ok'. If you want to exit, click 'Cancel'." ) if ans == QMessageBox.Ok: filename = QFileDialog.getOpenFileName( self, "Open", self.BZMAN_settings['path'], filter="Database Files (*.json)")[0] if filename: new_path, new_filename = os.path.split(filename) new_company_name = ",".join( os.path.split( os.path.splitext(filename)[0])[1].split('_')[:-2]) self.BZMAN_settings['path'] = new_path self.BZMAN_settings['database_name'] = new_filename self.BZMAN_settings['company'] = new_company_name write_file(self.BZMAN_settings, self.ctx.get_settings_file) inform_user( self, "New path to the company database has been set. You can now open the database using 'Open'" ) else: inform_user(self, "Select a valid database file")
def enter_company_name(self): dlg = QInputDialog(self) dlg.setInputMode(QInputDialog.TextInput) dlg.setWindowTitle('Enter Company Name') dlg.setLabelText('Company Name') line_edit = dlg.findChild( QLineEdit) # search Qlineedit child to set QCompleter completer = QCompleter(self._company_list_for_quick_actions, line_edit) completer.setCaseSensitivity(Qt.CaseInsensitive) line_edit.setCompleter(completer) dlg.resize(800, 100) ok = dlg.exec_() company_name = dlg.textValue() if ok and company_name: if company_name in self._company_list_for_quick_actions: return self._company_list_for_quick_actions.index(company_name) elif not company_name in self._company_list_for_quick_actions: inform_user( self, "This company name does not exist in database.\n\nIf this is a new customer, please use the 'Create New Customer' option." ) elif ok and not company_name: inform_user(self, "Please enter a valid company name")
def reload(self): # Set 'new' previous_data after reload, populate widgets and then collect widget data to set 'new_data' # This will set previous_data equal to new_data after reload self.previous_data = self._get_data() self.populate_view(data=self.previous_data) self._collect_widget_data() inform_user( self, "Entry updated. You may now reload using 'Reload' option.")
def delete_entry(self): answer = QMessageBox.question( self, None, "Are you sure you want to delete the entry? This can not be undone!", QMessageBox.Ok | QMessageBox.Cancel) if answer & QMessageBox.Ok: data_pkl = read_file(self.database_filename) data_pkl.pop(int(self.idx_no)) write_file(data_pkl, self.database_filename) inform_user(self, "Entry Deleted! You may now reload.")
def _new_file_logic(self): dlg = QInputDialog(self) dlg.setInputMode(QInputDialog.TextInput) dlg.setWindowTitle('New Database : Enter Your Company Name') dlg.setLabelText('Company Name') dlg.resize(self.ctx.available_geo().width() / 3.42, self.ctx.available_geo().height() / 17.44) ok = dlg.exec_() filename = dlg.textValue() if ok and filename: self.BZMAN_settings['company'] = filename self.BZMAN_settings[ 'database_name'] = filename + "_BZMAN_DATABASE.json" filename = os.path.join(self.folder_path + "/" + filename) self.database_filename = filename + "_BZMAN_DATABASE.json" new_database = list() write_file(new_database, self.database_filename) write_file(self.BZMAN_settings, self.ctx.get_settings_file) ans = inform_user( self, "Great! Company database created!\n\n" + "Click 'Ok' to open it.") if ans == QMessageBox.Ok: self.load_file() ans = ask_user( self, "There are no entries in your company database.\n\n" + "You can now add a new customer by clicking on 'Create New Customer' option in the top left or by clicking 'Ok'.\n" ) if ans == QMessageBox.Ok: self.entry_panel = EntryPanel(self.database_filename, self.ctx) self.entry_panel.show() #move this after opening file elif ok and not filename: inform_user(self, "Company name was left blank. \nEnter a valid name.") self._new_file_logic() else: self.BZMAN_settings["path"] = "" write_file(self.BZMAN_settings, self.ctx.get_settings_file)
def show_active_invoices_frm_payment(self): active_invoice_list = InvoiceListDialog(self) # BUG TODO when called from exec_, can't scroll or in child widgets like tree widget active_invoice_list._invoice_list_view.doubleClicked.connect( self._on_invoice_double_click) try: if len(self._invoice_iterator()[1]) > 0: for i in range(len(self._invoice_iterator()[1])): item = QStandardItem( self._invoice_iterator()[1][i]["Invoice No"]) active_invoice_list._invoice_model.appendRow(item) active_invoice_list.exec_() except TypeError: inform_user( self, "No invoices for this company. You can create one using 'New Invoice'" ) else: #BUG TODO - no message is popped if there are no active invoices inform_user(self, "No active invoices for this company")
def new_file(self, called_from_tutorial=False): self.BZMAN_settings = read_file(self.ctx.get_settings_file) if self.BZMAN_settings["path"] == "": inform_user( self, "Welcom to BZMAN! \n\n" + "Please select a folder to save your company database.") self.folder_path = QFileDialog.getExistingDirectory( self, 'Select a folder to save your database') if self.folder_path: self.BZMAN_settings["path"] = self.folder_path self._new_file_logic() else: inform_user(self, "No folder location selected.") else: ans = ask_user( self, "Company database already exists.\n\n" + "Do you still want to create a new database?\n\n") if ans == QMessageBox.Ok: self.BZMAN_settings["path"] = "" write_file(self.BZMAN_settings, self.ctx.get_settings_file) inform_user( self, "Your old database will now need to be manually opened using 'Open'\n\n" + "You may now create a new database") self.new_file()
def _collect_widget_data(self): company_name = self.panel_entry[0].ledit.text() if company_name != "": contact_name = self.panel_entry[1].ledit.text() address = self.panel_entry[2].tedit.toPlainText() email = self.panel_entry[3].ledit.text() phone_no = self.panel_entry[4].ledit.text() fax_no = self.panel_entry[5].ledit.text() total_business = 0 total_paid = 0 outstanding = 0 details = self.panel_entry[7].tedit.toPlainText() extra_details_textEdit = self.extra_details_textEdit.toPlainText() # # Read in database file to write in data_pkl = read_file(self.database_filename) self.idx_no = len( data_pkl ) # for setting invoice through entry panel, otherwise there is no reference of index no in entry panel data_dict = { "Company Name": company_name, "Contact Name": contact_name, "Address": address, "Email": email, "Phone No.": phone_no, "Fax No.": fax_no, "Total Business": total_business, "Total Paid": total_paid, "Outstanding": outstanding, "Details": details, "Invoices": {}, "Price Quote Log": extra_details_textEdit } data_pkl.append(data_dict) return data_pkl else: #return None if company_name is left blank inform_user(self, "Please enter a company name.") return None
def _replace_data(self): company_name, contact_name, address, email, phone_no, fax_no, details, extra_details_textEdit = self.new_data if company_name != "": data_pkl = read_file(self.database_filename) data_pkl[int(self.idx_no)]["Company Name"] = company_name data_pkl[int(self.idx_no)]["Contact Name"] = contact_name data_pkl[int(self.idx_no)]["Address"] = address data_pkl[int(self.idx_no)]["Email"] = email data_pkl[int(self.idx_no)]["Phone No."] = phone_no data_pkl[int(self.idx_no)]["Fax No."] = fax_no data_pkl[int(self.idx_no)]["Details"] = details data_pkl[int( self.idx_no)]["Price Quote Log"] = extra_details_textEdit return data_pkl else: #return None if company_name is left blank inform_user(self, "Please enter a company name.") return None
def open_payment_dialog(self): try: # Get active invoice numbers only from complete active invoices complete_active_invoices = self._invoice_iterator()[1] active_invoice_numb_only = [] for i in range(len(complete_active_invoices)): active_invoice_numb_only.append( complete_active_invoices[i]["Invoice No"]) if active_invoice_numb_only: new_payment_dialog = PaymentDialog(self) new_payment_dialog.setWindowTitle( "New Payment for " + str(self.panel_entry[0].ledit.text())) new_payment_dialog.item_0.comboBox.addItems( active_invoice_numb_only) ok = new_payment_dialog.exec_() if ok and new_payment_dialog.item_3.spin_box.value() != 0: if new_payment_dialog.payment_entry_widget.radio_button1.isChecked( ): payment_method = new_payment_dialog.payment_entry_widget.radio_button1.text( ) bank_name = None cheque_no = None elif new_payment_dialog.payment_entry_widget.radio_button2.isChecked( ): payment_method = new_payment_dialog.payment_entry_widget.radio_button2.text( ) bank_name = new_payment_dialog.payment_entry_widget.bank_name.ledit.text( ) cheque_no = new_payment_dialog.payment_entry_widget.cheque_no.ledit.text( ) remarks = new_payment_dialog.payment_entry_widget.remarks.tedit.toPlainText( ) success = write_new_payment( self, self.database_filename, self.idx_no, str(new_payment_dialog.item_0.comboBox.currentText()), float(new_payment_dialog.item_3.spin_box.value()), str(new_payment_dialog.item_4.calendar.selectedDate(). toString()), payment_method, bank_name, cheque_no, remarks) if success is True: self.reload() if success == 3: self.open_payment_dialog() elif ok and new_payment_dialog.item_3.spin_box.value() == 0: inform_user( self, "Payment amount was '0'. Ener a valid payment amount") self.open_payment_dialog() else: inform_user(self, "There are no active invoices for this compnay") except TypeError: inform_user(self, "There are no invoices for this company")
def open_invoice_dialog(self): new_invoice_dialog = InvoiceDialog(self) new_invoice_dialog.setWindowTitle( 'New invoice for ' + str(self.panel_entry[0].ledit.text())) ok = new_invoice_dialog.exec_() if ok and new_invoice_dialog.item_1.ledit.text( ) and new_invoice_dialog.item_3.spin_box.value() != 0: # TODO add to database write_invoice_to_file( self, self.database_filename, self.idx_no, str(new_invoice_dialog.item_1.ledit.text()), str(new_invoice_dialog.item_2.ledit.text()), float(new_invoice_dialog.item_3.spin_box.value()), str(new_invoice_dialog.item_4.calendar.selectedDate().toString( ))) self.reload() elif ok and not new_invoice_dialog.item_1.ledit.text( ) and new_invoice_dialog.item_3.spin_box.value() == 0: inform_user( self, "Invoice field was left empty or Amount was 0.\n\n" + "No new invoice was created.") self.open_invoice_dialog()
def __init__(self, ctx, *args, **kwargs): super().__init__() self.ctx = ctx # remove trial checks # self.check_trial_validity() self.setWindowTitle("Welcome to BZMAN!") version_no = self.ctx.build_settings['version'] text = "<center>" \ "<br><br><h1></h1>" \ "⁣" \ "<img src=%r>" \ "</center>" \ "<p>BZMAN</p>"\ % self.ctx.get_logo#<br/>" \ # "Copyright © JSS Inc.</p>" # text = QPixmap().setPixmap(self.ctx.get_logo) # text += "\nBZMAN\n" text += "Version " + version_no label = QLabel(text) # label.setPixmap(QPixmap(self.ctx.get_logo)) # label.setText("\nVersion "+version_no) # label.setMaximumSize(self.ctx.available_geo().width()/2,self.ctx.available_geo().height()/1.5) label.setAlignment(Qt.AlignCenter) # label.setFixedSize(self.ctx.available_geo().width()/5,self.ctx.available_geo().height()/5) hbox = QHBoxLayout() btn_new = QPushButton(" New ") btn_new.setMaximumSize(self.ctx.available_geo().width() / 9.12, self.ctx.available_geo().height() / 17.44) # btn_new.setStyleSheet("QPushButton {border-radius: 20px;}") btn_new.clicked.connect(self.new_file) hbox.addWidget(btn_new) btn_open = QPushButton(" Open ") btn_open.setMaximumSize(self.ctx.available_geo().width() / 9.12, self.ctx.available_geo().height() / 17.44) # btn_open.setStyleSheet("QPushButton {border-radius: 20px;}") btn_open.clicked.connect(self.load_file) hbox.addWidget(btn_open) hbox_widget = QWidget() hbox_widget.setLayout(hbox) container = QWidget() container_layout = QVBoxLayout() container_layout.addWidget(label) container_layout.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding)) container_layout.addWidget(hbox_widget) container.setLayout(container_layout) self.setCentralWidget(container) # toolbar = QToolBar("My Toolbar") # toolbar.setIconSize(QSize(30,30)) # self.addToolBar(toolbar) new_action = QAction("New", self) new_action.setStatusTip("Create a new file") new_action.triggered.connect(self.new_file) new_action.setShortcut(QKeySequence.New) # toolbar.addAction(new_action) # toolbar.addSeparator() load_action = QAction("Open", self) load_action.setStatusTip("Open an existing file") load_action.triggered.connect(self.load_file) load_action.setShortcut(QKeySequence.Open) # toolbar.addAction(load_action) load_demo = QAction("Open Demo", self) load_demo.setStatusTip("Open demo file") load_demo.triggered.connect(self.load_demo) set_new_file_path = QAction("Set New Path", self) set_new_file_path.setStatusTip("Sets a new path for an existing file") set_new_file_path.triggered.connect(self.set_new_file_location) dark_theme = QAction("Dark", self) dark_theme.triggered.connect(self.change_theme) breeze_dark = QAction("Breeze Dark", self) breeze_dark.triggered.connect(self.change_dark_breeze_theme) breeze_light = QAction("Light", self) breeze_light.triggered.connect(self.change_light_theme) blue = QAction("Blue", self) blue.triggered.connect(self.change_blue_theme) font = QAction("Fonts", self) font.triggered.connect(self.font_choice) self.setStatusBar(QStatusBar(self)) menu = self.menuBar() menu_font_size = menu.font() menu_font_size.setPointSize(10) menu.setFont(menu_font_size) menu.setNativeMenuBar(False) # for mac file_menu = menu.addMenu("&File") file_menu.setFont(menu_font_size) file_menu.addAction(new_action) file_menu.addAction(load_action) file_menu.addAction(load_demo) file_menu.addAction(set_new_file_path) options = menu.addMenu("&Customize") options.setFont(menu_font_size) theme = options.addMenu("Theme") theme.setFont(menu_font_size) theme.addAction(dark_theme) theme.addAction(breeze_dark) theme.addAction(breeze_light) theme.addAction(blue) options.addAction(font) # self.setGeometry(800,100,2000*self.devicePixelRatio(),1000*self.devicePixelRatio()) self.setWindowState(Qt.WindowMaximized) self.centerOnScreen() self.BZMAN_settings = read_file(self.ctx.get_settings_file) if self.BZMAN_settings['path'] != "": self.load_file() else: self.show() inform_user( self, "Welcom to BZMAN! \n\n" + "Click on the 'New' button to begin.")
def load_file(self): self.BZMAN_settings = read_file(self.ctx.get_settings_file) if self.BZMAN_settings['path'] == "": inform_user( self, "There is no database location specified.\n\n" + "If you haven't created a database, create a new database using 'New'\n\n" + "If you have recently moved the file to a new location, use the 'Set New Path' option in File menu to set the new file location" ) else: try: # x = [os.path.abspath(f) for f in os.listdir(self.BZMAN_settings['path']) if os.path.isfile(f)] x = os.listdir(self.BZMAN_settings['path']) temp_list = [] filename = None for i in range(len(x)): if x[i].find("_BZMAN_DATABASE.json") != -1: temp_list.append(x[i]) if len(temp_list) > 1: inform_user( self, "There are more than one database files. Please select the one you want to open" ) filename = QFileDialog.getOpenFileName( self, "Open", self.BZMAN_settings['path'], filter="Database Files (*.json)")[0] elif len(temp_list) == 0: ans = ask_user( self, "No Company Database found! \n\n" + "If you haven't created a company database yet, you can do it using 'New' option. Click 'Ok' to create a new database.\n\n" + "If you have already created a Database but moved it to a differenct location, please open it manually by clicking 'Cancel'." ) if ans == QMessageBox.Ok: self.new_file() elif ans == QMessageBox.Cancel: filename = QFileDialog.getOpenFileName( self, "Open", self.BZMAN_settings['path'], filter="Database Files (*.json)")[0] if filename: ans = ask_user( self, "Do you want to save this file location for future use? This will overwrite your existing path where the file wasn't found." ) if ans == QMessageBox.Ok: new_path, new_filename = os.path.split( filename) new_company_name = " ".join( os.path.split( os.path.splitext(filename)[0]) [1].split('_')[:-2]) self.BZMAN_settings['path'] = new_path self.BZMAN_settings[ 'database_name'] = new_filename self.BZMAN_settings[ 'company'] = new_company_name write_file(self.BZMAN_settings, self.ctx.get_settings_file) else: #4194304 pass else: filename = os.path.join(self.BZMAN_settings['path'] + '/' + temp_list[0]) if filename: self._open_main_window(filename) except OSError: #TODO maybe set the file path to ""; if file can not be found inform_user( self, "The database folder has been moved or deleted! If moved, use 'Open' or 'Set New Path'" )