コード例 #1
0
    def __init__(self,parent):
        global dao
        super(EditDeliverySlipDialog,self).__init__(parent)

        title = _("Create delivery slip")
        self.setWindowTitle(title)

        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title,self)
        top_layout.addWidget(self.title_widget)

        self.info_label = QLabel()
        self.info_label.setWordWrap(True)
        top_layout.addWidget(self.info_label)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton( QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton( QDialogButtonBox.Ok)

        order_part_prototype = []
        order_part_prototype.append( TextLinePrototype('human_identifier',_('Part n.'),editable=False))
        order_part_prototype.append( TextLinePrototype('description',_('Description'),editable=False))
        order_part_prototype.append( IntegerNumberPrototype('qty',_('Qty plan.'),editable=False))
        order_part_prototype.append( IntegerNumberPrototype('tex2',_('Qty so far'),editable=False))
        order_part_prototype.append( IntegerNumberPrototype(None,_('Qty out now'),nullable=True))
        self.qty_out_column = len(order_part_prototype) - 1

        # order_part_prototype.append( IntegerNumberPrototype(None,_('Reglages'),nullable=True))
        # order_part_prototype.append( IntegerNumberPrototype(None,_('Derogation'),nullable=True))
        # order_part_prototype.append( IntegerNumberPrototype(None,_('Rebus'),nullable=True))


        self.controller_part = PrototypeController(self, order_part_prototype,None,freeze_row_count=True)
        self.controller_part.view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
        self.controller_part.view.horizontalHeader().setResizeMode(1,QHeaderView.Stretch)


        self.controller_part.setModel(TrackingProxyModel(self,order_part_prototype))
        self.close_order_checkbox = QCheckBox(_("Close the order"))

        top_layout.addWidget(self.controller_part.view) # self.time_tracks_view)
        # top_layout.addWidget(self._make_units_qaulifications_gui())
        top_layout.addWidget(self.close_order_checkbox)
        top_layout.addWidget(self.buttons)
        self.setLayout(top_layout)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)

        sg = QDesktopWidget().screenGeometry()
        self.setMinimumWidth(0.5*sg.width())
        self.setMinimumHeight(0.3*sg.height())

        self.slip_id = None
コード例 #2
0
    def __init__(self, parent, dao, day):
        super(EditTimeTracksDialog, self).__init__(parent)

        self.edit_date = day

        title = _("Time spent on tasks")
        self.setWindowTitle(title)

        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title, self)
        top_layout.addWidget(self.title_widget)

        hlayout = QHBoxLayout()
        self.timesheet_info_label = QLabel("Name", self)
        hlayout.addWidget(self.timesheet_info_label)
        hlayout.addStretch()
        top_layout.addLayout(hlayout)
        info = QLabel(
            _("On the table below you can have two kinds of line. The grey line which shows the time spent on a task computed on the basis of the actual time recordings. Since those are computed automaticaly, you can't change them. The other lines in black, are those that you will encode have encoded yourself. They represent hours to add or remove to those of the grey lines. So, for example, if you want to remove 3 hours on a task, you encode the task with a duration of three hours."
              ), self)
        info.setWordWrap(True)
        top_layout.addWidget(info)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton(QDialogButtonBox.Ok)

        if dao.task_dao.tasks_count() > 0:

            prototype = []
            prototype.append(
                ImputableSelectorPrototype(None,
                                           _('Order Part'),
                                           nullable=True))

            # BUG today is wrong... Must be the imputation date
            self.task_on_orderpart_prototype = ProxyTaskComboPrototype(
                'task',
                _('Task'),
                on_date=date.today(),
                editable=True,
                nullable=False)
            prototype.append(self.task_on_orderpart_prototype)

            prototype.append(
                DurationPrototype('duration',
                                  _('Duration'),
                                  format_as_float=False))
            prototype.append(
                ConstrainedMachineSelectorPrototype('machine_id',
                                                    _('Machine'),
                                                    nullable=True))
            # prototype.append( TimestampPrototype('start_time',_('Start time'),fix_date=day,nullable=True,editable=True))
            # prototype.append( TimestampPrototype('encoding_date',_('Recorded at'),editable=False))

            self.controller = PrototypeController(self, prototype)

            self.controller.setModel(TrackingProxyModel(self, prototype))
            self.controller.view.horizontalHeader().setResizeMode(
                1, QHeaderView.Stretch)
            self.controller.view.enable_edit_panel()

            self.controller.model.rowsInserted.connect(self.data_changed_slot)
            self.controller.model.rowsRemoved.connect(self.data_changed_slot)
            self.controller.model.dataChanged.connect(self.data_changed_slot)

            # self.employee_select = QComboBox()
            # self.employee_select.setModel(self.dao.employee_dao.list_model())
            # self.employee_select.setCurrentIndex(0)
            # self.set_on_selected_employee()
            # top_layout.addWidget(self.employee_select)

            top_layout.addWidget(
                self.controller.view)  # self.time_tracks_view)

            hlayout = QHBoxLayout()
            self.sum_hours_label = QLabel("12345")
            self.sum_hours_label.setObjectName("important")  # Used for CSS
            hlayout.addStretch()
            hlayout.addWidget(QLabel(_("Sum of durations")))
            hlayout.addWidget(self.sum_hours_label)

            top_layout.addLayout(hlayout)

            top_layout.addWidget(self.buttons)
            self.setLayout(top_layout)

            self.buttons.accepted.connect(self.accept)
            self.buttons.rejected.connect(self.reject)
            # self.employee_select.activated.connect(self.employee_changed)

            self.resize(800, 400)
            self.setSizeGripEnabled(True)

        else:
            top_layout.addWidget(
                QLabel(
                    "There are no task in the system " +
                    "for you to report on. Create some " + "tasks first",
                    self))
            top_layout.addWidget(self.buttons)
            self.setLayout(top_layout)
            self.buttons.accepted.connect(self.accept_direct)
            self.buttons.rejected.connect(self.reject)
