示例#1
0
class ProjectsList(BaseListView):
    """
    The project list view is compound of :
        * the list of projects with action buttons (view, delete ...)
        * an action menu with:
            * links
            * an add projectform popup
            * a searchform
    """
    add_template_vars = ('title', 'stream_actions', 'addform')
    title = u"Liste des projets"
    schema = get_list_schema()
    default_sort = "created_at"
    default_direction = "desc"
    sort_columns = {
        'name': Project.name,
        "code": Project.code,
        "created_at": Project.created_at,
    }

    def query(self):
        company = self.request.context
        # We can't have projects without having customers
        if not company.customers:
            redirect_to_customerslist(self.request, company)
        main_query = DBSESSION().query(distinct(Project.id), Project)
        main_query = main_query.outerjoin(Project.customers)
        return main_query.filter(Project.company_id == company.id)

    def filter_archived(self, query, appstruct):
        archived = appstruct.get('archived', False)
        if archived in (False, colander.null):
            query = query.filter(Project.archived == False)
        return query

    def filter_name_or_customer(self, query, appstruct):
        search = appstruct['search']
        if search:
            query = query.filter(
                or_(
                    Project.name.like("%" + search + "%"),
                    Project.customers.any(
                        Customer.name.like("%" + search + "%"))))
        return query

    @property
    def addform(self):
        res = None
        if self.request.has_permission('add_project'):
            form = get_project_form(self.request)
            res = form.render()
        return res

    def stream_actions(self, project):
        """
        Stream actions available for the given project

        :param obj project: A Project instance
        :rtype: generator
        """
        yield (self.request.route_path("project", id=project.id),
               u"Voir/Modifier", u"Voir/Modifier", u"pencil", {})
        if self.request.has_permission('add_estimation', project):
            yield (self.request.route_path("project_estimations",
                                           id=project.id), u"Nouveau devis",
                   u"Créer un devis", u"file", {})
        if self.request.has_permission('add_invoice', project):
            yield (self.request.route_path("project_invoices", id=project.id),
                   u"Nouvelle facture", u"Créer une facture", u"file", {})
        if self.request.has_permission('edit_project', project):
            if project.archived:
                yield (self.request.route_path("project",
                                               id=project.id,
                                               _query=dict(action="archive")),
                       u"Désarchiver le projet", u"Désarchiver le projet",
                       u"book", {})
            else:
                yield (self.request.route_path("project",
                                               id=project.id,
                                               _query=dict(action="archive")),
                       u"Archiver le projet", u"Archiver le projet", u"book",
                       {})
        if self.request.has_permission('delete_project', project):
            yield (self.request.route_path("project",
                                           id=project.id,
                                           _query=dict(action="delete")),
                   u"Supprimer", u"Supprimer ce projet", u"trash", {
                       "onclick": (u"return confirm('Êtes-vous sûr de "
                                   "vouloir supprimer ce projet ?')")
                   })
示例#2
0
class ProjectListView(BaseListView, TreeMixin):
    """
    The project list view is compound of :
        * the list of projects with action buttons (view, delete ...)
        * an action menu with:
            * links
            * an add projectform popup
            * a searchform
    """
    add_template_vars = ('title', 'stream_actions', 'add_url')
    title = u"Liste des projets"
    schema = get_list_schema()
    default_sort = "created_at"
    default_direction = "desc"
    sort_columns = {
        'name': Project.name,
        "code": Project.code,
        "created_at": Project.created_at,
    }
    route_name = COMPANY_PROJECTS_ROUTE
    item_route_name = PROJECT_ITEM_ROUTE

    @property
    def tree_url(self):
        """
        Compile the url to be used in the breadcrumb for this view
        The context can be either :
            A Project
            A Business
            A Task
        """
        if isinstance(self.context, Company):
            cid = self.context.id
        elif isinstance(self.context, Project):
            cid = self.context.company_id
        elif hasattr(self.context, 'project'):
            cid = self.context.project.company_id
        else:
            raise Exception(
                u"Can't retrieve company id for breadcrumb generation %s" %
                (self.context, ))
        return self.request.route_path(self.route_name, id=cid)

    def query(self):
        company = self.request.context
        # We can't have projects without having customers
        if not company.customers:
            redirect_to_customerslist(self.request, company)
        main_query = DBSESSION().query(distinct(Project.id), Project)
        main_query = main_query.outerjoin(Project.customers)
        return main_query.filter(Project.company_id == company.id)

    def filter_archived(self, query, appstruct):
        archived = appstruct.get('archived', False)
        if archived in (False, colander.null):
            query = query.filter(Project.archived == False)
        return query

    def filter_name_or_customer(self, query, appstruct):
        search = appstruct['search']
        if search:
            query = query.filter(
                or_(
                    Project.name.like("%" + search + "%"),
                    Project.customers.any(
                        Customer.label.like("%" + search + "%"))))
        return query

    def filter_project_type(self, query, appstruct):
        val = appstruct.get('project_type_id')
        if val:
            query = query.filter(Project.project_type_id == val)
        return query

    def stream_actions(self, project):
        """
        Stream actions available for the given project

        :param obj project: A Project instance
        :rtype: generator
        """
        yield Link(
            self._get_item_url(project),
            u"Voir/Modifier",
            icon=u"pencil",
        )
        if self.request.has_permission('add_estimation', project):
            yield Link(
                self.request.route_path(
                    PROJECT_ITEM_ESTIMATION_ROUTE,
                    id=project.id,
                    _query={'action': 'add'},
                ),
                u"Nouveau devis",
                icon=u"file",
            )
        if self.request.has_permission('add_invoice', project):
            yield Link(
                self.request.route_path(
                    PROJECT_ITEM_INVOICE_ROUTE,
                    id=project.id,
                    _query={'action': 'add'},
                ),
                u"Nouvelle facture",
                icon=u"file",
            )
        if self.request.has_permission('edit_project', project):
            if project.archived:
                yield Link(
                    self._get_item_url(project, action='archive'),
                    u"Désarchiver le projet",
                    icon=u"book",
                )
            else:
                yield Link(
                    self._get_item_url(project, action='archive'),
                    u"Archiver le projet",
                    icon=u"book",
                )
        if self.request.has_permission('delete_project', project):
            yield Link(
                self._get_item_url(project, action='delete'),
                u"Supprimer",
                icon=u"trash",
                confirm=u'Êtes-vous sûr de vouloir supprimer ce projet ?')

    @property
    def add_url(self):
        return self.request.route_path(COMPANY_PROJECTS_ROUTE,
                                       id=self.context.id,
                                       _query={'action': 'add'})
