示例#1
0
def test():
    from tkinter import Tk
    from tkinter import ttk
    #import sys
    #sys.path.append('/home/martin/Projects/python/mywidgets')
    try:
        from editabletable import GenericEditableTable, Mappings
    except ImportError:
        print("couldn't import editabletable.")

    dp = DataProvider()
    dp.connect('martin', 'fuenf55')
    root = root = Tk()

    tv = GenericEditableTable(root)
    tv.grid(column=0, row=0, sticky='nswe')
    ctrl = SonstEinAusController(dp, tv)
    ctrl.startWork()
    ctrl.wohnungSelected(1)

    values = {
        'vj': '2019',
        'betrag': '500',
        'art': 'Sonderumlage',
        'bemerkung': 'ohne Grund',
        'whg_id': 2
    }
    #ctrl._onEditRowAction(Action.OK, '', values, None)

    root.mainloop()
示例#2
0
 def __init__(self, mainWindow):
     self.__mainWindow = mainWindow
     self.__selectedWohnungItem = None
     self.__dataProvider = DataProvider()
     self.__rechnungController = None
     self.__mieteController = None
     self.__hausgeldController = None
示例#3
0
def test():
    dp = DataProvider()
    dp.connect('martin', 'fuenf55')

    root = Tk()
    root.rowconfigure(0, weight=1)
    root.columnconfigure(0, weight=1)

    style = ttk.Style()
    style.theme_use('clam')

    vc = VerwalterController(dp, root)
    vc.createVerwalter()

    root.mainloop()
示例#4
0
def test():
    from business import DataProvider, DataError
    dp = DataProvider()
    dp.connect('test')
    root = Tk()
    # root.rowconfigure(0, weight=1)
    # root.columnconfigure(0, weight=1)

    style = ttk.Style()
    style.theme_use('clam')

    stv = VeranlagungView(root)
    stv.grid(column=0, row=0, sticky='nswe', padx=10, pady=10)

    root.mainloop()
示例#5
0
def test():
    from business import DataProvider, DataError
    dp = DataProvider()
    dp.connect('martin', 'fuenf55')
    root = Tk()
    root.rowconfigure(0, weight=1)
    root.columnconfigure(0, weight=1)

    style = ttk.Style()
    style.theme_use('clam')

    stv = StammdatenView(root)
    stv.grid(column=0, row=0, sticky='nswe', padx=10, pady=10)
    # ctrl = GrundsteuerController(dp, tv)
    # ctrl.startWork()
    # ctrl.wohnungSelected(1)

    root.mainloop()
示例#6
0
def test():
    from business import DataProvider, DataError
    dp = DataProvider()
    dp.connect('test')
    root = Tk()
    root.rowconfigure(0, weight=1)
    root.columnconfigure(0, weight=1)

    style = ttk.Style()
    style.theme_use('clam')

    wv = WohnungDetailsView(root)
    wv.grid(column=0, row=0, sticky='nswe', padx=10, pady=10)

    ctrl = WohnungDetailsController(dp, wv)
    ctrl.startWork()
    ctrl.wohnungSelected(10)

    root.mainloop()
def test():
    from tkinter import Tk
    from tkinter import ttk

    dp = DataProvider()
    dp.connect('martin', 'fuenf55')

    root = root = Tk()

    style = ttk.Style()
    style.theme_use('clam')

    tv = StammdatenView(root)
    tv.grid(column=0, row=0, sticky='nswe', padx=10, pady=10)
    ctrl = StammdatenController(dp, tv)
    ctrl.startWork()
    #ctrl.wohnungSelected(1)

    root.mainloop()
def test():
    from tkinter import Tk
    from tkinter import ttk

    dp = DataProvider()
    dp.connect('test')
    #dp.connect('d02bacec')

    root = root = Tk()

    style = ttk.Style()
    style.theme_use('clam')

    tv = VeranlagungView(root)
    tv.grid(column=0, row=0, sticky='nswe', padx=10, pady=10)
    ctrl = VeranlagungController(dp, tv)
    ctrl.startWork()
    ctrl.wohnungSelected(1)  # dev: Mendel
    #ctrl.wohnungSelected(5) # rel: Heuschlag

    root.mainloop()