コード例 #3
0
class EditTimeTracksDialog(QDialog):
    @Slot(QStandardItem)
    def data_changed_slot(self, item):
        # mainlog.debug("data_changed_slot")
        self.model_data_changed = True

        m = self.controller.model
        sum_hours = 0
        for i in range(m.rowCount()):
            ndx = m.index(i, 2)
            #mainlog.debug("editTT : {}: {}".format(i, m.data(ndx,Qt.UserRole)))
            try:
                sum_hours = sum_hours + float(m.data(ndx, Qt.UserRole))
            except:
                pass

        mainlog.debug("Sum = {}".format(sum_hours))
        self.sum_hours_label.setText(duration_to_hm(sum_hours))

    def __init__(self, parent, dao, day):
        super(EditTimeTracksDialog, self).__init__(parent)

        self.edit_date = day

        title = _("Time spent on tasks")
        self.setWindowTitle(title)

        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title, self)
        top_layout.addWidget(self.title_widget)

        hlayout = QHBoxLayout()
        self.timesheet_info_label = QLabel("Name", self)
        hlayout.addWidget(self.timesheet_info_label)
        hlayout.addStretch()
        top_layout.addLayout(hlayout)
        info = QLabel(
            _("On the table below you can have two kinds of line. The grey line which shows the time spent on a task computed on the basis of the actual time recordings. Since those are computed automaticaly, you can't change them. The other lines in black, are those that you will encode have encoded yourself. They represent hours to add or remove to those of the grey lines. So, for example, if you want to remove 3 hours on a task, you encode the task with a duration of three hours."
              ), self)
        info.setWordWrap(True)
        top_layout.addWidget(info)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton(QDialogButtonBox.Ok)

        if dao.task_dao.tasks_count() > 0:

            prototype = []
            prototype.append(
                ImputableSelectorPrototype(None,
                                           _('Order Part'),
                                           nullable=True))

            # BUG today is wrong... Must be the imputation date
            self.task_on_orderpart_prototype = ProxyTaskComboPrototype(
                'task',
                _('Task'),
                on_date=date.today(),
                editable=True,
                nullable=False)
            prototype.append(self.task_on_orderpart_prototype)

            prototype.append(
                DurationPrototype('duration',
                                  _('Duration'),
                                  format_as_float=False))
            prototype.append(
                ConstrainedMachineSelectorPrototype('machine_id',
                                                    _('Machine'),
                                                    nullable=True))
            # prototype.append( TimestampPrototype('start_time',_('Start time'),fix_date=day,nullable=True,editable=True))
            # prototype.append( TimestampPrototype('encoding_date',_('Recorded at'),editable=False))

            self.controller = PrototypeController(self, prototype)

            self.controller.setModel(TrackingProxyModel(self, prototype))
            self.controller.view.horizontalHeader().setResizeMode(
                1, QHeaderView.Stretch)
            self.controller.view.enable_edit_panel()

            self.controller.model.rowsInserted.connect(self.data_changed_slot)
            self.controller.model.rowsRemoved.connect(self.data_changed_slot)
            self.controller.model.dataChanged.connect(self.data_changed_slot)

            # self.employee_select = QComboBox()
            # self.employee_select.setModel(self.dao.employee_dao.list_model())
            # self.employee_select.setCurrentIndex(0)
            # self.set_on_selected_employee()
            # top_layout.addWidget(self.employee_select)

            top_layout.addWidget(
                self.controller.view)  # self.time_tracks_view)

            hlayout = QHBoxLayout()
            self.sum_hours_label = QLabel("12345")
            self.sum_hours_label.setObjectName("important")  # Used for CSS
            hlayout.addStretch()
            hlayout.addWidget(QLabel(_("Sum of durations")))
            hlayout.addWidget(self.sum_hours_label)

            top_layout.addLayout(hlayout)

            top_layout.addWidget(self.buttons)
            self.setLayout(top_layout)

            self.buttons.accepted.connect(self.accept)
            self.buttons.rejected.connect(self.reject)
            # self.employee_select.activated.connect(self.employee_changed)

            self.resize(800, 400)
            self.setSizeGripEnabled(True)

        else:
            top_layout.addWidget(
                QLabel(
                    "There are no task in the system " +
                    "for you to report on. Create some " + "tasks first",
                    self))
            top_layout.addWidget(self.buttons)
            self.setLayout(top_layout)
            self.buttons.accepted.connect(self.accept_direct)
            self.buttons.rejected.connect(self.reject)

    def keyPressEvent(self, event):

        # The goal here is to make sure the accept signal is called only
        # if the user clicks on the "OK" button /with the mouse/ and,
        # not with the keyboard.

        if event.key() in (Qt.Key_Enter, Qt.Key_Return):
            return
        else:
            super(EditTimeTracksDialog, self).keyPressEvent(event)

    def set_employee_and_date(
        self, employee_id, edit_date
    ):  # FIXME move this into constructore and remove call in using class... Or change the timestamp prototype

        employee = dao.employee_dao.find_by_id_frozen(employee_id)
        timetracks = dao.timetrack_dao.all_work_for_employee_date(
            employee_id, edit_date)
        self.task_cache = PotentialTasksCache(dao.task_dao, edit_date)

        mainlog.debug("set_employee_and_date : timetracks are")
        proxified_timetracks = []
        for timetrack in timetracks:
            mainlog.debug(timetrack)
            proxified_timetracks.append(TimetrackProxy(timetrack))
        mainlog.debug("done")

        self.edit_date = edit_date
        self.task_on_orderpart_prototype.on_date = edit_date
        self.timesheet_info_label.setText(
            _("Timesheet for <b>{}</b> on <b>{}</b>").format(
                employee.fullname, date_to_s(edit_date, True)))

        self.task_on_orderpart_prototype.set_task_cache(self.task_cache)

        self.controller.model._buildModelFromObjects(proxified_timetracks)

        self.controller.model.set_row_protect_func(
            lambda obj, row: obj is not None and obj.managed_by_code,
            prevent_row_delete_message)
        self.controller.model.row_update_protect_func = lambda obj, row: obj and obj.managed_by_code
        self.controller.model.row_update_protect_announce = prevent_row_update_message

        for i in range(len(timetracks)):
            row = self.controller.model.table[i]
            imputable = ImputableProxy(edit_date)
            imputable.set_on_timetrack(timetracks[i])
            row[0] = imputable

        # for row in self.controller.model.table:
        #     if row[1]:
        #         row[0] = row[1].operation.production_file.order_part

        # self.controller.model_data_changed = False # FIXME dirty (encapsulate in controller plz)
        self.current_employee_id_selected = employee_id

        self.controller.view.setFocus(Qt.OtherFocusReason)
        self.controller.view.setCurrentIndex(self.controller.model.index(0, 0))

        # FIXME Better separate presentation and data layer !!!
        session().commit()

        self.data_changed_slot(None)

    # @Slot(int)
    # def employee_changed(self,ndx):

    #     # Pay attention ! At this point the rdopdown already report the
    #     # new selection, not the one that is used for the table !

    #     mainlog.debug("Employee changed to {}, was {}".format(ndx,employee))

    #     if self.current_employee_selected != ndx:

    #         # Actually changed

    #         if not self.model_data_changed:
    #             self.set_on_selected_employee()
    #         else:
    #             ret = saveCheckBox()

    #             if ret == QMessageBox.Save:
    #                 if self.save():
    #                     self.set_on_selected_employee()
    #                 else:
    #                     self.employee_select.setCurrentIndex(self.current_employee_selected)
    #             elif ret == QMessageBox.Cancel:
    #                 # User has cancelled or save didn't work out => we reset to the old value
    #                 self.employee_select.setCurrentIndex(self.current_employee_selected)
    #             else: # QMessageBox.Discard
    #                 self.set_on_selected_employee()

    def save(self):
        mainlog.debug("EditTimeTracksDialog.save()")
        errors = self.controller.model.validate()
        if errors:
            showTableEntryErrorBox(errors)
            return False

        tt_start_time = datetime(self.edit_date.year, self.edit_date.month,
                                 self.edit_date.day, 6, 0, 0)
        edited_proxy_tts = self.controller.model.model_to_objects(
            lambda: TimetrackProxy())
        employee_id = self.current_employee_id_selected

        # for tt in edited_proxy_tts:
        #     mainlog.debug(type(tt))
        #     mainlog.debug(str(tt))

        try:
            save_proxy_timetracks(edited_proxy_tts, tt_start_time, employee_id)
            return True
        except Exception as e:
            msgBox = QMessageBox(self)
            msgBox.setIcon(QMessageBox.Critical)
            msgBox.setText("There was an error while saving your data")
            msgBox.setInformativeText(str(e))
            msgBox.setStandardButtons(QMessageBox.Ok)
            # msgBox.setDefaultButton(QMessageBox.Ok);
            ret = msgBox.exec_()
            return False

    @Slot()
    def accept(self):
        if self.save():
            mainlog.debug("Clearing model {}".format(self.controller.model))

            # Don't forget to clear the model so we don't keep any
            # references to anything

            self.controller.model.clear()
            return super(EditTimeTracksDialog, self).accept()
        else:
            mainlog.debug("accept was not accepted :-)")

    @Slot()
    def accept_direct(self):
        super(EditTimeTracksDialog, self).accept()
        self.controller.model.clear()

    @Slot()
    def reject(self):
        super(EditTimeTracksDialog, self).reject()
        self.controller.model.clear()
