def createView(self) -> IccView: checkView = CheckView() checkView.saveCallback = self.onSaveData jahrelist = BusinessLogic.inst().getExistingJahre(einausart.MIETE) if len(jahrelist) == 0: BusinessLogic.inst().createFolgejahrSet(self._currentYear) jahrelist.append(self._currentYear) checkView.setJahre(jahrelist) # neue CheckViews immer mit aktuellem Jahr/Monat curr = getCurrentYearAndMonth() checkView.setJahr(self._currentYear) checkView.setCheckMonat(self._currentCheckMonth) model: CheckTableModel = self.createModel(self._currentYear, self._currentCheckMonth) checkView.setModel(model) model.setSortable(True) checkView.setJahrChangedCallback(self.jahrChangedCallback) checkView.setCheckMonatChangedCallback(self.monatChangedCallback) tv = checkView.tableView self._tableContextMenu = TableCellActionHandler(tv) self._tableContextMenu.activateComputeSumAction() tv.setColumnHidden(0, True) tv.setColumnHidden(1, True) tv.setColumnHidden(2, True) tv.setColumnHidden(3, True) self._view = checkView self.implementSpecificFeatures(tv) return checkView
def _doCsvExport( self, dlg:IccDialog ): model: QAbstractItemModel = dlg.getView().getModel() try: BusinessLogic.inst().exportToCsv( model ) except Exception as ex: box = ErrorBox( "Export als .csv-Datei", str( ex ), "in MainController.exportToCsv()" ) box.exec_()
def onSubmitChanges(self, x: XSonstAus) -> bool: """ wird gerufen, wenn der Anwender OK im Edit-Feld-Bereich drückt. Die Änderungen werden dann geprüft und in die Auszahlungentabelle übernommen. :param x: :return: """ msg = self._validateEditFields(x) if len(msg) == 0: # das master-objekt könnte sich geändert haben - wir ermitteln vorsichtshalber die master_id x.master_id = BusinessLogic.inst().getMasteridFromMastername( x.master_name) self._view.getAuszahlungenTableView().model().updateOrInsert(x) self._view.clearEditFields() kreditoren = BusinessLogic.inst().getAlleKreditoren() self._view.setKreditoren(kreditoren) self._view.setSaveButtonEnabled(True) self._setChangedFlag(True) return True else: self._view.showException( "Validation Fehler", "Falsche oder fehlende Daten bei der Erfassung der Auszahlung", msg) return False
def onMasterobjektChanged(self, newname: str): """ User hat Masterobjekt geändert. Neue Mietobjekte-Liste holen. Eingestellten Kreditor und Buchungstext (Leistungsidentifikation) merken. Zum neuen Masterobjekte die passenden Kreditoren holen. Wenn in den neuen Kreditoren der vorher eingestellte Kreditor enthalten ist, diesen auswählen. Andernfalls eintragen. Vorher eingestellte Leistungsidentifikation eintragen. :param newname: :return: """ self._view.clearMietobjekte() mietobjekte = BusinessLogic.inst().getMietobjekte(newname) if len(mietobjekte) > 0: self._view.setMietobjekte(mietobjekte) # momentan eingestellten Kreditor und Leistungsidentifik. merken curr_kreditor = self._view.getCurrentKreditor() curr_leistident = self._view.getCurrentLeistungsidentifikation() self._view.clearKreditoren() kreditoren = BusinessLogic.inst().getKreditoren(newname) if len(kreditoren) > 0: self._view.setKreditoren(kreditoren) if len(curr_kreditor) > 0: self._view.setCurrentKreditor(curr_kreditor) if len(curr_leistident) > 0: self._view.setCurrentLeistungsidentifikation(curr_leistident)
def jahrChangedCallback(self, jahr: int): if jahr == self._currentYear: return eaart: einausart = self.getEinAusArt() if not BusinessLogic.inst().existsEinAusSet(eaart, jahr): BusinessLogic.inst().createFolgejahrSet(jahr) model = self.createModel(jahr, self._currentCheckMonth) self._dlg.getView().setModel(model) self._currentYear = jahr
def writeChanges( self, changes:Any=None ) -> bool: try: BusinessLogic.inst().saveNotizen( self._model ) self._view.setSaveButtonEnabled( False ) self._view.resetChangeFlag() return True except Exception as exc: self._view.showException( "Fehler beim Speichern", str( exc ) ) return False
def _getFolgeIntervall( self, x:XSollzahlung ) -> XSollzahlung or None: if BusinessLogic.inst().canCreateFolgeIntervallHausgeld( x ): xnew:XSollzahlung = self._tm.duplicate( x ) # xnew.von mit dem Monatsende des aktuellen Monats versorgen xnew.von = BusinessLogic.inst().getStartOfNextSollzahlungInterval( x.von ) return xnew else: self._view.showException( "Falsche Auswahl", "Folge-Intervall nicht möglich" ) return None
def kuendigeMietverhaeltnis(self, mv_id: str, kuendDatum: str) -> None: # Kündigung in der Datenbank durchführen try: BusinessLogic.inst().kuendigeMietverhaeltnis(mv_id, kuendDatum) self.mietverhaeltnisGekuendigt.emit(mv_id, kuendDatum) except Exception as ex: box = ErrorBox( "Kündigung hat nicht geklappt", "MiniKuendigungsController.kuendigeMietverhaeltnis()", str(ex)) box.exec_()
def __init__( self, win:IccMainWindow ): QObject.__init__( self ) self._mainwin:IccMainWindow = win datum, text = BusinessLogic.inst().getLetzteBuchung() win.setLetzteBuchung( datum, text ) win.setTabellenAuswahl( BusinessLogic.inst().getIccTabellen() ) win.setActionCallback( self.onMainWindowAction ) win.setShutdownCallback( self.onShutdown ) #win.bringDialogToFront.connect( self.onBringDialogToFront ) #win.showTableContent.connect( self.onShowTableContent ) self._mietverhaeltnisDlg:IccDialog = None self._mieteDlg:IccDialog = None self._hgvDlg:IccDialog = None self._sonstAusDlg:IccDialog = None self._oposDlg:IccDialog = None self._sollMietenDlg:IccDialog = None self._sollHausgeldDlg:IccDialog = None self._nkaDlg:IccDialog = None self._hgaDlg:IccDialog = None self._notizenDlg:IccDialog = None self._renditeDlg:IccDialog = None self._anlageVDlg:IccDialog = None self._mieterWechselDlg:IccDialog = None self._mietobjektDlg:IccDialog = None self._geschaeftsreiseDlg:IccDialog = None self._anlageVDlg:IccDialog = None self._mietverhaeltnisCtrl = MietverhaeltnisController() self._mietenCtrl:MietenController = MietenController() self._mietenCtrl.changedCallback = self.onViewChanged self._mietenCtrl.savedCallback = self.onViewSaved self._hgvCtrl:HGVController = HGVController() self._hgvCtrl.changedCallback = self.onViewChanged self._hgvCtrl.savedCallback = self.onViewSaved self._sonstAusCtrl:SonstAusController = SonstAusController() self._sonstAusCtrl.changedCallback = self.onViewChanged self._sonstAusCtrl.savedCallback = self.onViewSaved self._sollMietenCtrl = SollmietenController() self._sollHausgelderCtrl = SollHgvController() self._nkaCtrl = NkAbrechnungenController() self._hgaCtrl = HgAbrechnungenController() self._oposCtrl:OffenePostenController = OffenePostenController() self._notizenCtrl:NotizenController = NotizenController() self._renditeCtrl:RenditeController = RenditeController() self._anlageVCtrl: AnlageVController = None self._mieterWechselCtrl:MieterwechselController = None self._mietobjektCtrl:MietobjektController = None self._geschaeftsreiseCtrl:GeschaeftsreisenController = None self._nChanges = 0 # zählt die Änderungen, damit nach Speichern-Vorgängen das Sternchen nicht zu früh entfernt wird. self._x, self._y = 0, 0 self._provideSumFields()
def writeChanges(self, changes: Any = None) -> bool: if self._validate(): self._view.applyChanges() try: BusinessLogic.inst().saveMietverhaeltnis(self._mv) self._view.resetChangeFlag() return True except Exception as ex: self.showErrorMessage( "Mietverhältnis: Speichern fehlgeschlagen", str(ex)) return False return False
def _provideBuchungstexte(self, master_name: str, mobj_id: str, kreditor: str): buchungstexte = "" if master_name is None or master_name == "Haus": # kein Masterobjekt eingestellt buchungstexte = BusinessLogic.inst().getBuchungstexte(kreditor) else: if mobj_id: buchungstexte = BusinessLogic.inst( ).getBuchungstexteFuerMietobjekt(master_name, kreditor) if not buchungstexte: buchungstexte = BusinessLogic.inst( ).getBuchungstexteFuerMasterobjekt(master_name, kreditor) self._view.setLeistungsidentifikationen(buchungstexte)
def __init__(self, mainframe: MainFrame): self._mainframe = mainframe self._tree: NotesTree = mainframe.tree self._edi: NoteEditor = mainframe.edi self._edi.setCtrlSCallback(self.onCtrlS) self._status = mainframe.statusbar self._tree.setTreeCallback(self._treeCallback) self._mainframe.setToolActionCallback(self.toolActionCallback) self._folder_id_iid_ref: Dict = {0: ''} #key: id, value: iid self._note_id_iid_ref: Dict = {} #key: id, value: iid self._imgFolder: PhotoImage = None #= PhotoImage( file="/home/martin/Projects/python/notes/images/folder_16.png" ) self._imgNote: PhotoImage = None #= PhotoImage( file="/home/martin/Projects/python/notes/images/note_16.png" ) self._business = BusinessLogic() self._options = Options()
def _onDetaillierteAusgaben(self, action: QAction, point: QPoint, row: int): model: Rendite_ZahlungenTableModel = BusinessLogic.inst( ).getDetaillierteAuszahlungen(self._model, row, self._jahr) dlg = GenericTableViewDialog(model) dlg.setWindowTitle("Detaillierte Ausgaben") dlg.exec_()
def createView(self) -> QWidget: sausview = SonstigeAusgabenView() self._view = sausview sausview.setWindowTitle(self._title) jahre = BusinessLogic.inst().getExistingJahre( constants.einausart.MIETE) sausview.setBuchungsjahre(jahre) jahr = datetime.now().year sausview.setBuchungsjahr(jahr) self._adjustBuchungsjahr(jahr) ###self._setTitle( jahr ) ###self._jahr = jahr masterobjekte = BusinessLogic.inst().getMasterobjekte() sausview.setMasterobjekte(masterobjekte) kreditoren = BusinessLogic.inst().getAlleKreditoren() sausview.setKreditoren(kreditoren) if len(kreditoren) > 0: self._view.setKreditoren(kreditoren) sausview.setKostenarten(BusinessLogic.inst().getKostenartenLang()) ###sonstauslist = BusinessLogic.inst().getSonstigeAusgabenUndSummen( self._jahr ) ###tm = SonstAusTableModel( sonstauslist ) ###sausview.setAuszahlungenTableModel( tm ) #sausview.setSummen( summen ) tv = sausview.getAuszahlungenTableView() self._searchhandler = SearchHandler(tv) tcm = TableCellActionHandler(tv) tcm.addAction(self._computeSumAction, self._onComputeSum) tcm.addAction(self._duplicateAction, self._onDuplicateAuszahlung) tcm.addAction(self._deleteAction, self._onDeleteAuszahlung) tcm.addAction(self._showSausIdAction, self._onShowSausId) self._tableCellActionHandler = tcm ###tv.resizeColumnsToContents() ###tv.setSortingEnabled( True ) # Achtung: damit wirklich sortiert werden kann, muss die Sortierbarkeit im Model eingeschaltet werden ###tm.setSortable( True ) tv.clicked.connect(self.onAuszahlungenLeftClick) ## set callbacks: sausview.setBuchungsjahrChangedCallback(self.onBuchungsjahrChanged) sausview.setSaveActionCallback(self.onSave) sausview.setSearchActionCallback(self._searchhandler.onSearch) sausview.setDbSearchActionCallback(self._onDbSearch) sausview.setMasterobjektChangedCallback(self.onMasterobjektChanged) sausview.setMietobjektChangedCallback(self.onMietobjektChanged) sausview.setKreditorChangedCallback(self.onKreditorChanged) sausview.setSubmitChangesCallback(self.onSubmitChanges) return sausview
def _createEditViewAndDialog( self ): if not self._mobjList: dummy, self._mobjList = BusinessLogic.inst().getAllMietobjekte() self._view = GeschaeftsreiseEditView( self._mobjList, self._xgeschaeftsreise ) self._dlg = OkCancelDialog() self._dlg.addWidget( self._view, 1 ) self._dlg.setValidationFunction( self.validate ) self._dlg.setCancellationFunction( self.mayCancel )
def createView(self) -> QWidget: #zuerst über den Auswahldialog bestimmen, welche Daten für die View selektiert werden müssen mobj_id = self._mietobjektAuswahl.selectMietobjekt() if not mobj_id: return None busi: BusinessLogic = BusinessLogic.inst() self._mietobjekt = busi.getMietobjektExt(mobj_id) self._view = MietobjektView(self._mietobjekt) self._view.save.connect(self.writeChanges) return self._view
def createView( self ) -> QWidget: self._model = BusinessLogic.inst().getOposModel() v = OffenePostenView( self._model ) v.createOposSignal.connect( self.onCreateOffenerPosten ) v.editOposSignal.connect( self.onEditOffenerPosten ) v.deleteOposSignal.connect( self.onDeleteOffenerPosten ) v.saveChangesSignal.connect( self.onSaveChanges ) self._view = v return v
class FolderProvider: def __init__( self ): self._business = BusinessLogic() self._business.initDatabase() self._folder_id_iid_ref: Dict = { 0: '' } # key: id, value: iid self._folderImage = ImageFactory.getInstance().imgFolder def provideFolders( self, tree: NotesTree ) -> Dict: #key: id, value: iid folder_id_iid_ref: Dict = { 0: '' } self._provideFolders( tree, folder_id_iid_ref, 0, '' ) return folder_id_iid_ref def _provideFolders( self, tree:NotesTree, folder_id_iid_ref:Dict, parent_id:int, parent_iid:str ): folders: List[Tuple] = self._business.getFolders( parent_id ) for f in folders: id, parent_id, text = f iid = tree.addFolder( parent_iid, id, text, self._folderImage ) folder_id_iid_ref[id] = iid # each id could have subfolders: self._provideFolders( tree, folder_id_iid_ref, id, iid )
def createView( self ) -> QWidget: self._model = BusinessLogic.inst().getNotizenModel() v = NotizenView( self._model ) v.getNotizenTableViewWidget().createItem.connect( self.onCreateNotiz ) v.getNotizenTableViewWidget().editItem.connect( self.onEditNotiz ) v.getNotizenTableViewWidget().deleteItem.connect( self.onDeleteNotiz ) v.getNotizenTableViewWidget().getTableView().ctvDoubleClicked.connect( self.onEditNotiz ) v.saveNotiz.connect( self.onSaveNotizen ) self._model.setSortable( True ) v.setSaveButtonEnabled( False ) self._view = v return v
def _adjustBuchungsjahr(self, jahr: int): self._jahr = jahr self._title = "Rechnungen, Abgaben, Gebühren,... " + str(jahr) sonstauslist = BusinessLogic.inst().getSonstigeAusgabenUndSummen(jahr) tm = SonstAusTableModel(sonstauslist) self._view.setAuszahlungenTableModel(tm) tv = self._view.getAuszahlungenTableView() tv.resizeColumnsToContents() tv.setSortingEnabled( True ) # Achtung: damit wirklich sortiert werden kann, muss die Sortierbarkeit im Model eingeschaltet werden tm.setSortable(True)
def validateNotiz() -> bool: xcopy:XNotiz = edidlg.getEditor().getNotizCopyWithChanges() msg = BusinessLogic.inst().validateNotiz( xcopy ) if msg: # Validation nicht ok, denn es gibt eine Meldung. # Meldung ausgeben und Dialog offen lassen. self._view.showException( "Validierungsfehler", msg ) return False else: # Validation ok. Zurück zum Aufrufer. edidlg.getEditor().guiToData() return True
def setSumFields(self): try: sumMieten, sumAusgaben, sumHGV = BusinessLogic.inst().getSummen() except Exception as ex: sumMieten = 0 sumAusgaben = 0 sumHGV = 0 self._errorCallback(str(ex)) self.setSumMieten(sumMieten) self.setSumAusgaben(sumAusgaben) self.setSumHGV(sumHGV)
def selectMietobjekt(self) -> str: dlg = MietobjektAuswahldialog() crsr = QCursor.pos() dlg.move(crsr.x(), crsr.y()) itemtext_list, mobj_list = BusinessLogic.inst().getAllMietobjekte() dlg.appendItemList(itemtext_list) if dlg.exec_() == QDialog.Accepted: auswahl: List[Tuple] = dlg.getSelection() itemtext = auswahl[0][0] mobj_id = "" for n in range(len(itemtext_list)): if itemtext_list[n] == itemtext: mobj_id = mobj_list[n] return mobj_id raise Exception( "MietobjektAuswahl.selectMietobjekt: interner Fehler") return ""
def main(): root = Tk() root.title("Anlage V -- Dateneingabe und Erstellung") root.rowconfigure( 0, weight=1 ) root.columnconfigure( 0, weight=1 ) root.option_add('*Dialog.msg.font', 'Helvetica 11') frame:AnlageVFrame = AnlageVFrame( root ) frame.grid( row=0, column=0, sticky="nswe", padx=3, pady=3 ) busi:BusinessLogic = BusinessLogic() ctrl:Controller = Controller( frame, busi ) ctrl.startWork() root.mainloop() busi.terminate() print( "Database closed successfully")
def _onDbSearch(self, searchstring: str): def onSelected(indexes: List[QModelIndex]): if len(indexes) > 0: # übernehmen des selektierten XBuchungstextMatch in die Editfelder x: XBuchungstextMatch = matchModel.getXBuchungstextMatch( indexes[0].row()) self._view.provideEditFieldsPartly( (x.umlegbar > 0), x.master_id, x.master_name, x.mobj_id, x.kreditor, x.kostenart_lang, x.buchungstext) matchModel = BusinessLogic.inst().getBuchungstextMatches(searchstring) dlg = TableViewDialog(self._view) dlg.setModal(True) dlg.getTableView().setSelectionBehavior(QAbstractItemView.SelectRows) dlg.setTableModel(matchModel) dlg.setSelectedCallback(onSelected) dlg.show()
def onFrozenRightClick(self, point: QPoint): @Slot(str, str) def onGekuendigt(mv_id: str, datum: str): #Model aktualisieren model.setBis(index.row(), datum) tv = self._view.tableView #model = tv.getTableModel() model = tv.getModel() index = tv.indexAt(point) if not index.column() in (model.nameColumnIdx, model.sollColumnIdx): return mv_id = model.getId(index.row()) menu = QMenu(tv) if index.column() == model.nameColumnIdx: action = QAction("Dieses Mietverhältnis beenden") action.setData("K") menu.addAction(action) menu.addSeparator() action2 = QAction("Mietverhältnisdaten anzeigen") action2.setData("A") menu.addAction(action2) else: action = QAction("Nettomiete und NKV anzeigen") menu.addAction(action) action = menu.exec_(tv.viewport().mapToGlobal(point)) if action and index.column() == model.nameColumnIdx: if action.data() == "K": c = MiniKuendigungsController(self._view) c.mietverhaeltnisGekuendigt.connect(onGekuendigt) c.kuendigeMietverhaeltnisUsingMiniDialog(mv_id) else: self._showMietverhaeltnis(mv_id, point) elif action and index.column() == model.sollColumnIdx: netto, nkv = BusinessLogic.inst().getNettomieteUndNkv( mv_id, self._currentYear, self._currentCheckMonth) box = QMessageBox() box.setWindowTitle("Teile der Bruttomiete") box.setIcon(QMessageBox.Information) box.setText("Nettomiete:\t%.2f €\n\n" "Nebenkosten:\t%.2f €" % (netto, nkv)) box.exec_()
def showTableContent( self, table:str ): dictList = BusinessLogic.inst().getTableContent( table ) tm = DictListTableModel( dictList ) dlg = IccDialog( self._mainwin ) dlg.mayClose = lambda : 1 == 1 tv = CustomTableView() tv.setModel( tm ) tv.setFont( QFont( "Arial", 12 ) ) tv.resizeColumnsToContents() tv.resizeRowsToContents() tv.setSortingEnabled( True ) tm.setSortable( True ) tm.layoutChanged.connect( tv.resizeRowsToContents ) ## <======== WICHTIG bei mehrzeiligem Text in einer Zelle! dlg.setView( tv ) dlg.setWindowTitle( table ) w = 0 for c in range( tm.columnCount() ): w += tv.columnWidth( c ) self._showDialog( dlg, w, 900 )
def createView(self) -> QWidget: busi: BusinessLogic = BusinessLogic.inst() jahre = busi.getExistingJahre(einausart.MIETE) jahr = 0 if len(jahre) > 0: if len(jahre) > 1: jahr = jahre[ 1] # das aktuelle minus 1 - für das liegen die Daten komplett vor else: jahr = jahre[0] self._model = busi.getRenditeTableModel(jahr) v = RenditeView(self._model) v.setWindowTitle("Erträge der Objekte") v.setBetrachtungsjahre(jahre) v.setBetrachtungsjahr(jahr) v.betrachtungsjahrChanged.connect(self._onBetrachtungsjahrChanged) tv = v.getRenditeTableView() tv.detaillierteAusgabenSignal.connect(self._onDetaillierteAusgaben) tv.setAlternatingRowColors(True) tv.setSortingEnabled(True) self._model.setSortable(True) self._view = v self._jahr = jahr return v
def _dispatchSaveAction(self, actionstring: str, x: XSonstAus): try: idx = constants.actionList.index(actionstring) except: self._view.showException( "Internal Error", "SonstAusController._dispatchSaveAction(): unknown action '%s'" % (actionstring)) sys.exit() if idx == constants.tableAction.INSERT: try: BusinessLogic.inst().insertSonstigeAuszahlung(x) except Exception as e: self._view.showException( "SonstAusController._dispatchSaveAction()", "call BusinessLogic.inst().insertSonstigeAuszahlung(x)", str(e)) sys.exit() elif idx == constants.tableAction.UPDATE: try: BusinessLogic.inst().updateSonstigeAuszahlung(x) except Exception as e: self._view.showException( "SonstAusController._dispatchSaveAction()", "call BusinessLogic.inst().updateSonstigeAuszahlung(x)", str(e)) sys.exit() elif idx == constants.tableAction.DELETE: try: BusinessLogic.inst().deleteSonstigeAuszahlung(x) except Exception as e: self._view.showException( "SonstAusController._dispatchSaveAction()", "call BusinessLogic.inst().deleteSonstigeAuszahlung(x)", str(e)) sys.exit() else: self._view.showException( "SonstAusController._dispatchSaveAction(): known but unhandled action '%s'" % (actionstring)) sys.exit()
def __init__(self): ## ACHTUNG: in definitions.py zuerst ROOT auf ändern, # sonst werden die Änderungen in der Test-Datenbank eingetragen. # !!!!!!!!!!!!!!!UND DANN WIEDER ZURÜCK ÄNDERN!!!!!!!!!!!!! return ## AUSKOMMENTIEREN self._busi = BusinessLogic.inst()