Ejemplo n.º 1
0
def make_header_model(titles,headers=None):
    if headers is None:
        headers = QStandardItemModel(1, len(titles))

    i = 0
    for p in titles:
        headers.setHeaderData(i, Qt.Orientation.Horizontal, p)
        i = i + 1
    return headers
Ejemplo n.º 2
0
    def refresh_action(self):
        global dao

        # mainlog.debug("refresh action started")
        self.hours_per_pers_subframe.set_title(date_to_my(
            self.base_date, True))

        chrono.chrono_start()
        all_events_in_month = people_admin_service.events_for_month(
            self.base_date)

        employee_with_events = [
            event.employee_id for event in all_events_in_month
        ]

        # mainlog.debug(all_events_in_month)

        self.all_events_in_year = people_admin_service.events_for_year(
            self.base_date.year)
        self.all_presences = all_presences = dao.employee_dao.presence_overview_for_month(
            self.base_date)

        all_correction_times = dict()
        for s in dao.month_time_synthesis_dao.load_all_synthesis(
                self.base_date.year, self.base_date.month):
            all_correction_times[s.employee_id] = s.correction_time

        special_activities = dao.special_activity_dao.find_on_month(
            self.base_date)

        employees = list(
            filter(
                lambda e: e.is_active or e.employee_id in all_presences or e.
                employee_id in all_correction_times or e.employee_id in
                special_activities or e.employee_id in employee_with_events,
                dao.employee_dao.list_overview()))
        self.employees = employees

        chrono.chrono_click()

        day_max = calendar.monthrange(self.base_date.year,
                                      self.base_date.month)[1]
        t_start = datetime(self.base_date.year, self.base_date.month, 1)
        t_end = datetime(self.base_date.year, self.base_date.month, day_max,
                         23, 59, 59, 999999)

        self._table_model.setRowCount(len(employees))
        self._table_model.setColumnCount(1 + day_max + 3)

        headers = QStandardItemModel(1, 1 + day_max + 3)

        headers.setHeaderData(0, Qt.Orientation.Horizontal, _("Employee"))
        for i in range(day_max):
            headers.setHeaderData(i + 1, Qt.Orientation.Horizontal,
                                  "{}".format(i + 1))
        headers.setHeaderData(day_max + 1, Qt.Orientation.Horizontal,
                              _("Correction"))
        headers.setHeaderData(day_max + 2, Qt.Orientation.Horizontal,
                              _("Total"))
        headers.setHeaderData(day_max + 3, Qt.Orientation.Horizontal,
                              _("Days off"))

        self.headers_view.setModel(
            headers)  # qt's doc : The view does *not* take ownership
        self.header_model = headers
        self.headers_view.setModel(
            self.header_model)  # qt's doc : The view does *not* take ownership

        # Compute all mondays indices
        monday = 0
        if t_start.weekday() > 0:
            monday = 7 - t_start.weekday()
        all_mondays = []

        while monday < day_max:
            all_mondays.append(monday)
            monday += 7

        today = date.today()

        # mainlog.debug("Running on employees")
        for row in range(self._table_model.rowCount()):

            # Clear the line
            for col in range(0, 32):
                ndx = self._table_model.index(row, col)
                self._table_model.setData(ndx, None, Qt.BackgroundRole)
                self._table_model.setData(ndx, QBrush(Qt.GlobalColor.black),
                                          Qt.TextColorRole)
                self._table_model.setData(ndx, None, Qt.DisplayRole)
                self._table_model.setData(ndx, None, Qt.UserRole)
                self._table_model.setData(ndx, None, Qt.UserRole + 1)
                #     else:
                #         self._table_model.setData(ndx,None,Qt.BackgroundRole)

                # else:
                #     self._table_model.setData(ndx,None,Qt.DisplayRole)
                #     self._table_model.setData(ndx,None,Qt.BackgroundRole)

            # Mark mondays
            for col in all_mondays:
                # col + 1 to account for the employee column
                self._table_model.setData(
                    self._table_model.index(row, col + 1),
                    QBrush(QColor(230, 230, 255)), Qt.BackgroundRole)

            # Mark today
            if today.month == self.base_date.month and today.year == self.base_date.year:
                self._table_model.setData(
                    self._table_model.index(row, today.day),
                    QBrush(QColor(255, 255, 128)), Qt.BackgroundRole)

        row = 0
        for employee in employees:  # employees are sorted

            self._table_model.setData(self._table_model.index(row, 0),
                                      employee.fullname,
                                      Qt.DisplayRole)  # FIXME Use a delegate
            self._table_model.setData(self._table_model.index(row, 0),
                                      employee.employee_id,
                                      Qt.UserRole)  # FIXME Use a delegate

            correction = 0
            if employee.employee_id in all_correction_times:
                correction = all_correction_times[employee.employee_id]
                self._table_model.setData(
                    self._table_model.index(row, day_max + 1),
                    duration_to_hm(correction, short_unit=True),
                    Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 1), None,
                    Qt.DisplayRole)

            presence = 0
            if employee.employee_id in all_presences and len(
                    all_presences[employee.employee_id]) > 0:
                import functools
                presence = functools.reduce(
                    lambda acc, s: acc + s,
                    all_presences[employee.employee_id], 0)
            presence += correction

            if presence != 0:
                self._table_model.setData(ndx, QBrush(Qt.GlobalColor.black),
                                          Qt.TextColorRole)
                self._table_model.setData(
                    self._table_model.index(row, day_max + 2),
                    duration_to_hm(presence, short_unit=True), Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 2), None,
                    Qt.DisplayRole)

            if employee.employee_id in all_presences and len(
                    all_presences[employee.employee_id]) > 0:
                for b in range(len(all_presences[employee.employee_id])):
                    ndx = self._table_model.index(row, b + 1)

                    p = all_presences[employee.employee_id][b]

                    if p > 0:
                        self._table_model.setData(
                            ndx, duration_to_hm(p, short_unit=True),
                            Qt.DisplayRole)
                        self._table_model.setData(ndx, p, Qt.UserRole)

                        if p >= 4 and p <= 8:
                            # Regular work load
                            self._table_model.setData(
                                ndx, QBrush(QColor(192, 255, 192)),
                                Qt.BackgroundRole)
                        elif p > 8 or (p < 4 and p > 0):
                            # Problematic work load
                            self._table_model.setData(
                                ndx, QBrush(QColor(255, 192, 192)),
                                Qt.BackgroundRole)

            if employee.employee_id in special_activities:
                sa_of_employee = special_activities[employee.employee_id]

                for sa in sa_of_employee:
                    start = max(t_start, sa.start_time)
                    end = min(t_end, sa.end_time)

                    for i in range(start.day, end.day + 1):
                        ndx = self._table_model.index(row, i)
                        self._table_model.setData(ndx,
                                                  QBrush(QColor(255, 128, 0)),
                                                  Qt.BackgroundRole)

                # self._table_model.setData(self._table_model.index(row,b+1),Qt.AlignRight | Qt.AlignVCenter,Qt.TextAlignmentRole)
            row += 1

        # Display day events

        employee_id_to_row = dict()  # little accelerator
        for row in range(len(employees)):
            employee_id_to_row[employees[row].employee_id] = row

        # Compute days off totals and show them

        self.day_event_totals = dict([(e.employee_id, dict())
                                      for e in employees])
        for day_event in all_events_in_month:
            # mainlog.debug("employee_id = {}".format(day_event.employee_id))
            # if day_event.employee_id not in self.day_event_totals:
            #    mainlog.debug(self.day_event_totals)

            t = self.day_event_totals[day_event.employee_id]
            if day_event.event_type not in t:
                t[day_event.event_type] = day_event.duration
            else:
                t[day_event.event_type] += day_event.duration

        for employee in employees:  # employees are sorted
            t = self.day_event_totals[employee.employee_id]
            mainlog.debug(t)
            total_off = sum(t.values())
            mainlog.debug(total_off)
            row = employee_id_to_row[employee.employee_id]
            mainlog.debug(row)
            if total_off:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 3),
                    nice_round(total_off), Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 3), None,
                    Qt.DisplayRole)

        # Show days off

        for day_event in all_events_in_month:
            row = employee_id_to_row[day_event.employee_id]
            col = day_event.date.day

            fg = bg = None
            if day_event.event_type in self.DAY_EVENT_PALETTE:
                fg, bg = self.DAY_EVENT_PALETTE[day_event.event_type]
            else:
                fg, bg = Qt.GlobalColor.red, Qt.GlobalColor.gray

            ndx = self._table_model.index(row, col)

            self._table_model.setData(ndx, day_event.day_event_id,
                                      Qt.UserRole + 1)

            # The problem here is to nicely blend the fact
            # that you can have a day event mixed with actual work
            # the very same day. Here's a poor man solution.

            active_time = self._table_model.data(ndx, Qt.UserRole)
            if not active_time:
                self._table_model.setData(
                    ndx, DayEventType.short_code(day_event.event_type),
                    Qt.DisplayRole)

                self._table_model.setData(ndx, QBrush(fg), Qt.TextColorRole)
                self._table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole)
            else:
                self._table_model.setData(ndx, QBrush(fg), Qt.TextColorRole)
                self._table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole)

                self._table_model.setData(
                    ndx,
                    duration_to_hm(active_time, short_unit=True) +
                    DayEventType.short_code(day_event.event_type),
                    Qt.DisplayRole)

        chrono.chrono_click()

        #for i in range(len(all_mondays)):
        self.table_view.resizeColumnsToContents()

        # mainlog.debug("Reset selection")
        ndx = self.table_view.currentIndex()

        self.table_view.selectionModel().clear()
        # self.table_view.selectionModel().clearSelection()
        # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
        # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
        self.table_view.selectionModel().setCurrentIndex(
            self.table_view.model().index(ndx.row(), ndx.column()),
            QItemSelectionModel.Select)

        self.cell_entered(self.table_view.currentIndex())