コード例 #4
0
ファイル: EditSupplyOrderPanel.py プロジェクト: wiz21b/koi
class EditSupplyOrderPanel(HorsePanel):

    supply_order_saved = Signal()

    def panel_content_hash(self):
        return (self.current_supply_order_id,
                self.current_supplier.supplier_id)

    def needs_close_confirmation(self):
        return self.model_data_changed

    def confirm_close(self):
        return self._save_if_necessary()

    @Slot()
    def change_supplier(self):
        from koi.supply.ChooseSupplierDialog import ChooseSupplierDialog
        from PySide.QtGui import QDialog

        d = ChooseSupplierDialog(self)
        if d.exec_() and d.result(
        ) == QDialog.Accepted and d.supplier_id != self.current_supplier.supplier_id:
            mainlog.debug("Supplier chosen {}".format(d.supplier))
            self.current_supplier = d.supplier
            self.supplier_plate_widget.set_contact_data(self.current_supplier)
            self.data_changed2_slot()

    @Slot()
    def print_supply_order(self):
        if self._save_if_necessary():
            try:
                print_supply_order(self.current_supply_order_id)
            except Exception as e:
                showErrorBox(str(e))

    def _save_if_necessary(self):
        """ True if the user has either said he doesn't want to save or
        he saved successufly. False if the user has cancelled (no save, no "no save")
        or the save operation has failed """

        if self.model_data_changed:
            ynb = yesNoBox(
                _("Data were changed"),
                _("You have changed some of the data in this. Do you want to save before proceeding ?"
                  ))
            if ynb == QMessageBox.Yes:
                if self.save(
                ) != False:  # FIXME defensive, make sure it's True
                    # Because when I save, although the order definition is
                    # not meant to change, the order numbers (accounting label,
                    # etc.) might actually change.
                    self.reload()
                    return True
                else:
                    return False
            elif ynb == QMessageBox.No:
                return True
            elif ynb == QMessageBox.Cancel:
                return False
        else:
            return True

    def edit_new(self, supplier):
        """ Start editing a brand new order
        """

        self.current_supplier = supplier
        self.current_supply_order_id = None
        self.edit_comment_widget.setText(None)
        self.delivery_date_widget.set_value(None)
        self.creation_date_widget.setText("")
        self.controller_part.model.clear()
        self.controller_part.model.insertRows(0, 1, QModelIndex())
        self.accounting_label = None
        self._set_view(None, True)

        mainlog.debug("edit_new : supplier : {}".format(
            self.current_supplier.supplier_id))

    def edit(self, supply_order_id):
        """ Start editing an existing order
        """

        self._fill_view_with_order_data(supply_order_id)
        self._set_view(None, False)

    def reload(self):
        ndx = self.controller_part.view.currentIndex()
        self._fill_view_with_order_data(self.current_supply_order_id)
        self._set_view(ndx, False)

    def _fill_view_with_order_data(self, order_id):
        sorder, sorder_parts = supply_order_service.find_by_id(order_id)

        self.edit_comment_widget.setText(sorder.description)
        self.delivery_date_widget.set_value(sorder.expected_delivery_date)
        self.creation_date_widget.setText(date_to_dmy(sorder.creation_date))
        self.supplier_reference_widget.setText(sorder.supplier_reference)
        self.current_supplier = supplier_service.find_by_id(sorder.supplier_id)
        self.current_supply_order_id = sorder.supply_order_id
        self.model._buildModelFromObjects(sorder_parts)
        self.accounting_label = sorder.accounting_label

    def _set_view(self, ndx=None, start_editing=False):
        """ Once the data and models are prepared, one comes
        here to start the editing...
        """

        self.supplier_plate_widget.set_contact_data(self.current_supplier)
        self.controller_part.view.setFocus()

        if not ndx:
            ndx = self.controller_part.model.index(0, 0)
        # Somehow, editing a cell doesn't set up the currentIndex automatically...
        self.controller_part.view.setCurrentIndex(ndx)

        if start_editing:
            self.controller_part.view.edit(ndx)

        self.model_data_changed = False
        self.title_widget.set_modified_flag(False)

        ref = self.accounting_label or self.supplier_reference_widget.text()

        if ref:
            self.set_panel_title(u"{}\n{}".format(
                ref, self.current_supplier.fullname))
        else:
            self.set_panel_title(
                _("Supply order") + u"\n" + self.current_supplier.fullname)

        refs = []
        if self.accounting_label:
            refs.append(
                u"<span style='color:orange; font-style:normal;'>{}</span>".
                format(self.accounting_label))

        if self.supplier_reference_widget.text():
            refs.append(
                u"<span style='color:black; font-style:normal;'>{}</span>".
                format(self.supplier_reference_widget.text()))

        self.in_title_label.setText(
            _("<h1>Ref. : {}</h1>").format(u" / ".join(refs)))

    def _validate(self):
        errs = self.model.validate()
        if errs:
            errs = [formatErrorsOnLine(errs)]
        else:
            errs = []

        if not self.delivery_date_widget.is_valid():
            errs.append(_('The date is not valid'))

        return errs or True

    def save(self):
        if self.model_data_changed:

            focused_widget = QApplication.focusWidget()
            if isinstance(focused_widget,
                          QLineEdit) and focused_widget.parent() != self:
                focused_widget.clearFocus()
                focused_widget = QApplication.focusWidget()

            validation_results = self._validate()
            if validation_results != True:
                showErrorBox(_("The data are not correct"),
                             "<br>-" + "<br>-".join(validation_results))
                return False

            mainlog.debug("save : supplier_id : {}".format(
                self.current_supplier.supplier_id))

            obj = blank_dto(SupplyOrder)
            obj.supply_order_id = self.current_supply_order_id
            obj.creation_date = date.today()
            obj.description = self.edit_comment_widget.toPlainText()
            obj.supplier_id = self.current_supplier.supplier_id
            obj.expected_delivery_date = self.delivery_date_widget.value()
            obj.supplier_reference = self.supplier_reference_widget.text()
            obj.accounting_label = self.accounting_label

            def factory():
                return blank_dto(SupplyOrderPart)

            parts_actions = self.model.model_to_objects(factory)

            try:
                mainlog.debug("Saving")
                self.current_supply_order_id = supply_order_service.save(
                    obj, parts_actions)
                # Reload the data
                self.reload()
                mainlog.debug("Emitting change signal")
                self.supply_order_saved.emit()  # self.current_supply_order_id)

            except Exception as ex:
                showErrorBox(
                    _("Error while saving"),
                    _("There was an unexpected error while saving your data"),
                    ex,
                    object_name="saveError")

            if focused_widget:
                focused_widget.setFocus(Qt.OtherFocusReason)

    @Slot()
    def delete(self):
        if self.current_supply_order_id:

            s = _("About to delete order {}").format(self.accounting_label)

            if confirmationBox(s, _("Are you sure ?")):

                try:
                    supply_order_service.deactivate(
                        self.current_supply_order_id)
                except Exception as ex:
                    showErrorBox("I could not delete the order", ex=ex)
                    return

                rep = supply_order_service.find_last_order_id(
                    self.current_supplier.supplier_id)
                if rep:
                    self.edit(rep)
                else:
                    self.edit_new(self.current_supplier)
        else:
            showErrorBox(
                _("No order or non-saved order selected"),
                _("You can only delete an order that has already been saved"),
                object_name="delete_only_saved_order")
            return

    @Slot()
    def show_actions(self):
        button = self.action_menu.parent()
        p = button.mapToGlobal(QPoint(0, button.height()))
        self.action_menu.exec_(p)

    @Slot(QStandardItem)
    def data_changed_slot(self, item):
        self.model_data_changed = True
        self.title_widget.set_modified_flag(self.model_data_changed)

    @Slot()
    def data_changed2_slot(self):
        self.model_data_changed = True
        self.title_widget.set_modified_flag(self.model_data_changed)

    @Slot()
    def next_order_for_supplier(self):
        if self._save_if_necessary():
            # This could find nothing if there's no order for the supplier :-)
            oid = supply_order_service.find_next_for_supplier(
                self.current_supply_order_id,
                self.current_supplier.supplier_id)
            if oid:
                self.edit(oid)

    @Slot()
    def previous_order_for_supplier(self):
        if self._save_if_necessary():
            oid = supply_order_service.find_previous_for_supplier(
                self.current_supply_order_id,
                self.current_supplier.supplier_id)
            if oid:
                self.edit(oid)

    def __init__(self, parent):
        super(EditSupplyOrderPanel, self).__init__(parent)

        self.current_supply_order_id = None

        self.proto = []
        self.proto.append(
            TextAreaPrototype('description',
                              _('Description'),
                              editable=True,
                              nullable=False))
        self.proto.append(
            FloatNumberPrototype('quantity',
                                 _('Quantity'),
                                 editable=True,
                                 nullable=False))
        self.proto.append(
            FloatNumberPrototype('unit_price',
                                 _('Unit price'),
                                 editable=True,
                                 nullable=True))

        self.delivery_date_prototype = FutureDatePrototype('description',
                                                           ('Description'),
                                                           editable=True,
                                                           nullable=False)

        self.model = SupplyOrderPartsModel(self, self.proto)

        self.controller_part = PrototypeController(
            self, self.proto, ProxyTableView(None, self.proto))

        self.controller_part.setModel(self.model)
        # self.controller_part.view.verticalHeader().hide()
        self.controller_part.view.horizontalHeader().setResizeMode(
            0, QHeaderView.Stretch)

        self.print_supply_order_action = QAction(_("Print supply order"),
                                                 self)  # , parent
        self.print_supply_order_action.triggered.connect(
            self.print_supply_order)
        self.print_supply_order_action.setShortcut(
            QKeySequence(Qt.CTRL + Qt.Key_P))
        self.print_supply_order_action.setShortcutContext(
            Qt.WidgetWithChildrenShortcut)
        self.addAction(self.print_supply_order_action)

        self.save_supply_order_action = QAction(_("Save supply order"),
                                                self)  # , parent
        self.save_supply_order_action.triggered.connect(self.save)
        self.save_supply_order_action.setShortcut(
            QKeySequence(Qt.CTRL + Qt.Key_S))
        self.save_supply_order_action.setShortcutContext(
            Qt.WidgetWithChildrenShortcut)
        self.addAction(self.save_supply_order_action)

        self.delete_supply_order_action = QAction(_("Deactivate supply order"),
                                                  self)  # , parent
        self.delete_supply_order_action.triggered.connect(self.delete)
        self.addAction(self.delete_supply_order_action)

        self.next_order_for_supplier_action = QAction(
            _("Next supplier's order"), self)  # , parent
        self.next_order_for_supplier_action.setShortcut(
            QKeySequence(Qt.CTRL + Qt.Key_PageDown))
        self.next_order_for_supplier_action.setShortcutContext(
            Qt.WidgetWithChildrenShortcut)
        self.next_order_for_supplier_action.triggered.connect(
            self.next_order_for_supplier)
        self.addAction(self.next_order_for_supplier_action)

        self.previous_order_for_supplier_action = QAction(
            _("Previous supplier's order"), self)  # , parent
        self.previous_order_for_supplier_action.setShortcut(
            QKeySequence(Qt.CTRL + Qt.Key_PageDown))
        self.previous_order_for_supplier_action.setShortcutContext(
            Qt.WidgetWithChildrenShortcut)
        self.previous_order_for_supplier_action.triggered.connect(
            self.next_order_for_supplier)
        self.addAction(self.previous_order_for_supplier_action)

        self.change_supplier_action = QAction(_("Change supplier"),
                                              self)  # , parent
        self.change_supplier_action.triggered.connect(self.change_supplier)
        self.addAction(self.change_supplier_action)

        # self.controller_operation.view.addAction(self.reprint_delivery_slip)
        self.controller_part.view.addAction(self.print_supply_order_action)
        self.controller_part.view.addAction(self.save_supply_order_action)
        self.controller_part.view.addAction(self.delete_supply_order_action)

        navigation = NavBar(self,
                            [(self.next_order_for_supplier_action.text(),
                              self.next_order_for_supplier),
                             (self.previous_order_for_supplier_action.text(),
                              self.previous_order_for_supplier),
                             (_("Action"), self.show_actions)])
        navigation.buttons[2].setObjectName("specialMenuButton")

        self.action_menu = QMenu(navigation.buttons[2])
        list_actions = [(self.print_supply_order_action, None),
                        (self.save_supply_order_action, None),
                        (self.delete_supply_order_action, None),
                        (self.change_supplier_action, None)]

        populate_menu(self.action_menu,
                      self,
                      list_actions,
                      context=Qt.WidgetWithChildrenShortcut)

        self.title_widget = TitleWidget(_("Supply order"), self, navigation)
        self.supplier_plate_widget = SupplierPlateWidget(self)
        self.edit_comment_widget = DescribedTextEdit(_("Comments"))
        self.edit_comment_widget.setMinimumHeight(20)
        self.edit_comment_widget.setMinimumWidth(600)
        self.edit_comment_widget.setMaximumHeight(60)
        self.edit_comment_widget.setSizePolicy(QSizePolicy.Preferred,
                                               QSizePolicy.Preferred)

        self.supplier_reference_widget = QLineEdit()

        self.delivery_date_widget = DateEntryWidget()
        self.delivery_date_widget.setMaximumWidth(100)

        self.creation_date_widget = QLabel()

        self.in_title_label = QLabel()

        top_layout1 = QHBoxLayout()
        top_layout1.addWidget(self.in_title_label)
        top_layout1.addStretch()
        top_layout1.addWidget(self.supplier_plate_widget)

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel(_("Delivery date")))
        hlayout.addWidget(self.delivery_date_widget)
        hlayout.addStretch()

        hlayout3 = QHBoxLayout()
        hlayout3.addWidget(QLabel(_("Creation date")))
        hlayout3.addWidget(self.creation_date_widget)
        hlayout3.addStretch()

        hlayout2 = QHBoxLayout()
        hlayout2.addWidget(QLabel(_("Supplier's reference")))
        hlayout2.addWidget(self.supplier_reference_widget)
        hlayout2.addStretch()

        vlayout = QVBoxLayout()
        vlayout.addLayout(hlayout)  # delivery date
        vlayout.addLayout(hlayout3)  # creation date
        vlayout.addLayout(hlayout2)  # reference
        vlayout.addStretch()

        top_layout2 = QHBoxLayout()
        top_layout2.addLayout(vlayout)
        top_layout2.addWidget(self.edit_comment_widget)
        top_layout2.addStretch()
        top_layout2.setStretch(0, 0)
        top_layout2.setStretch(1, 0)
        # For some reason, the stretch added above is not enough
        # to push the whole layout to the left. I have to set
        # it's stretch factor too...
        top_layout2.setStretch(2, 100)

        vhead_layout = QVBoxLayout()
        vhead_layout.addWidget(self.title_widget)
        top_layout1.setContentsMargins(4, 0, 4, 0)
        # vhead_layout.addLayout(top_layout1)
        vhead_layout.addWidget(InlineSubFrame(top_layout1, None))

        vhead_layout.addLayout(top_layout2)
        # top_layout2.setContentsMargins(4,4,4,4)
        #vhead_layout.addWidget(InlineSubFrame(top_layout2,None))

        vhead_layout.addWidget(self.controller_part.view)
        vhead_layout.setStretch(0, 0)
        vhead_layout.setStretch(1, 0)
        vhead_layout.setStretch(2, 0)
        vhead_layout.setStretch(3, 10)

        self.setLayout(vhead_layout)

        self.controller_part.view.enable_edit_panel()

        # Handling changes in the model (helpful to know if saving
        # is necessary)

        self.model_data_changed = False
        self.model.rowsInserted.connect(self.data_changed_slot)
        self.model.rowsRemoved.connect(self.data_changed_slot)
        self.model.dataChanged.connect(self.data_changed_slot)
        self.supplier_reference_widget.textChanged.connect(
            self.data_changed2_slot)
        self.edit_comment_widget.textChanged.connect(self.data_changed2_slot)
        self.delivery_date_widget.textChanged.connect(self.data_changed2_slot)