示例#3
0
class ProjectsList(BaseListView):
    """
    The project list view is compound of :
        * the list of projects with action buttons (view, delete ...)
        * an action menu with:
            * links
            * an add projectform popup
            * a searchform
    """
    add_template_vars = (
        'title',
        'item_actions',
    )
    title = u"Liste des projets"
    schema = get_list_schema()
    default_sort = "name"
    sort_columns = {
        'name': Project.name,
        "code": Project.code,
    }

    def query(self):
        company = self.request.context
        # We can't have projects without having customers
        if not company.customers:
            redirect_to_customerslist(self.request, company)
        main_query = DBSESSION().query(distinct(Project.id), Project)
        main_query = main_query.outerjoin(Project.customers)
        return main_query.filter(Project.company_id == company.id)

    def filter_archived(self, query, appstruct):
        archived = appstruct['archived']
        return query.filter(Project.archived == archived)

    def filter_name_or_customer(self, query, appstruct):
        search = appstruct['search']
        if search:
            query = query.filter(
                or_(
                    Project.name.like("%" + search + "%"),
                    Project.customers.any(
                        Customer.name.like("%" + search + "%"))))
        return query

    def populate_actionmenu(self, appstruct):
        populate_actionmenu(self.request)
        if has_permission('add', self.request.context, self.request):
            form = get_project_form(self.request)
            popup = PopUp('add', u"Ajouter un projet", form.render())
            self.request.popups = {popup.name: popup}
            self.request.actionmenu.add(popup.open_btn())
        self.request.actionmenu.add(self._get_archived_btn(appstruct))

    def _get_archived_btn(self, appstruct):
        """
            return the show archived button
        """
        archived = appstruct['archived']
        if not archived:
            url = self.request.current_route_path(_query=dict(archived="true"))
            link = HTML.a(u"Afficher les projets archivés", href=url)
        else:
            url = self.request.current_route_path(_query=dict(
                archived="false"))
            link = HTML.a(u"Afficher les projets actifs", href=url)
        return StaticWidget(link)

    @property
    def item_actions(self):
        """
            return action buttons builder
        """
        return self._get_actions()

    def _get_actions(self):
        """
            Return action buttons with permission handling
        """
        btns = []
        btns.append(
            ItemActionLink(u"Voir",
                           "view",
                           css='btn btn-default btn-sm',
                           path="project",
                           icon="search"))
        btns.append(
            ItemActionLink(
                u"Devis",
                "edit",
                css="btn btn-default btn-sm",
                title=u"Nouveau devis",
                path="project_estimations",
                icon="file",
            ))
        btns.append(
            ItemActionLink(
                u"Facture",
                "edit",
                css="btn btn-default btn-sm",
                title=u"Nouvelle facture",
                path="project_invoices",
                icon="file",
            ))
        if self.request.params.get('archived', '0') in ('0', 'false'):
            btns.append(
                ItemActionLink(
                    u"Archiver",
                    "edit",
                    css="btn btn-default btn-sm",
                    confirm=u'Êtes-vous sûr de vouloir archiver ce projet ?',
                    path="project",
                    title=u"Archiver le projet",
                    _query=dict(action="archive"),
                    icon="book",
                ))
        else:
            btns.append(
                ItemActionLink(
                    u"Désarchiver",
                    "edit",
                    css="btn btn-default btn-sm",
                    path="project",
                    title=u"Désarchiver le projet",
                    _query=dict(action="archive"),
                    icon="book",
                ))
            del_link = ItemActionLink(
                u"Supprimer",
                "edit",
                css="btn btn-danger",
                confirm=u'Êtes-vous sûr de vouloir supprimer ce projet ?',
                path="project",
                title=u"Supprimer le projet",
                _query=dict(action="delete"),
                icon="trash")

            def is_deletable_perm(context, req):
                """
                    Return True if the current item (context) is deletable
                """
                return context.is_deletable()

            del_link.set_special_perm_func(is_deletable_perm)
            btns.append(del_link)
        return btns