Ejemplo n.º 3
0
    def refresh_action(self):
        global dao

        self.title_box.set_title(_("Time Records Overview - {}").format(date_to_my(self.base_date,True)))


        self.employees = dao.employee_dao.all()
        day_max = calendar.monthrange(self.base_date.year,self.base_date.month)[1]
        t_start = datetime(self.base_date.year,self.base_date.month,1)
        t_end   = datetime(self.base_date.year,self.base_date.month,day_max,23,59,59,999999)


        self._table_model.setRowCount( len(self.employees))
        self._table_model.setColumnCount( 1+day_max)

        headers = QStandardItemModel(1, 1+day_max)
        headers.setHeaderData(0, Qt.Orientation.Horizontal, _("Employee"))
        for i in range(day_max):
            headers.setHeaderData(i+1, Qt.Orientation.Horizontal, "{}".format(i+1))
        self.headers_view.setModel(headers) # qt's doc : The view does *not* take ownership
        self.header_model = headers

        row = 0
        for employee in self.employees:
            # mainlog.debug(u"refresh action employee {}".format(employee))

            self._table_model.setData(self._table_model.index(row,0),employee.fullname,Qt.DisplayRole) # FIXME Use a delegate
            self._table_model.setData(self._table_model.index(row,0),employee,Qt.UserRole) # FIXME Use a delegate

            tracks = session().query(TimeTrack).filter(and_(TimeTrack.employee_id == employee.employee_id, TimeTrack.start_time >= t_start,TimeTrack.start_time <= t_end)).all()

            # One bucket per day
            buckets = [0] * day_max
            for t in tracks:
                mainlog.debug("Bucket {}".format(t))
                buckets[t.start_time.day - 1] += t.duration

            for b in range(len(buckets)):
                if buckets[b] != 0:
                    self._table_model.setData(self._table_model.index(row,b+1),duration_to_s(buckets[b]),Qt.DisplayRole)
                else:
                    self._table_model.setData(self._table_model.index(row,b+1),None,Qt.DisplayRole)

                if buckets[b] >= 0:
                    # Clear the background
                    self._table_model.setData(self._table_model.index(row,b+1),None,Qt.BackgroundRole)
                else:
                    self._table_model.setData(self._table_model.index(row,b+1),QBrush(QColor(255,128,128)),Qt.TextColorRole)

                self._table_model.setData(self._table_model.index(row,b+1),Qt.AlignRight,Qt.TextAlignmentRole)
            row += 1


        # Compute all mondays indices
        monday = 0
        if t_start.weekday() > 0:
            monday = 7 - t_start.weekday()
        all_mondays = []

        while monday < day_max:
            all_mondays.append(monday)
            monday += 7

        today = date.today()

        for row in range(len(self.employees)):
            # Mark mondays
            for col in all_mondays:
                # col + 1 to account for the employee column
                self._table_model.setData(self._table_model.index(row,col + 1),QBrush(QColor(230,230,255)),Qt.BackgroundRole)

            # Mark today
            if today.month == self.base_date.month and today.year == self.base_date.year:
                self._table_model.setData(self._table_model.index(row,today.day),QBrush(QColor(255,255,128)),Qt.BackgroundRole)

        #for i in range(len(all_mondays)):
        self.table_view.resizeColumnsToContents()

        # mainlog.debug("Reset selection")
        ndx = self.table_view.currentIndex()

        self.table_view.selectionModel().clear()
        # self.table_view.selectionModel().clearSelection()
        # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
        # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
        self.table_view.selectionModel().setCurrentIndex( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
Ejemplo n.º 4
0
    def __init__(self,parent):
        super(TimeTracksOverviewWidget,self).__init__(parent)

        self.base_date = date.today()

        headers = QStandardItemModel(1, 31 + 1)
        headers.setHeaderData(0, Qt.Orientation.Horizontal, _("Employee"))
        for i in range(31):
            headers.setHeaderData(i+1, Qt.Orientation.Horizontal, "{}".format(i+1))

        self._table_model = QStandardItemModel(1, 31+1, None)


        self.headers_view = QHeaderView(Qt.Orientation.Horizontal,self)
        self.header_model = headers
        self.headers_view.setResizeMode(QHeaderView.ResizeToContents)
        self.headers_view.setModel(self.header_model) # qt's doc : The view does *not* take ownership

        self.table_view = QTableView(None)
        self.table_view.setModel(self._table_model)
        self.table_view.setHorizontalHeader(self.headers_view)
        self.table_view.verticalHeader().hide()
        self.table_view.setAlternatingRowColors(True)
        # self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)


        navbar = NavBar(self, [ (_("Month before"), self.month_before),
                                (_("Today"),self.month_today),
                                (_("Month after"), self.month_after)])

        self.title_box = TitleWidget(_("Time Records Overview"),self,navbar)
        self.vlayout = QVBoxLayout(self)
        self.vlayout.setObjectName("Vlayout")
        self.vlayout.addWidget(self.title_box)


        self.setLayout(self.vlayout)


        self.hours_per_pers_subframe = SubFrame(_("Hours worked per person"), self.table_view, self)

        self.vlayout.addWidget(self.hours_per_pers_subframe)


        hlayout = QHBoxLayout()

        prototype = []
        prototype.append( OrderPartOnTaskPrototype(None, _('Order Part')))
        prototype.append( TaskOnOrderPartPrototype('task', _('Task'),on_date=date.today()))
        prototype.append( DurationPrototype('duration',_('Duration')))
        prototype.append( TimestampPrototype('start_time',_('Start time'),fix_date=date.today()))
        prototype.append( DatePrototype('encoding_date',_('Recorded at'),editable=False))

        self.controller = PrototypeController(self,prototype)
        self.controller.setModel(TrackingProxyModel(self,prototype))
        self.controller.view.setColumnWidth(1,300)
        self.controller.view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
        self.controller.view.horizontalHeader().setResizeMode(1,QHeaderView.Stretch)

        navbar = NavBar(self, [ (_("Edit"), self.edit_timetrack_no_ndx)])
        self.hours_on_day_subframe = SubFrame(_("Total times on day"), self.controller.view, self,navbar)
        hlayout.addWidget(self.hours_on_day_subframe)


        prototype = []
        # prototype.append( EmployeePrototype('reporter', _('Description'), dao.employee_dao.all()))

        prototype.append( TaskDisplayPrototype('task', _('Task')))
        self.pointage_timestamp_prototype = TimestampPrototype('time',_('Hour'),editable=False,fix_date=date.today())
        prototype.append( self.pointage_timestamp_prototype)
        prototype.append( TaskActionTypePrototype('kind',_('Action')))
        prototype.append( TextLinePrototype('origin_location',_('Origin')))
        prototype.append( TextLinePrototype('editor',_('Editor'),editable=False,default='master'))


        self.controller_actions = PrototypeController(self,prototype)
        self.controller_actions.setModel(ActionReportModel(self,prototype))

        navbar = NavBar(self, [ (_("Edit"), self.editTaskActionReports)])
        hlayout.addWidget(SubFrame(_("Time records"),self.controller_actions.view,self,navbar))
        self.controller_actions.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.controller_actions.view.doubleClicked.connect(self.editTaskActionReports)

        self.controller_actions.view.horizontalHeader().setResizeMode(0,QHeaderView.Stretch)
        self.controller_actions.view.horizontalHeader().setResizeMode(3,QHeaderView.ResizeToContents)
        self.controller_actions.view.horizontalHeader().setResizeMode(4,QHeaderView.ResizeToContents)

        self.vlayout.addLayout(hlayout)

        self.vlayout.setStretch(0,0)
        self.vlayout.setStretch(1,300)
        self.vlayout.setStretch(2,200)

        # self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        #self.table_view.entered.connect(self.cell_entered)

        self.table_view.selectionModel().currentChanged.connect(self.cell_entered)
        self.table_view.doubleClicked.connect(self.edit_timetrack)
        self.controller.view.selectionModel().currentChanged.connect(self.timetrack_changed)
        self.controller.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.refresh_action()
Ejemplo n.º 5
0
class ConsoleWidget(QMainWindow):
    def __init__(self):
        super(ConsoleWidget, self).__init__()
        self.setWindowTitle('1c query')

        self._connection = None

        self._home = os.path.expanduser('~/%s' % QApplication.applicationName())
        if not os.path.isdir(self._home):
            os.mkdir(self._home)

        self.queryToolBar = self.addToolBar('Query')
        self.queryAction = self.queryToolBar.addAction('Run', self.executeQuery)
        self.queryAction.setDisabled(True)

        uri_history = list()
        path = os.path.join(self._home, 'uri_history.txt')
        if os.path.isfile(path):
            uri_history = open(path, 'r').read().split('\n')

        self.connectionToolBar = self.addToolBar('Connection')
        self.connectionUriCombo = QComboBox(self)
        self.connectionUriCombo.setEditable(True)
        if not uri_history:
            self.connectionUriCombo.addItem('File="";usr="";pwd="";')
            self.connectionUriCombo.addItem('Srvr="{host}";Ref="{ref}";Usr="******";Pwd="{password}";')
        else:
            self.connectionUriCombo.addItems(uri_history)
            self.connectionUriCombo.setCurrentIndex(len(uri_history) - 1)
        self.connectionUriCombo.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum)
        self.connectionToolBar.addWidget(self.connectionUriCombo)

        self.onesVersionCombo = QComboBox(self)
        self.onesVersionCombo.addItems(['8.3', '8.2', '8.1', '8.0'])
        self.onesVersionCombo.setCurrentIndex(0)
        self.connectionToolBar.addWidget(self.onesVersionCombo)
        self.connectAction = self.connectionToolBar.addAction('Connect', self.connectOneS)
        self.disconnectAction = self.connectionToolBar.addAction('Disconnect', self.disconnectOneS)
        self.disconnectAction.setDisabled(True)

        self.logEdit = QPlainTextEdit(self)
        self.logDock = QDockWidget('Log', self)
        self.logDock.setWidget(self.logEdit)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.logDock, Qt.Horizontal)

        self.splitter = QSplitter(Qt.Vertical, self)
        self.setCentralWidget(self.splitter)

        self.sqlEdit = QTextEdit(self)
        self.sqlEdit.setLineWrapMode(QTextEdit.NoWrap)

        path = os.path.join(self._home, 'last-sql.txt')
        if os.path.isfile(path):
            sql = open(path, 'r').read()
            self.sqlEdit.setText(sql)

        self.model = QStandardItemModel(self)
        self.tableView = QTableView(self)
        self.tableView.setModel(self.model)

        self.splitter.addWidget(self.sqlEdit)
        self.splitter.addWidget(self.tableView)
        self.splitter.setStretchFactor(0, 3)
        self.splitter.setStretchFactor(1, 2)

    def query(self, sql):
        if not self._connection:
            self.logEdit.appendPlainText('No connection')
            return None

        try:
            query = self._connection.NewObject('Query', sql)
            result = query.Execute()
        except Exception as e:
            self.logEdit.appendPlainText(str(e))
            return None

        return result

    def refresh(self, result):
        self.model.clear()

        columns = list()
        result_columns = result.Columns
        for index in range(result_columns.Count()):
            name = result_columns.Get(index).Name
            columns.append(name)

        self.model.setColumnCount(len(columns))
        for section, name in enumerate(columns):
            self.model.setHeaderData(section, Qt.Horizontal, name)

        select = result.Choose()
        self.logEdit.appendPlainText('Selected %d records' % select.Count())
        while select.Next():
            items = list()
            for index in range(len(columns)):
                value = select.Get(index)

                item = QStandardItem('')
                if isinstance(value, bool):
                    item.setText(value and 'Yes' or 'No')

                elif isinstance(value, (int, str)):
                    item.setText(str(value))

                elif isinstance(value, datetime.datetime):
                    item.setText(value.strftime('%Y.%m.%d %H:%M:%S'))

                else:
                    item.setText(str(value))
                items.append(item)

            self.model.appendRow(items)

    @Slot()
    def executeQuery(self):
        sql = self.sqlEdit.toPlainText()
        result = self.query(sql)
        if result:
            path = os.path.join(self._home, 'last-sql.txt')
            open(path, 'w').write(sql)
            self.refresh(result)

    @Slot()
    def connectOneS(self):
        uri = self.connectionUriCombo.currentText().strip()
        if not uri:
            self.logEdit.appendPlainText('Need a connection string')
            return

        version = self.onesVersionCombo.currentText()
        comName = "V%s.COMConnector" % str(version).replace('.', '')

        pythoncom.CoInitialize()
        try:
            obj = win32com.client.Dispatch(comName)
            self._connection = obj.Connect(uri)
        except Exception as e:
            self.logEdit.appendPlainText(str(e))
            return

        self.connectAction.setDisabled(True)
        self.disconnectAction.setEnabled(True)
        self.queryAction.setEnabled(True)

        uri_history = list()
        for i in range(self.connectionUriCombo.count()):
            uri_history.append(self.connectionUriCombo.itemText(i))

        if uri not in uri_history:
            self.connectionUriCombo.clearEditText()
            self.connectionUriCombo.addItem(uri)
            self.connectionUriCombo.setCurrentIndex(len(uri_history))
            uri_history.append(uri)
            path = os.path.join(self._home, 'uri_history.txt')
            open(path, 'w').write('\n'.join(uri_history))

    @Slot()
    def disconnectOneS(self):
        pythoncom.CoUninitialize()
        self._connection = None
        self.connectAction.setEnabled(True)
        self.disconnectAction.setDisabled(True)
        self.queryAction.setDisabled(True)