コード例 #5
0
ファイル: EditSupplyOrderPanel.py プロジェクト: wiz21b/koi
    def __init__(self, parent):
        super(EditSupplyOrderPanel, self).__init__(parent)

        self.current_supply_order_id = None

        self.proto = []
        self.proto.append(
            TextAreaPrototype('description',
                              _('Description'),
                              editable=True,
                              nullable=False))
        self.proto.append(
            FloatNumberPrototype('quantity',
                                 _('Quantity'),
                                 editable=True,
                                 nullable=False))
        self.proto.append(
            FloatNumberPrototype('unit_price',
                                 _('Unit price'),
                                 editable=True,
                                 nullable=True))

        self.delivery_date_prototype = FutureDatePrototype('description',
                                                           ('Description'),
                                                           editable=True,
                                                           nullable=False)

        self.model = SupplyOrderPartsModel(self, self.proto)

        self.controller_part = PrototypeController(
            self, self.proto, ProxyTableView(None, self.proto))

        self.controller_part.setModel(self.model)
        # self.controller_part.view.verticalHeader().hide()
        self.controller_part.view.horizontalHeader().setResizeMode(
            0, QHeaderView.Stretch)

        self.print_supply_order_action = QAction(_("Print supply order"),
                                                 self)  # , parent
        self.print_supply_order_action.triggered.connect(
            self.print_supply_order)
        self.print_supply_order_action.setShortcut(
            QKeySequence(Qt.CTRL + Qt.Key_P))
        self.print_supply_order_action.setShortcutContext(
            Qt.WidgetWithChildrenShortcut)
        self.addAction(self.print_supply_order_action)

        self.save_supply_order_action = QAction(_("Save supply order"),
                                                self)  # , parent
        self.save_supply_order_action.triggered.connect(self.save)
        self.save_supply_order_action.setShortcut(
            QKeySequence(Qt.CTRL + Qt.Key_S))
        self.save_supply_order_action.setShortcutContext(
            Qt.WidgetWithChildrenShortcut)
        self.addAction(self.save_supply_order_action)

        self.delete_supply_order_action = QAction(_("Deactivate supply order"),
                                                  self)  # , parent
        self.delete_supply_order_action.triggered.connect(self.delete)
        self.addAction(self.delete_supply_order_action)

        self.next_order_for_supplier_action = QAction(
            _("Next supplier's order"), self)  # , parent
        self.next_order_for_supplier_action.setShortcut(
            QKeySequence(Qt.CTRL + Qt.Key_PageDown))
        self.next_order_for_supplier_action.setShortcutContext(
            Qt.WidgetWithChildrenShortcut)
        self.next_order_for_supplier_action.triggered.connect(
            self.next_order_for_supplier)
        self.addAction(self.next_order_for_supplier_action)

        self.previous_order_for_supplier_action = QAction(
            _("Previous supplier's order"), self)  # , parent
        self.previous_order_for_supplier_action.setShortcut(
            QKeySequence(Qt.CTRL + Qt.Key_PageDown))
        self.previous_order_for_supplier_action.setShortcutContext(
            Qt.WidgetWithChildrenShortcut)
        self.previous_order_for_supplier_action.triggered.connect(
            self.next_order_for_supplier)
        self.addAction(self.previous_order_for_supplier_action)

        self.change_supplier_action = QAction(_("Change supplier"),
                                              self)  # , parent
        self.change_supplier_action.triggered.connect(self.change_supplier)
        self.addAction(self.change_supplier_action)

        # self.controller_operation.view.addAction(self.reprint_delivery_slip)
        self.controller_part.view.addAction(self.print_supply_order_action)
        self.controller_part.view.addAction(self.save_supply_order_action)
        self.controller_part.view.addAction(self.delete_supply_order_action)

        navigation = NavBar(self,
                            [(self.next_order_for_supplier_action.text(),
                              self.next_order_for_supplier),
                             (self.previous_order_for_supplier_action.text(),
                              self.previous_order_for_supplier),
                             (_("Action"), self.show_actions)])
        navigation.buttons[2].setObjectName("specialMenuButton")

        self.action_menu = QMenu(navigation.buttons[2])
        list_actions = [(self.print_supply_order_action, None),
                        (self.save_supply_order_action, None),
                        (self.delete_supply_order_action, None),
                        (self.change_supplier_action, None)]

        populate_menu(self.action_menu,
                      self,
                      list_actions,
                      context=Qt.WidgetWithChildrenShortcut)

        self.title_widget = TitleWidget(_("Supply order"), self, navigation)
        self.supplier_plate_widget = SupplierPlateWidget(self)
        self.edit_comment_widget = DescribedTextEdit(_("Comments"))
        self.edit_comment_widget.setMinimumHeight(20)
        self.edit_comment_widget.setMinimumWidth(600)
        self.edit_comment_widget.setMaximumHeight(60)
        self.edit_comment_widget.setSizePolicy(QSizePolicy.Preferred,
                                               QSizePolicy.Preferred)

        self.supplier_reference_widget = QLineEdit()

        self.delivery_date_widget = DateEntryWidget()
        self.delivery_date_widget.setMaximumWidth(100)

        self.creation_date_widget = QLabel()

        self.in_title_label = QLabel()

        top_layout1 = QHBoxLayout()
        top_layout1.addWidget(self.in_title_label)
        top_layout1.addStretch()
        top_layout1.addWidget(self.supplier_plate_widget)

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel(_("Delivery date")))
        hlayout.addWidget(self.delivery_date_widget)
        hlayout.addStretch()

        hlayout3 = QHBoxLayout()
        hlayout3.addWidget(QLabel(_("Creation date")))
        hlayout3.addWidget(self.creation_date_widget)
        hlayout3.addStretch()

        hlayout2 = QHBoxLayout()
        hlayout2.addWidget(QLabel(_("Supplier's reference")))
        hlayout2.addWidget(self.supplier_reference_widget)
        hlayout2.addStretch()

        vlayout = QVBoxLayout()
        vlayout.addLayout(hlayout)  # delivery date
        vlayout.addLayout(hlayout3)  # creation date
        vlayout.addLayout(hlayout2)  # reference
        vlayout.addStretch()

        top_layout2 = QHBoxLayout()
        top_layout2.addLayout(vlayout)
        top_layout2.addWidget(self.edit_comment_widget)
        top_layout2.addStretch()
        top_layout2.setStretch(0, 0)
        top_layout2.setStretch(1, 0)
        # For some reason, the stretch added above is not enough
        # to push the whole layout to the left. I have to set
        # it's stretch factor too...
        top_layout2.setStretch(2, 100)

        vhead_layout = QVBoxLayout()
        vhead_layout.addWidget(self.title_widget)
        top_layout1.setContentsMargins(4, 0, 4, 0)
        # vhead_layout.addLayout(top_layout1)
        vhead_layout.addWidget(InlineSubFrame(top_layout1, None))

        vhead_layout.addLayout(top_layout2)
        # top_layout2.setContentsMargins(4,4,4,4)
        #vhead_layout.addWidget(InlineSubFrame(top_layout2,None))

        vhead_layout.addWidget(self.controller_part.view)
        vhead_layout.setStretch(0, 0)
        vhead_layout.setStretch(1, 0)
        vhead_layout.setStretch(2, 0)
        vhead_layout.setStretch(3, 10)

        self.setLayout(vhead_layout)

        self.controller_part.view.enable_edit_panel()

        # Handling changes in the model (helpful to know if saving
        # is necessary)

        self.model_data_changed = False
        self.model.rowsInserted.connect(self.data_changed_slot)
        self.model.rowsRemoved.connect(self.data_changed_slot)
        self.model.dataChanged.connect(self.data_changed_slot)
        self.supplier_reference_widget.textChanged.connect(
            self.data_changed2_slot)
        self.edit_comment_widget.textChanged.connect(self.data_changed2_slot)
        self.delivery_date_widget.textChanged.connect(self.data_changed2_slot)