示例#9
0
                                 whg['whg_bez'] + ') erstellt.')
            except WvException as e:
                msg = 'Wohnung ' + str(whg_id) + ':\n' + e.message()
                raise WvException(e.rc(), msg)

        anlcreator.endCreate()
        self._savePath = anlcreator.getSavePath()
        self._doCallback('Alle Anlagen V im Verzeichnis ' +
                         anlcreator.getSavePath() + ' erstellt.')

    def getSavePath(self):
        return self._savePath

    def _doCallback(self, msg: str):
        if self._infoCallback:
            self._infoCallback(msg)


def info(msg: str) -> None:
    print('Batch says: ', msg)


if __name__ == '__main__':
    prov = DataProvider()
    prov.connect('d02bacec')
    whglist = prov.getWohnungsUebersicht()
    partlist = whglist[0:2]
    batch = AnlageVCreatorBatch(2018, prov, partlist)
    batch.registerInfoCallback(info)
    batch.startWork()
示例#10
0
class Controller():
    def __init__(self, mainWindow):
        self.__mainWindow = mainWindow
        self.__selectedWohnungItem = None
        self.__dataProvider = DataProvider()
        self.__rechnungController = None
        self.__mieteController = None
        self.__hausgeldController = None

    def initialize(self):
        self.__dataProvider.connect('martin', 'fuenf55')  #TODO: login dialog
        self.__rechnungController = RechnungController(self.__dataProvider)
        self.__mieteController = MieteController(self.__dataProvider)
        self.__hausgeldController = HausgeldController(self.__dataProvider)

        resp = self.__dataProvider.getWohnungsUebersicht()
        whg_list = json.loads(resp.content)
        whg_model = WohnungenModel(whg_list)
        self.__mainWindow.tvWohnungen.setModel(whg_model)
        self.__mainWindow.tvWohnungen.expandAll()

    def onNewRechnungClicked(self) -> None:
        #item = self.__getSelectedWohnungTreeItem()
        if self.__selectedWohnungItem is not None:
            whg_short_ident = self.__getWohnungIdentifikation(
                self.__selectedWohnungItem.id())
            newRechnung = Rechnung()
            newRechnung.setValue('whg_id', self.__selectedWohnungItem.id())
            try:
                self.__rechnungController.newRechnung(whg_short_ident,
                                                      newRechnung)
                self.__mainWindow.tblRechnungen.model().appendRow(newRechnung)
            except ServiceError as err:
                self.__mainWindow.showError(str(err.rc()), err.message())

    def onDeleteRechnungClicked(self) -> None:
        rechnungItem: TableItem = self.__getSelectedRechnungTableItem()
        if type(rechnungItem) == RechnungItem:
            rechnung = rechnungItem.rechnung()
            rg_id = rechnung.id()
            try:
                retval = self.__dataProvider.deleteRechnung(rg_id)
                self.__mainWindow.tblRechnungen.model().\
                    removeRow(rechnungItem.index().row())
            except ServiceError as err:
                self.__mainWindow.showError(str(err.message()['rc']),
                                            err.message()['msg'])

    '''
    a tree item has been selected.
    If this item is of type WohnungItem get data for all tabs
    '''

    def onWohnungenTreeClicked(self):
        self.__selectedWohnungItem = self.__getSelectedWohnungTreeItem()
        item = self.__selectedWohnungItem
        #self.__enableButtons( type( item ) == WohnungItem )
        if type(item) == WohnungItem:
            #provide data for wohnung details:
            self.__provideDetails(item)
            #provide data for rechnungen:
            self.__provideRechnungen(item)
            #provide data for miete tab:
            self.__provideMieteData(item)
            #provide data for hausgeld tab
            self.__provideHausgeldData(item)
            # todo: provide data for other tabs:
            # 3. provide data for sonstige ein-/auszahlungen tab
            # 4. provide data for mieter tab
        else:
            self.__selectedWohnungItem = None
            self.__clearMainWindow()

    '''
    on Rechnungen tab a year filter was set.
    check which one and hide rows not matching the
    year criterium
    '''

    def onRechnungenFilterChanged(self):
        self.__mainWindow.clearFilter()
        sel_item = self.__mainWindow.cboRechnungenFilter.currentText()
        try:
            year = int(sel_item)
            model = self.__mainWindow.tblRechnungen.model()
            rmax = model.rowCount()
            #get index of rg_datum column
            ##c = model.columnId('rg_datum')
            c = model.columnId('rg_bezahlt_am')
            #iterate over all rows and check dates in column 'rg_datum'
            rows = []
            for r in range(rmax):
                #rg_bezahlt_am = model.item(r, c).userData()['rg_bezahlt_am']
                rg_bezahlt_am = model.item(r, c).value('rg_bezahlt_am')
                if rg_bezahlt_am is not None and not rg_bezahlt_am.startswith(
                        sel_item):
                    rows.append(r)
            self.__mainWindow.hideTableRechnungenRow(rows)

        except ValueError:

            return

    def onRechnungenTableDblClicked(self) -> None:
        """
        a row in tblRechnungen has been double clicked.
        Open the Rechnung dialog for browsing or editing
        :return: None
        """
        rechnungItem = self.__getSelectedRechnungTableItem()
        rechnung = rechnungItem.rechnung()  #rechnung: list of RechnungItem

        #get Wohnung short identifikation:
        shortIdent = self.__getSelectedWohnungIdentifikation()

        if self.__rechnungController.editRechnung(shortIdent, rechnung):
            #force rechnungen table to refresh:
            #rechnungen = self.__mainWindow.tblRechnungen.model()
            #rechnungen.changeRechnung(rg)
            pass

        return

    def onTestClicked(self):
        self.dumpRechnungenModel()

    def onMietenEdit(self) -> None:
        """
        a row in tblMieten has been double clicked or
        button "Miete anpassen..." has been clicked.
        Miete table could be empty.
        Open the Miete dialog for browsing or editing
        :return:
        """
        # get Wohnung short identifikation:
        shortIdent = self.__getSelectedWohnungIdentifikation()

        row: DictTableRow = self.__getBestRow(self.__mainWindow.tblMieten)
        if row is not None:
            tableItem = row.getItem('miete_id')
            rowAbove = self.__getRowAbove('miete_id', tableItem.value(),
                                          self.__mainWindow.tblMieten)
        else:  #mietenTable is empty. row is still None
            #item = self.__getSelectedWohnungTreeItem()
            #item should always be of type WohnungsItem;
            #otherwise we wouldn't have a table to select in
            if self.__selectedWohnungItem is not None:
                whg_id = self.__selectedWohnungItem.id()

        try:
            if row is None:
                miete_row: DictTableRow = self.__mieteController.insertFirstMiete(
                    whg_id, shortIdent)

                #model = self.__mainWindow.tblMieten.model()
                #model.setColumnNames(miete_row.columnNames())
                #model.appendRow(miete_row)
            else:
                self.__mieteController.editMiete(shortIdent, row, rowAbove)
        except AbstractWvException as e:
            self.__mainWindow.showError(
                "WvException in Controller.onMietenEdit:\n", e.toString())

        self.__provideMieteData(self.__selectedWohnungItem)

        return

    def __getBestRow(self, table: QTableView) -> DictTableRow:
        """
        returns either the selected row or in case no row is selected
        the top row
        :param table: QTableView to get the row from
        :return: the best row or None if table is empty
        """
        row: DictTableRow = self.__getSelectedRow(table)
        if row is None:
            row = self.__getTopRow(table)
        return row

    def onDeleteMiete(self):
        row: DictTableRow = self.__getSelectedRow(self.__mainWindow.tblMieten)
        if row is not None:
            mieteItem: TableItem = row.getItem('miete_id')
            try:
                self.__mieteController.deleteMiete(mieteItem.intValue())
                # self.__mainWindow.tblMieten.model(). \
                #     removeRow(mieteItem.index().row())
            except AbstractWvException as e:
                self.__mainWindow.showError(
                    "WvException in Controller.onDeleteMiete:\n", e.toString())
            self.__provideMieteData(self.__selectedWohnungItem)

    def onNewHausgeld(self):
        if self.__selectedWohnungItem is not None:
            # get Wohnung short identifikation:
            shortIdent = self.__getSelectedWohnungIdentifikation()
            whg_id = self.__selectedWohnungItem.id()
            row: DictTableRow = self.__hausgeldController.newHausgeld(
                whg_id, shortIdent)
            #read table data again:
            self.__provideHausgeldData(self.__selectedWohnungItem)
            #model = self.__mainWindow.tblHausgeld.model()
            #model.setColumnNames(row.columnNames())
            #model.appendRow(row)

    def onEditHausgeld(self):
        # get Wohnung short identifikation:
        shortIdent = self.__getSelectedWohnungIdentifikation()
        row: DictTableRow = self.__getBestRow(self.__mainWindow.tblHausgeld)
        if row is None:
            return

        self.__hausgeldController.editHausgeld(shortIdent, row)
        #read table data again:
        self.__provideHausgeldData(self.__selectedWohnungItem)

    def onDeleteHausgeld(self):
        row: DictTableRow = self.__getBestRow(self.__mainWindow.tblHausgeld)
        if row is None:
            return

        self.__hausgeldController.deleteHausgeld(
            row.getItem('hausgeld_id').value())
        #read table data again:
        self.__provideHausgeldData(self.__selectedWohnungItem)

    def dumpRechnungenModel(self):
        model = self.__mainWindow.tblRechnungen.model()
        rmax = model.rowCount()
        cmax = model.columnCount()
        for r in range(rmax):
            for c in range(cmax):
                val = model.data(model.index(r, c))
                print(r, '/', c, ': ', val)

    def __provideDetails(self, whg_item) -> None:
        """
        provides data for details tab
        :param whg_item:
        :return:
        """
        whg = self.__dataProvider.getWohnungDetails(whg_item.id())
        if 200 != whg.status_code:
            self.__mainWindow. \
                showError('Failed getting Wohnung details',
                          'status_code=' + str(whg.status_code) + '\n' +
                          whg.content.decode(encoding='UTF-8'))
            return
        details = json.loads(whg.content)
        self.__whgData2Ui(details)

    def __provideRechnungen(self, whg_item):
        """
        provides data for the rechnungen tab, that means
        all rechnungen for tblRechnungen and a distinct list of years
        to be used by the RechnungenFilter combobox
        :param whg_item:
        :return:
        """
        resp = self.__dataProvider.getRechnungsUebersicht(whg_item.id())
        if 200 != resp.status_code:
            self.__mainWindow. \
                showError('Failed getting Rechnungsübersicht',
                          'status_code=' + str(resp.status_code) + '\n' +
                          resp.content.decode(encoding='UTF-8'))
            return
        rg_list = json.loads(resp.content)
        self.__rglistData2Ui(rg_list)

    def __provideMieteData(self, whg_item):
        """
        provides data for the miete tab (both latest and former data)
        :param whg_item:
        :return:
        """
        resp = self.__dataProvider.getMieteData(whg_item.id())
        miete_data = json.loads(resp.content)
        self.__mieteData2Ui(miete_data)

    def __provideHausgeldData(self, whg_item: WohnungItem) -> None:
        resp = self.__dataProvider.getHausgeldData(whg_item.id())
        hausgeld_data = json.loads(resp.content)
        self.__hausgeldData2Ui(hausgeld_data)

    def __getSelectedWohnungTreeItem(self) -> WohnungItem or None:
        """
        returns the selected tree item in tvWohnungen
        :return:
        """
        indexes = self.__mainWindow.tvWohnungen.selectedIndexes()
        if len(indexes) > 0:
            index = self.__mainWindow.tvWohnungen.selectedIndexes()[0]
            d = index.model().itemFromIndex(index)
            #print(d.data(Qt.DisplayRole))
            return d
        return None

    def __getSelectedRechnungTableItem(self):
        indexes = self.__mainWindow.tblRechnungen.selectedIndexes()
        if len(indexes) > 0:
            index = self.__mainWindow.tblRechnungen.selectedIndexes()[0]
            r = index.model().itemFromIndex(index)  #r is of  type RechnungItem
            return r
        return QVariant

    '''
    returns the selectedRow of the given QTableView
    '''

    def __getSelectedRow(self, tableView) -> DictTableRow:
        indexes = self.__mainWindow.tblMieten.selectedIndexes()
        if len(indexes) > 0:
            index = indexes[0]
            selRow = index.model().itemFromIndex(index).dictTableRow()
            return selRow
        return None

    def __getTopRow(self, tableView: QTableView) -> DictTableRow:
        model = tableView.model()
        if model.rowCount() > 0:
            index = model.index(0, 0)
            return model.itemFromIndex(index).dictTableRow()
        return None

    def __getRowAbove(self, key: str, value: str,
                      tableView: QTableView) -> DictTableRow:
        index = self.__getIndexFrom(key, value, tableView)
        if index is None:
            #todo: raise exception
            return None

        model = tableView.model()
        if index.row() == 0:
            return None

        indexAbove = model.index(index.row() - 1, 0)
        return model.itemFromIndex(indexAbove).dictTableRow()

    def __getIndexFrom(self, key: str, value: str, tableView: QTableView):
        model = tableView.model()
        rmax = model.rowCount()
        cmax = model.columnCount()
        for r in range(rmax):
            for c in range(cmax):
                item = model.item(r, c)
                if item.key() == key:
                    if item.value() == value:
                        index = model.indexFromItem(item)
                        r = index.row()
                        return index
        #todo: raise exception
        return None

    def __clearMainWindow(self):
        self.__clearMainWindow_(self.__mainWindow)

    def __clearMainWindow_(self, widget: QWidget) -> None:
        if isinstance(widget, QLineEdit):
            widget.clear()
        elif isinstance(widget, QSpinBox):
            widget.setValue(0)
        elif isinstance(widget, QPlainTextEdit):
            widget.setPlainText('')
        elif isinstance(widget, QCheckBox):
            widget.setChecked(False)
        elif isinstance(widget, QComboBox):
            widget.setCurrentIndex(0)
        elif isinstance(widget, QTableView):
            model = widget.model()
            model.clear()
        else:
            l = widget.children()
            for w in l:
                self.__clearMainWindow_(w)

    def __whgData2Ui(self, details):
        self.__mainWindow.inPlz.setText(details['plz'])
        self.__mainWindow.inOrt.setText(details['ort'])
        self.__mainWindow.inStrasse.setText(details['strasse'])
        self.__mainWindow.inWhgBez.setText(details['whg_bez'])
        self.__mainWindow.spinZimmer.setValue(int(details['zimmer']))
        self.__mainWindow.inQm.setText(details['qm'])
        cbo = self.__mainWindow.cboBalkon
        #allItems = [cbo.itemText(i) for i in range(cbo.count())]
        index = cbo.findText(details['balkon'], Qt.MatchFixedString)
        if index >= 0:
            cbo.setCurrentIndex(index)

        checked = details['ebk'] == 'J'
        self.__mainWindow.cbEbk.setChecked(checked)

        cbo = self.__mainWindow.cboHeizung
        index = cbo.findText(details['heizung'], Qt.MatchFixedString)
        if index >= 0:
            cbo.setCurrentIndex(index)

        self.__mainWindow.txtZusatz.setPlainText(details['zusatz'])

        checked = details['tageslichtbad'] == 'J'
        self.__mainWindow.cbTageslicht.setChecked(checked)

        checked = details['dusche'] == 'J'
        self.__mainWindow.cbDusche.setChecked(checked)

        checked = details['badewanne'] == 'J'
        self.__mainWindow.cbWanne.setChecked(checked)

        checked = details['bidet'] == 'J'
        self.__mainWindow.cbBidet.setChecked(checked)

        checked = details['kellerabteil'] == 'J'
        self.__mainWindow.cbKeller.setChecked(checked)

        checked = details['aufzug'] == 'J'
        self.__mainWindow.cbAufzug.setChecked(checked)

        cbo = self.__mainWindow.cboGarage
        index = cbo.findText(details['garage'], Qt.MatchFixedString)
        if index >= 0:
            cbo.setCurrentIndex(index)

        self.__mainWindow.txtBemerk.setPlainText(details['bemerkung'])

    def __rglistData2Ui(self, rg_list):
        win = self.__mainWindow
        rechnungen = RechnungenModel(rg_list)
        win.tblRechnungen.setModel(rechnungen)
        win.tblRechnungen.resizeColumnsToContents()
        #hide rechnung id:
        win.tblRechnungen.setColumnHidden(0, True)

        # TEST
        #self.dumpRechnungenModel()
        # TEST
        #provide distinct years for filter purposes:
        s = set()
        for rg in rg_list:
            #s.add(rg['rg_datum'][:4])
            if rg['rg_bezahlt_am'] is not None:
                s.add(rg['rg_bezahlt_am'][:4])
        s = sorted(s)
        l = []
        l.append("Kein Jahresfilter")
        for item in s:
            l.append(item)
        win.cboRechnungenFilter.clear()
        win.cboRechnungenFilter.addItems(l)

    def __mieteData2Ui(self, miete_data):
        win = self.__mainWindow
        model = DictListTableModel(miete_data)
        win.tblMieten.setModel(model)
        #hide columns whg_id and miete_id:
        win.tblMieten.setColumnHidden(0, True)
        win.tblMieten.setColumnHidden(1, True)

    def __hausgeldData2Ui(self, hausgeld_data: List[Dict]):
        win = self.__mainWindow
        model = DictListTableModel(hausgeld_data)
        win.tblHausgeld.setModel(model)
        #hide columns whg_id and miete_id:
        win.tblHausgeld.setColumnHidden(0, True)
        win.tblHausgeld.setColumnHidden(1, True)
        #win.tblHausgeld.setColumnWidth(2, 100)
        #win.tblHausgeld.setColumnWidth(3, 100)
        win.tblHausgeld.setColumnWidth(4, 150)
        win.tblHausgeld.setColumnWidth(5, 130)
        win.tblHausgeld.setColumnWidth(6, 130)

    def __getSelectedWohnungIdentifikation(self) -> str:
        #whg = self.__getSelectedWohnungTreeItem()
        if self.__selectedWohnungItem is not None:
            return self.__getWohnungIdentifikation(
                self.__selectedWohnungItem.id())

    def __getWohnungIdentifikation(self, whg_id) -> str:
        resp = self.__dataProvider.getWohnungIdentifikation(whg_id)
        if 200 != resp.status_code:
            self.__mainWindow. \
                showError('Failed getting Wohnung details',
                          'status_code=' + str(resp.status_code) + '\n' +
                          resp.content.decode(encoding='UTF-8'))
            return
        dict = json.loads(resp.content)

        line1 = dict.get('plz')
        line1 += ' '
        line1 += dict.get('ort')

        line2 = dict.get('strasse')
        line2 += ' / '
        line2 += dict.get('whg_bez')

        ident = '<html><head/><body><p><span style=" font-weight:600; color:#204a87;">'
        ident += line1
        ident += '<br>'
        ident += line2
        ident += '</span></p></body></html>'

        return ident