def __init__(self, session, member, parent=None, ldapmanager=None): """Create the dialog and fill in the values from a member. session -- Sqlalchemy session. member -- backend.orm.Member to be edited. parent -- Parent for the QDialog """ self.parent = parent super().__init__() self.ui = Ui_MemberEdit() self.ui.setupUi(self) self.session = session self.member = self.session.query(Member).filter_by( objectId=member.objectId).one() self.ldapmanager = ldapmanager self.fillFields() self.setWindowTitle(self.member.getWholeName()) self.usernamevalidator = UsernameValidator(self.session, self) self.ui.username_fld.setValidator(self.usernamevalidator)
class MemberEdit(QWidget): """Dialog to edit almost every aspect of a member.""" def __init__(self, session, member, parent=None, ldapmanager=None): """Create the dialog and fill in the values from a member. session -- Sqlalchemy session. member -- backend.orm.Member to be edited. parent -- Parent for the QDialog """ self.parent = parent super().__init__() self.ui = Ui_MemberEdit() self.ui.setupUi(self) self.session = session self.member = self.session.query(Member).filter_by( objectId=member.objectId).one() self.ldapmanager = ldapmanager self.fillFields() self.setWindowTitle(self.member.getWholeName()) self.usernamevalidator = UsernameValidator(self.session, self) self.ui.username_fld.setValidator(self.usernamevalidator) def refreshUserAccounts(self): ldapuserexists = "Nej" billuserexists = "Nej" ldapcolor = "red" billcolor = "red" self.ui.removeAccountButton.setEnabled(False) self.ui.username_fld.setEnabled(True) self.ui.billAccountCreditLabel.setText("Icke tillgänglig") if self.ldapmanager.check_bill_account(self.member): billuserexists = "Ja" billcolor = "green" self.ui.billAccountCreditLabel.setText(str( self.ldapmanager.get_bill_balance(self.member)) + " €") if self.ldapmanager.checkldapuser(self.member): ldapuserexists = "Ja" ldapcolor = "green" self.ui.ldapGroupsLabel.setPlainText("\n".join(self.ldapmanager.getPosixGroups(self.member))) self.ui.removeAccountButton.setEnabled(True) self.ui.username_fld.setEnabled(False) self.ui.ldapAccountStatusLabel.setText(ldapuserexists) self.ui.billAccountStatusLabel.setText(billuserexists) stylesheet = "QLabel {color:%s}" % ldapcolor self.ui.ldapAccountStatusLabel.setStyleSheet(stylesheet) stylesheet = "QLabel {color:%s}" % billcolor self.ui.billAccountStatusLabel.setStyleSheet(stylesheet) def createAccountOrChangePassword(self): password, ok = QInputDialog.getText(self, "Ange lösenord", "Lösenord", QLineEdit.Password) if not ok: return password2, ok2 = QInputDialog.getText(self, "Lösenord igen", "Lösenord", QLineEdit.Password) if not ok2: return if password != password2: QMessageBox.information(self, "Åtgärden misslyckades!", "Lösenorden matchar inte.", QMessageBox.Ok) return send_password= (password + '.')[:-1] if QMessageBox.question(self, "Hemligt lösenord?", "Ett hemligt lösenord synns inte i mailet som skickas.", QMessageBox.Yes, QMessageBox.No) == QMessageBox.Yes: send_password = "******" if self.ldapmanager.checkldapuser(self.member): # Change only password if account exists self.ldapmanager.change_ldap_password(self.member.username_fld, password) self.refreshUserAccounts() mailutil.send_mail(self.ldapmanager.ps, self.ui.email_fld.text(), 'Ditt konto vid Teknologföreningen', 'Hejsan\n\nDitt lösenord vid Teknologföreningen har blivit bytt.\n\nDitt nya lösenord är: {:s}\n\nVid frågor eller ifall du inte begärt detta, kontakta [email protected]\n\nDetta är ett automatiskt meddelande, du behöver inte svara på det.'.format(send_password)) QMessageBox.information(self, "Lösenord bytt!", "Lösenordet skickat till användarens e-post.", QMessageBox.Ok) return username = self.ui.username_fld.text() email = self.ui.email_fld.text() preferredname = self.ui.preferredName_fld.text() surname = self.ui.surName_fld.text() if (username and email and preferredname and surname): if not self.member.ifOrdinarieMedlem(): if QMessageBox.question(self, "Skapa användarkonto?", "Användaren är inte ordinarie medlem, skapa konto ändå?", QMessageBox.Yes, QMessageBox.No) == QMessageBox.No: return self.member.username_fld = username self.member.email_fld = email self.member.preferredName_fld = preferredname self.member.surName_fld = surname self.session.commit() self.ldapmanager.addldapuser(self.member, password) self.refreshUserAccounts() mailutil.send_mail(self.ldapmanager.ps, self.member.email_fld, 'Ditt konto vid Teknologföreningen', 'Du har skapat ett konto till Teknologföreningens IT-system.\nDitt användarnamn är {:s}\noch ditt lösenord är {:s}\n\nGå in på http://bill.teknologforeningen.fi/code för att ta reda på din BILL-kod som du kan använda till kopiering o.dyl.\n\nLäs igenom reglerna för användandet av TF:s IT-tjänster på denna sida (fyll dock inte i blanketten; reglerna berör dig ändå):\nhttps://www.teknologforeningen.fi/index.php?option=com_content&view=article&id=115&Itemid=177&lang=sv\n\nKom ihåg att användarkonto och BILL-kod är ett privilegium, inte en rätt. De kan tas bort vid missbruk.\n\n/Infochefen & TF-IC'.format(username,send_password)) QMessageBox.information(self, "Användare skapad!", "Lösenordet skickat till användarens e-post.", QMessageBox.Ok) return QMessageBox.information(self, "Kunde inte skapa användarkonto", "Felaktigt användarnamn, email, efternamn eller tilltalsnamn", QMessageBox.Ok) def removeAccount(self): if QMessageBox.question(self, "Ta bort användarkonto?", "Är du säker att du vill radera användarkontot för användaren %s?" % self.member.username_fld + " BILL krediter kommer att bevaras.", QMessageBox.Yes, QMessageBox.No) == QMessageBox.Yes: self.ldapmanager.delldapuser(self.member) self.refreshUserAccounts() def fillFields(self): """Fill every widget with the corresponding values of a Member.""" for field in Member.editable_text_fields: fill_qlineedit_from_db(self.ui, field, self.member) self.ui.notes_fld.setPlainText(self.member.notes_fld) self.ui.dead_fld.setChecked(bool(self.member.dead_fld)) if self.member.birthDate_fld: self.ui.birthDate_fld.setDateTime(self.member.birthDate_fld) self.ui.subscribedToModulen_fld_checkbox.setChecked( bool(self.member.subscribedtomodulen_fld)) self.ui.noPublishContactInfo_fld_checkbox.setChecked( bool(self.member.noPublishContactInfo_fld)) init_gender_combobox(self.ui.gender_fld, self.member) # Contact information contactinfo = self.member.contactinfo for field in contactinfo.publicfields: fill_qlineedit_from_db(self.ui, field, contactinfo) mshipdelegate = MembershipDelegate() # Groups grouplistmodel = GroupListModel(self.session, self.member, self, self.ui.group_comboBox) self.ui.groupView.setModel(grouplistmodel) self.ui.groupView.setItemDelegate(mshipdelegate) self.ui.removeGroupButton.clicked.connect(lambda: self.removeSelectedMembership(self.ui.groupView)) grouplistmodel.rowsInserted.connect(lambda index, row: self.ui.groupView.edit(grouplistmodel.index(row))) # Posts postlistmodel = PostListModel(self.session, self.member, self, self.ui.post_comboBox) self.ui.postView.setModel(postlistmodel) self.ui.removePostButton.clicked.connect(lambda: self.removeSelectedMembership(self.ui.postView)) self.ui.postView.setItemDelegate(mshipdelegate) postlistmodel.rowsInserted.connect(lambda index, row: self.ui.postView.edit(postlistmodel.index(row))) # Departments departmentlistmodel = DepartmentListModel(self.session, self.member, self, self.ui.department_comboBox) self.ui.departmentView.setModel(departmentlistmodel) self.ui.removeDepartmentButton.clicked.connect(lambda: self.removeSelectedMembership(self.ui.departmentView)) self.ui.departmentView.setItemDelegate(mshipdelegate) # Memberships membershiplistmodel = MembershipListModel(self.session, self.member, self, self.ui.membership_comboBox) self.ui.membershipView.setModel(membershiplistmodel) self.ui.removeMembershipButton.clicked.connect(lambda: self.removeSelectedMembership(self.ui.membershipView)) self.ui.membershipView.setItemDelegate(mshipdelegate) self.ui.makePhuxButton.clicked.connect(lambda: membershiplistmodel.insertMembership("Phux")) self.ui.makeOrdinarieButton.clicked.connect(lambda: membershiplistmodel.insertMembership("Ordinarie medlem")) self.ui.makeActiveAlumnButton.clicked.connect(lambda: membershiplistmodel.insertMembership("Aktiv alumn")) self.ui.makeStAlMButton.clicked.connect(lambda: membershiplistmodel.insertMembership("StÄlM")) self.ui.makeJuniorStAlMButton.clicked.connect(lambda: membershiplistmodel.insertMembership("JuniorStÄlM")) self.ui.makeEjMedlemButton.clicked.connect(lambda: membershiplistmodel.insertMembership("Ej längre medlem")) # Optional LDAP-integration. self.ui.tabWidget.setTabEnabled(1, False) if self.ldapmanager: self.ui.createUserAccountOrChangePasswordButton.clicked.connect( lambda: self.createAccountOrChangePassword()) self.ui.removeAccountButton.clicked.connect(lambda: self.removeAccount()) self.ui.tabWidget.setTabEnabled(1, True) self.refreshUserAccounts() def removeSelectedMembership(self, listview): """Remove selected items from a QListView.""" selections = listview.selectedIndexes() for index in selections: listview.model().removeRow(index.row()) def accept(self): """Commit Member.*_fld and contactinfo.*_fld changes to database. Most notably all the QListView changes are already committed. """ for field in Member.editable_text_fields: if (field == "username_fld" and not self.ui.username_fld.hasAcceptableInput()): continue update_qtextfield_to_db(self.ui, field, self.member) self.member.notes_fld = str(self.ui.notes_fld.toPlainText()[:255]) self.member.gender_fld = self.ui.gender_fld.currentIndex() date = self.ui.birthDate_fld.dateTime().date() self.member.birthDate_fld = self.ui.birthDate_fld.dateTime( ).toPyDateTime() self.member.dead_fld = int(self.ui.dead_fld.isChecked()) self.member.subscribedtomodulen_fld = int( self.ui.subscribedToModulen_fld_checkbox.isChecked()) self.member.noPublishContactInfo_fld = int( self.ui.noPublishContactInfo_fld_checkbox.isChecked()) contactinfo = self.member.contactinfo for field in contactinfo.publicfields: update_qtextfield_to_db(self.ui, field, contactinfo) self.session.commit() self.parent.populateMemberList(choosemember=self.member) self.close() def reject(self): """Close the dialog without saving the fields to the database.""" #TODO: Also rollback the MembershipListView changes. self.session.rollback() self.close()
class MemberEdit(QWidget): """Dialog to edit almost every aspect of a member.""" def __init__(self, session, member, parent=None, ldapmanager=None): """Create the dialog and fill in the values from a member. session -- Sqlalchemy session. member -- backend.orm.Member to be edited. parent -- Parent for the QDialog """ self.parent = parent super().__init__() self.ui = Ui_MemberEdit() self.ui.setupUi(self) self.session = session self.member = self.session.query(Member).filter_by( objectId=member.objectId).one() self.ldapmanager = ldapmanager self.fillFields() self.setWindowTitle(self.member.getWholeName()) self.usernamevalidator = UsernameValidator(self.session, self) self.ui.username_fld.setValidator(self.usernamevalidator) def refreshUserAccounts(self): ldapuserexists = "Nej" billuserexists = "Nej" ldapcolor = "red" billcolor = "red" self.ui.removeAccountButton.setEnabled(False) self.ui.username_fld.setEnabled(True) self.ui.billAccountCreditLabel.setText("Icke tillgänglig") if self.ldapmanager.check_bill_account(self.member): billuserexists = "Ja" billcolor = "green" self.ui.billAccountCreditLabel.setText( str(self.ldapmanager.get_bill_balance(self.member)) + " €") if self.ldapmanager.checkldapuser(self.member): ldapuserexists = "Ja" ldapcolor = "green" self.ui.ldapGroupsLabel.setPlainText("\n".join( self.ldapmanager.getPosixGroups(self.member))) self.ui.removeAccountButton.setEnabled(True) self.ui.username_fld.setEnabled(False) self.ui.ldapAccountStatusLabel.setText(ldapuserexists) self.ui.billAccountStatusLabel.setText(billuserexists) stylesheet = "QLabel {color:%s}" % ldapcolor self.ui.ldapAccountStatusLabel.setStyleSheet(stylesheet) stylesheet = "QLabel {color:%s}" % billcolor self.ui.billAccountStatusLabel.setStyleSheet(stylesheet) def createAccountOrChangePassword(self): password, ok = QInputDialog.getText(self, "Ange lösenord", "Lösenord", QLineEdit.Password) if not ok: return password2, ok2 = QInputDialog.getText(self, "Lösenord igen", "Lösenord", QLineEdit.Password) if not ok2: return if password != password2: QMessageBox.information(self, "Åtgärden misslyckades!", "Lösenorden matchar inte.", QMessageBox.Ok) return send_password = (password + '.')[:-1] if QMessageBox.question( self, "Hemligt lösenord?", "Ett hemligt lösenord synns inte i mailet som skickas.", QMessageBox.Yes, QMessageBox.No) == QMessageBox.Yes: send_password = "******" if self.ldapmanager.checkldapuser(self.member): # Change only password if account exists self.ldapmanager.change_ldap_password(self.member.username_fld, password) self.refreshUserAccounts() mailutil.send_mail( self.ldapmanager.ps, self.ui.email_fld.text(), 'Ditt konto vid Teknologföreningen', 'Hejsan\n\nDitt lösenord vid Teknologföreningen har blivit bytt.\n\nDitt nya lösenord är: {:s}\n\nVid frågor eller ifall du inte begärt detta, kontakta [email protected]\n\nDetta är ett automatiskt meddelande, du behöver inte svara på det.' .format(send_password)) QMessageBox.information( self, "Lösenord bytt!", "Lösenordet skickat till användarens e-post.", QMessageBox.Ok) return username = self.ui.username_fld.text() email = self.ui.email_fld.text() preferredname = self.ui.preferredName_fld.text() surname = self.ui.surName_fld.text() if (username and email and preferredname and surname): if not self.member.ifOrdinarieMedlem(): if QMessageBox.question( self, "Skapa användarkonto?", "Användaren är inte ordinarie medlem, skapa konto ändå?", QMessageBox.Yes, QMessageBox.No) == QMessageBox.No: return self.member.username_fld = username self.member.email_fld = email self.member.preferredName_fld = preferredname self.member.surName_fld = surname self.session.commit() self.ldapmanager.addldapuser(self.member, password) self.refreshUserAccounts() mailutil.send_mail( self.ldapmanager.ps, self.member.email_fld, 'Ditt konto vid Teknologföreningen', 'Du har skapat ett konto till Teknologföreningens IT-system.\nDitt användarnamn är {:s}\noch ditt lösenord är {:s}\n\nGå in på http://bill.teknologforeningen.fi/code för att ta reda på din BILL-kod som du kan använda till kopiering o.dyl.\n\nLäs igenom reglerna för användandet av TF:s IT-tjänster på denna sida (fyll dock inte i blanketten; reglerna berör dig ändå):\nhttps://www.teknologforeningen.fi/index.php?option=com_content&view=article&id=115&Itemid=177&lang=sv\n\nKom ihåg att användarkonto och BILL-kod är ett privilegium, inte en rätt. De kan tas bort vid missbruk.\n\n/Infochefen & TF-IC' .format(username, send_password)) QMessageBox.information( self, "Användare skapad!", "Lösenordet skickat till användarens e-post.", QMessageBox.Ok) return QMessageBox.information( self, "Kunde inte skapa användarkonto", "Felaktigt användarnamn, email, efternamn eller tilltalsnamn", QMessageBox.Ok) def removeAccount(self): if QMessageBox.question( self, "Ta bort användarkonto?", "Är du säker att du vill radera användarkontot för användaren %s?" % self.member.username_fld + " BILL krediter kommer att bevaras.", QMessageBox.Yes, QMessageBox.No) == QMessageBox.Yes: self.ldapmanager.delldapuser(self.member) self.refreshUserAccounts() def fillFields(self): """Fill every widget with the corresponding values of a Member.""" for field in Member.editable_text_fields: fill_qlineedit_from_db(self.ui, field, self.member) self.ui.notes_fld.setPlainText(self.member.notes_fld) self.ui.dead_fld.setChecked(bool(self.member.dead_fld)) if self.member.birthDate_fld: self.ui.birthDate_fld.setDateTime(self.member.birthDate_fld) self.ui.subscribedToModulen_fld_checkbox.setChecked( bool(self.member.subscribedtomodulen_fld)) self.ui.noPublishContactInfo_fld_checkbox.setChecked( bool(self.member.noPublishContactInfo_fld)) init_gender_combobox(self.ui.gender_fld, self.member) # Contact information contactinfo = self.member.contactinfo for field in contactinfo.publicfields: fill_qlineedit_from_db(self.ui, field, contactinfo) mshipdelegate = MembershipDelegate() # Groups grouplistmodel = GroupListModel(self.session, self.member, self, self.ui.group_comboBox) self.ui.groupView.setModel(grouplistmodel) self.ui.groupView.setItemDelegate(mshipdelegate) self.ui.removeGroupButton.clicked.connect( lambda: self.removeSelectedMembership(self.ui.groupView)) grouplistmodel.rowsInserted.connect( lambda index, row: self.ui.groupView.edit(grouplistmodel.index(row) )) # Posts postlistmodel = PostListModel(self.session, self.member, self, self.ui.post_comboBox) self.ui.postView.setModel(postlistmodel) self.ui.removePostButton.clicked.connect( lambda: self.removeSelectedMembership(self.ui.postView)) self.ui.postView.setItemDelegate(mshipdelegate) postlistmodel.rowsInserted.connect( lambda index, row: self.ui.postView.edit(postlistmodel.index(row))) # Departments departmentlistmodel = DepartmentListModel(self.session, self.member, self, self.ui.department_comboBox) self.ui.departmentView.setModel(departmentlistmodel) self.ui.removeDepartmentButton.clicked.connect( lambda: self.removeSelectedMembership(self.ui.departmentView)) self.ui.departmentView.setItemDelegate(mshipdelegate) # Memberships membershiplistmodel = MembershipListModel(self.session, self.member, self, self.ui.membership_comboBox) self.ui.membershipView.setModel(membershiplistmodel) self.ui.removeMembershipButton.clicked.connect( lambda: self.removeSelectedMembership(self.ui.membershipView)) self.ui.membershipView.setItemDelegate(mshipdelegate) self.ui.makePhuxButton.clicked.connect( lambda: membershiplistmodel.insertMembership("Phux")) self.ui.makeOrdinarieButton.clicked.connect( lambda: membershiplistmodel.insertMembership("Ordinarie medlem")) self.ui.makeActiveAlumnButton.clicked.connect( lambda: membershiplistmodel.insertMembership("Aktiv alumn")) self.ui.makeStAlMButton.clicked.connect( lambda: membershiplistmodel.insertMembership("StÄlM")) self.ui.makeJuniorStAlMButton.clicked.connect( lambda: membershiplistmodel.insertMembership("JuniorStÄlM")) self.ui.makeEjMedlemButton.clicked.connect( lambda: membershiplistmodel.insertMembership("Ej längre medlem")) # Optional LDAP-integration. self.ui.tabWidget.setTabEnabled(1, False) if self.ldapmanager: self.ui.createUserAccountOrChangePasswordButton.clicked.connect( lambda: self.createAccountOrChangePassword()) self.ui.removeAccountButton.clicked.connect( lambda: self.removeAccount()) self.ui.tabWidget.setTabEnabled(1, True) self.refreshUserAccounts() def removeSelectedMembership(self, listview): """Remove selected items from a QListView.""" selections = listview.selectedIndexes() for index in selections: listview.model().removeRow(index.row()) def accept(self): """Commit Member.*_fld and contactinfo.*_fld changes to database. Most notably all the QListView changes are already committed. """ for field in Member.editable_text_fields: if (field == "username_fld" and not self.ui.username_fld.hasAcceptableInput()): continue update_qtextfield_to_db(self.ui, field, self.member) self.member.notes_fld = str(self.ui.notes_fld.toPlainText()[:255]) self.member.gender_fld = self.ui.gender_fld.currentIndex() date = self.ui.birthDate_fld.dateTime().date() self.member.birthDate_fld = self.ui.birthDate_fld.dateTime( ).toPyDateTime() self.member.dead_fld = int(self.ui.dead_fld.isChecked()) self.member.subscribedtomodulen_fld = int( self.ui.subscribedToModulen_fld_checkbox.isChecked()) self.member.noPublishContactInfo_fld = int( self.ui.noPublishContactInfo_fld_checkbox.isChecked()) contactinfo = self.member.contactinfo for field in contactinfo.publicfields: update_qtextfield_to_db(self.ui, field, contactinfo) self.session.commit() self.parent.populateMemberList(choosemember=self.member) self.close() def reject(self): """Close the dialog without saving the fields to the database.""" #TODO: Also rollback the MembershipListView changes. self.session.rollback() self.close()