コード例 #6
0
    def __init__(self, dao, parent, edit_date):
        super(EditTaskActionReportsDialog, self).__init__(parent)

        title = _("Task actions records")
        self.setWindowTitle(title)

        self.dao = dao

        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title, self)
        top_layout.addWidget(self.title_widget)

        hlayout = QHBoxLayout()
        self.timesheet_info_label = QLabel("Name", self)
        hlayout.addWidget(self.timesheet_info_label)
        hlayout.addStretch()
        top_layout.addLayout(hlayout)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton(QDialogButtonBox.Ok)

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

        prototype.append(
            OrderPartOnTaskPrototype(None,
                                     _('Order Part'),
                                     editable=True,
                                     nullable=True))

        # BUG today is wrong... Must be the imputation date
        self.task_on_orderpart_prototype = TaskOnOrderPartPrototype(
            'task',
            _('Task'),
            on_date=date.today(),
            editable=True,
            nullable=True)
        prototype.append(self.task_on_orderpart_prototype)

        prototype.append(
            TaskActionTypePrototype('kind',
                                    _('Action'),
                                    editable=True,
                                    nullable=False))
        prototype.append(
            TimestampPrototype('time',
                               _('Hour'),
                               editable=True,
                               nullable=False,
                               fix_date=edit_date))
        prototype.append(
            TimestampPrototype('report_time', _('Recorded at'),
                               editable=False))
        prototype.append(
            TextLinePrototype('origin_location', _('Origin'), editable=False))
        prototype.append(
            TextLinePrototype('editor',
                              _('Editor'),
                              editable=False,
                              default='master'))

        self.controller = PrototypeController(self, prototype)
        self.controller.setModel(TrackingProxyModel(self, prototype))
        self.controller.view.enable_edit_panel()

        top_layout.addWidget(self.controller.view)  # self.time_tracks_view)
        top_layout.addWidget(self.buttons)
        self.setLayout(top_layout)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
コード例 #7
0
class EditTaskActionReportsDialog(QDialog):
    def __init__(self, dao, parent, edit_date):
        super(EditTaskActionReportsDialog, self).__init__(parent)

        title = _("Task actions records")
        self.setWindowTitle(title)

        self.dao = dao

        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title, self)
        top_layout.addWidget(self.title_widget)

        hlayout = QHBoxLayout()
        self.timesheet_info_label = QLabel("Name", self)
        hlayout.addWidget(self.timesheet_info_label)
        hlayout.addStretch()
        top_layout.addLayout(hlayout)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton(QDialogButtonBox.Ok)

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

        prototype.append(
            OrderPartOnTaskPrototype(None,
                                     _('Order Part'),
                                     editable=True,
                                     nullable=True))

        # BUG today is wrong... Must be the imputation date
        self.task_on_orderpart_prototype = TaskOnOrderPartPrototype(
            'task',
            _('Task'),
            on_date=date.today(),
            editable=True,
            nullable=True)
        prototype.append(self.task_on_orderpart_prototype)

        prototype.append(
            TaskActionTypePrototype('kind',
                                    _('Action'),
                                    editable=True,
                                    nullable=False))
        prototype.append(
            TimestampPrototype('time',
                               _('Hour'),
                               editable=True,
                               nullable=False,
                               fix_date=edit_date))
        prototype.append(
            TimestampPrototype('report_time', _('Recorded at'),
                               editable=False))
        prototype.append(
            TextLinePrototype('origin_location', _('Origin'), editable=False))
        prototype.append(
            TextLinePrototype('editor',
                              _('Editor'),
                              editable=False,
                              default='master'))

        self.controller = PrototypeController(self, prototype)
        self.controller.setModel(TrackingProxyModel(self, prototype))
        self.controller.view.enable_edit_panel()

        top_layout.addWidget(self.controller.view)  # self.time_tracks_view)
        top_layout.addWidget(self.buttons)
        self.setLayout(top_layout)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)

        # self.resize(640,400)

    def keyPressEvent(self, event):

        # The goal here is to make sure the accept signal is called only
        # if the user clicks on the "OK" button /with the mouse/ and,
        # not with the keyboard

        if event.key() in (Qt.Key_Enter, Qt.Key_Return):
            return
        else:
            super(EditTaskActionReportsDialog, self).keyPressEvent(event)

    def set_employee_date(self, employee, d):
        self.current_employee = employee
        self.current_date = d

        self.timesheet_info_label.setText(
            _("Time recordings for <b>{}</b> on <b>{}</b>").format(
                employee.fullname, date_to_s(d, True)))

        self.controller.model._buildModelFromObjects(
            dao.task_action_report_dao.get_reports_for_employee_on_date(
                employee, d))

        for i in range(len(self.controller.model.objects)):
            if self.controller.model.objects[i]:
                row = self.controller.model.table[i]
                obj = self.controller.model.objects[i].task

                if isinstance(obj, TaskOnOrder):
                    row[0] = obj.order
                elif isinstance(obj, TaskOnOperation):
                    row[0] = obj.operation.production_file.order_part
                elif isinstance(obj, TaskOnNonBillable):
                    row[0] = ""
                elif obj is None:
                    row[0] = ""
                else:
                    raise Exception("Can't work with type {}".format(
                        type(obj)))

        self.controller.model_data_changed = False  # FIXME dirty (encapsulate in controller plz)

    def save(self):
        errors = self.controller.model.validate()
        if errors is not None:
            showTableEntryErrorBox(errors)
            return False

        results = self.controller.model.model_to_objects(
            lambda: TaskActionReport(), None)

    def save(self):
        mainlog.debug("EditTimeTracksDialog.save()")
        errors = self.controller.model.validate()
        if errors:
            showTableEntryErrorBox(errors)
            return False

        try:
            to_delete, to_create, to_update = self.controller.model.filter_db_updates(
                self.controller.model.model_to_objects(
                    lambda: TaskActionReport()))
            self.dao.task_action_report_dao.multi_update(
                to_delete, to_create, to_update, self.current_employee)
            return True
        except Exception as e:
            msgBox = makeErrorBox(
                _("There was an error while saving your data"), str(e))
            msgBox.exec_()
            return False

    @Slot()
    def accept(self):
        if self.save():
            super(EditTaskActionReportsDialog, self).accept()
            self.deleteLater()

    @Slot()
    def reject(self):
        super(EditTaskActionReportsDialog, self).reject()
        self.deleteLater()
コード例 #8
0
ファイル: TimeTracksOverview.py プロジェクト: mobidian/koi
class TimeTracksOverviewWidget(QWidget):

    @Slot(QModelIndex)
    def cell_entered(self,ndx):
        chrono = datetime.now()

        employee = self.employees[ndx.row()]

        a = max(1,ndx.column())
        d = date(self.base_date.year,self.base_date.month,min(calendar.monthrange(self.base_date.year,self.base_date.month)[1], max(1,ndx.column())))
        # print employee, d

        # Fill in the timetracks report panel ----------------------------

        # First we read the timetrackss and their associated OrderPart

        t_start = datetime(d.year,d.month,d.day,0,0,0,0)
        t_end = datetime(d.year,d.month,d.day,23,59,59,999999)

        # FIXME not abstract enough
        # FIXME This should be in the DAO

        tt = session().query(TimeTrack,OrderPart).\
            join(TaskOnOperation).join(Operation).join(ProductionFile).join(OrderPart).\
            filter(and_(TimeTrack.employee == employee,
                        TimeTrack.start_time >= t_start,
                        TimeTrack.start_time <= t_end)).order_by(asc(TimeTrack.start_time)).all()

        tt += session().query(TimeTrack,Order).join(TaskOnOrder).join(Order).filter(and_(TimeTrack.employee == employee, TimeTrack.start_time >= t_start, TimeTrack.start_time <= t_end)).order_by(asc(TimeTrack.start_time)).all()

        tt += session().query(TimeTrack,OperationDefinition).join(TaskOnNonBillable).join(OperationDefinition).filter(and_(TimeTrack.employee == employee, TimeTrack.start_time >= t_start, TimeTrack.start_time <= t_end)).order_by(asc(TimeTrack.start_time)).all()


        # Fill in the report panel ---------------------------------------

        self.hours_on_day_subframe.set_title(_("Hours worked on the {} by {}").format(date_to_s(d,True),employee.fullname))
        self.controller.model._buildModelFromObjects(map(lambda o : o[0],tt)) #     dao.timetrack_dao.all_for_employee(employee))

        # self.controller.model.row_protect_func = lambda obj,row: obj is not None and obj.managed_by_code

        ndx = 0
        for row in self.controller.model.table:
            if row[1]:
                row[0] = tt[ndx][1] # First column becomes the order
            ndx += 1

        self.controller.view.resizeColumnsToContents()


        # Fill in the time report panel ---------------------------------

        self.pointage_timestamp_prototype.set_fix_date(d)
        self.controller_actions.model._buildModelFromObjects(
            dao.task_action_report_dao.get_reports_for_employee_on_date(employee,d))


    @Slot()
    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)

        # self.cell_entered(self.table_view.currentIndex())


    @Slot()
    def month_today(self):
        self.base_date = date.today()
        self.refresh_action()


    @Slot()
    def month_before(self):
        m = self.base_date.month

        if m > 1:
            self.base_date = date(self.base_date.year,m - 1,self.base_date.day)
        else:
            self.base_date = date(self.base_date.year - 1,12,self.base_date.day)
        self.refresh_action()

    @Slot()
    def month_after(self):
        m = self.base_date.month

        if self.base_date.year < date.today().year or m < date.today().month:
            if m < 12:
                self.base_date = date(self.base_date.year,m + 1,self.base_date.day)
            else:
                self.base_date = date(self.base_date.year + 1,1,self.base_date.day)
            self.refresh_action()

    @Slot()
    def edit_timetrack_no_ndx(self):
        ndx = self.table_view.currentIndex()
        if ndx.isValid() and ndx.column() >= 0 and ndx.row() >= 0:
            self.edit_timetrack(ndx)
        else:
            showWarningBox(_("Can't edit"),_("You must first select a day/person."))


    @Slot(QModelIndex)
    def edit_timetrack(self,ndx):
        global dao
        global user_session

        if not user_session.has_any_roles(['TimeTrackModify']):
            return

        m = self.base_date.month
        edit_date = date(self.base_date.year,m,ndx.column()) # +1 already in because of employee's names
        employee = self._table_model.data(self._table_model.index(ndx.row(),0),Qt.UserRole) # FIXME Use a delegate
        d = EditTimeTracksDialog(self,dao,edit_date)
        d.set_employee_and_date(employee,edit_date)
        d.exec_()
        if d.result() == QDialog.Accepted:
            self.refresh_action()
        d.deleteLater()


    @Slot()
    def editTaskActionReports(self):
        if not user_session.has_any_roles(['TimeTrackModify']):
            return

        m = self.base_date.month
        ndx = self.table_view.currentIndex()

        if ndx.isValid() and ndx.column() >= 0 and ndx.row() >= 0:
            edit_date = date(self.base_date.year,m,ndx.column()) # +1 already in because of employee's names
            employee = self._table_model.data(self._table_model.index(ndx.row(),0),Qt.UserRole) # FIXME Use a delegate

            d = EditTaskActionReportsDialog(dao,self,edit_date)
            d.set_employee_date(employee, edit_date)
            d.exec_()
            if d.result() == QDialog.Accepted:
                self.refresh_action()
            d.deleteLater()
        else:
            showWarningBox(_("Can't edit"),_("You must first select a day/person."))


    @Slot(QModelIndex)
    def timetrack_changed(self,ndx):

        selected_timetrack = self.controller.model.object_at(ndx)

        # Update the colors in the timetrack views
        # to show what action reports correspond to the
        # selected timetrack

        self.controller_actions.model.current_timetrack = selected_timetrack
        self.controller_actions.model.beginResetModel()
        self.controller_actions.model.endResetModel()

        # Make sure the first of the action reports is shown in the
        # table

        action_reports = self.controller_actions.model.objects
        for i in range(len(action_reports)-1,-1,-1):
            if action_reports[i] and action_reports[i].timetrack == selected_timetrack:
                self.controller_actions.view.scrollTo(self.controller_actions.model.index(i,0))
                break


    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()
コード例 #9
0
ファイル: TimeTracksOverview.py プロジェクト: mobidian/koi
    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()
コード例 #10
0
class EditDeliverySlipDialog(QDialog):

    # def _make_units_qaulifications_gui(self):
    #     hlayout = QHBoxLayout()
    #     for qualif in [_("Good"), _("Bad"), _("Test")]:
    #         hlayout.addWidget( QLabel(qualif))
    #         hlayout.addWidget( QLineEdit())
    #
    #     f = QGroupBox(_("Qualification of units"))
    #     f.setLayout(hlayout)
    #     return f

    def __init__(self,parent):
        global dao
        super(EditDeliverySlipDialog,self).__init__(parent)

        title = _("Create delivery slip")
        self.setWindowTitle(title)

        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title,self)
        top_layout.addWidget(self.title_widget)

        self.info_label = QLabel()
        self.info_label.setWordWrap(True)
        top_layout.addWidget(self.info_label)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton( QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton( QDialogButtonBox.Ok)

        order_part_prototype = []
        order_part_prototype.append( TextLinePrototype('human_identifier',_('Part n.'),editable=False))
        order_part_prototype.append( TextLinePrototype('description',_('Description'),editable=False))
        order_part_prototype.append( IntegerNumberPrototype('qty',_('Qty plan.'),editable=False))
        order_part_prototype.append( IntegerNumberPrototype('tex2',_('Qty so far'),editable=False))
        order_part_prototype.append( IntegerNumberPrototype(None,_('Qty out now'),nullable=True))
        self.qty_out_column = len(order_part_prototype) - 1

        # order_part_prototype.append( IntegerNumberPrototype(None,_('Reglages'),nullable=True))
        # order_part_prototype.append( IntegerNumberPrototype(None,_('Derogation'),nullable=True))
        # order_part_prototype.append( IntegerNumberPrototype(None,_('Rebus'),nullable=True))


        self.controller_part = PrototypeController(self, order_part_prototype,None,freeze_row_count=True)
        self.controller_part.view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
        self.controller_part.view.horizontalHeader().setResizeMode(1,QHeaderView.Stretch)


        self.controller_part.setModel(TrackingProxyModel(self,order_part_prototype))
        self.close_order_checkbox = QCheckBox(_("Close the order"))

        top_layout.addWidget(self.controller_part.view) # self.time_tracks_view)
        # top_layout.addWidget(self._make_units_qaulifications_gui())
        top_layout.addWidget(self.close_order_checkbox)
        top_layout.addWidget(self.buttons)
        self.setLayout(top_layout)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)

        sg = QDesktopWidget().screenGeometry()
        self.setMinimumWidth(0.5*sg.width())
        self.setMinimumHeight(0.3*sg.height())

        self.slip_id = None

    def set_data(self,order_id):
        self.slip_id = None
        self.order_id = order_id

        order = dao.order_dao.find_by_id(order_id)
        parts = list(filter(lambda part:part.qty > 0 and part.tex2 < part.qty, order.parts))
        self.controller_part.model._buildModelFromObjects(parts)

        cn = ""
        if order.customer_order_name:
            cn = u" " + _("(customer number <b>{}</b>)").format(order.customer_order_name)

        self.info_label.setText(_("Creating a new delivery slip for order <b>{}</b>{} of customer <b>{}</b>").format(order.accounting_label,cn,order.customer.fullname))

        for p in parts:
            x = p.order_part_id # Force attribute load
            session().expunge(p)

        session().commit() # FIXME let the locks go

    def _start_edit(self):
        # Out to allow testing
        ndx = self.controller_part.model.index(0,self.qty_out_column)
        self.controller_part.view.setCurrentIndex( ndx)
        self.controller_part.view.edit( ndx)

    def exec_(self):
        # Start editing the table when showing the dialog
        self._start_edit()
        super(EditDeliverySlipDialog,self).exec_()

    def save(self):
        return True

    @Slot()
    def accept(self):
        # I do this to make sure that if the user was editing some data
        # in the table, those data will actually be commited once he
        # pushed the button

        ndx = self.controller_part.view.currentIndex()
        self.controller_part.view.setCurrentIndex(self.controller_part.model.index(0,0))
        self.controller_part.view.setCurrentIndex(ndx)

        if self.make_delivery_slip() == True:
            super(EditDeliverySlipDialog,self).accept()

    @Slot()
    def reject(self):
        super(EditDeliverySlipDialog,self).reject()


    def _check_unpriced_part(self):
        t = self.controller_part.model

        parts = dict()
        for p in dao.order_part_dao.find_by_order_id(self.order_id):
            parts[p.order_part_id] = p

        for i in range(t.rowCount()):
            if t.objects[i]:
                qty = t.data( t.index(i,self.qty_out_column), Qt.UserRole) or 0
                order_part_id = t.objects[i].order_part_id
                if qty > 0 and parts[order_part_id].sell_price == 0:
                    return True


    def _check_for_quantities_too_big(self):
        t = self.controller_part.model
        too_big = False
        order = dao.order_dao.find_by_id(self.order_id)
        for i in range(t.rowCount()):
            if t.objects[i]:
                qty = t.data( t.index(i,self.qty_out_column), Qt.UserRole) or 0
                order_part_id = t.objects[i].order_part_id
                for part in order.parts:
                    if part.order_part_id == order_part_id:
                        if part.tex2 + qty > part.qty:
                            too_big = True
                            break
        session().commit()

        return too_big




    def make_delivery_slip(self):
        global dao

        t = self.controller_part.model

        # mainlog.debug(u"make_delivery_slip() {}".format(t.objects))

        # Extract the quantities to get out from the order part table

        parts_ids_quantities = dict()

        info = u""
        for i in range(t.rowCount()):
            qty = t.data( t.index(i,self.qty_out_column), Qt.UserRole) or 0
            order_part = t.objects[i]

            mainlog.debug("Line {} qty = {}, order part={} ".format(i,qty, order_part is not None))

            if order_part and qty > 0:

                if order_part.order_part_id not in parts_ids_quantities:
                    parts_ids_quantities[order_part.order_part_id] = 0
                parts_ids_quantities[order_part.order_part_id] += qty

                info = info + ("<li>" + _("For {} {}, quantity {}")\
                               + "</li>").format(t.data( t.index(i,0), Qt.UserRole),
                                                 t.data( t.index(i,1), Qt.UserRole),
                                                 qty)

        info = u"<ul>{}</ul>".format(info)


        mainlog.debug("edit_dialog : checking for missing quantities")
        if len(parts_ids_quantities) == 0:
            showWarningBox(_("You requested to create a new delivery slip. However, you didn't encode any quantities"),None,None,"quantity_missing")
            return False

        mainlog.debug("edit_dialog : checking for quantities")
        if self._check_for_quantities_too_big():
            showErrorBox(_("One quantity is too big"), _("Pay attention ! On some parts, you gave a quantity out that will make the total quantity out bigger than what was ordered. You must either change the quantity out or change the planned quantity."),None,"quantityTooBig")
            return False

        if self._check_unpriced_part():
            showWarningBox(_("Some of the parts you want to make a delivery slip for have a null sell price. This is not an error but you may want to double check that situation."),None,None,"unpriced_part")

        mainlog.debug("edit_dialog : confirmationBox to be opened order_id is {}".format(self.order_id))

        if confirmationBox(u"<font color='red'><b>{}</b></font>".format(_("<b>You're about to make a new delivery slip. This can't be reversed, please confirm.\n Here are the quantities you're going to record")),info,"confirmDSCreation"):
            mainlog.debug("confirmationBox was OK")
            try:
                self.slip_id = dao.delivery_slip_part_dao.make_delivery_slip_for_order(
                    self.order_id,
                    parts_ids_quantities,
                    datetime.now(),
                    self.close_order_checkbox.checkState() == Qt.Checked)

                mainlog.debug("A delivery slip was created {}".format(self.slip_id))

                return True
            except Exception as ex:
                showErrorBox(_("Error while creating the delivery slip"),
                             _("The delivery slip was not created due to an unexpected error."),ex)
                return False