def search(self, customer_id, project_id, date_from, date_to,
               users, customer_requests, invoice_number, workflow_states):

        # also search archived projects, if none are specified
        qry = DBSession.query(TimeEntry).join(TimeEntry.project).join(Project.customer).outerjoin(TimeEntry.author)
        qry = qry.options(lazyload(TimeEntry.project, TimeEntry.author, Project.customer))

        if customer_id is not colander.null:
            qry = qry.filter(Project.customer_id == customer_id)

        if project_id is not colander.null:
            qry = qry.filter(TimeEntry.project_id == project_id)

        if date_from is not colander.null:
            qry = qry.filter(TimeEntry.date>=date_from)

        if date_to is not colander.null:
            qry = qry.filter(TimeEntry.date<=date_to)

        if users:
            qry = qry.filter(TimeEntry.author_id.in_(users))

        if invoice_number:
            qry = qry.filter(TimeEntry.invoice_number==invoice_number)

        if workflow_states:
            qry = qry.filter(TimeEntry.workflow_state.in_(workflow_states))

        qry = qry.filter(te_filter_by_customer_requests(customer_requests, request=self.request))

        qry = qry.order_by(sa.desc(TimeEntry.date), sa.desc(TimeEntry.start), sa.desc(TimeEntry.creation_date))

        time_entries = self.request.filter_viewables(qry)

        proj_tickets = collections.defaultdict(set)
        for te in time_entries:
            if te.ticket is None:
                continue
            proj_tickets[te.project_id].add(te.ticket)

        # projectsmap = {
        #    'project_id': {
        #         'ticket_id': 'customer_request_id',
        #         ...
        #    },
        #    ...
        # }

        projectsmap = {}
        for project_id, ticket_ids in proj_tickets.items():
            project = DBSession.query(Project).get(project_id)
            projectsmap[project_id] = dict(ticket_store.get_requests_from_tickets(
                                            project, tuple(ticket_ids), request=self.request))

        tkts = {}
        for project_id, ticket_ids in proj_tickets.items():
            project = DBSession.query(Project).get(project_id)
            for tkt in ticket_store.get_tickets_for_project(project, request=self.request):
                tkts[(project_id, tkt['id'])] = tkt

        entries_tree = collections.defaultdict(lambda: collections.defaultdict(list))

        cr_get = DBSession.query(CustomerRequest).get

        # one nullcr for each project, to better group them
        nullcrs = dict(
                (project, NullCustomerRequest(project=project))
                for project in DBSession.query(Project)
                )


        for te in time_entries:
            if te.ticket is None:
                customer_request = nullcrs[project]
            else:
                cr_id = projectsmap[te.project_id].get(te.ticket)
                if not cr_id:
                    continue
                customer_request = cr_get(cr_id) or nullcrs[project]

            entry = {
                        'customer': te.project.customer.name.strip(),
                        'project': te.project.name.strip(),
                        'user': te.author.fullname.strip(),
                        'date': te.date.strftime('%Y-%m-%d'),
                        'contract': te.contract,
                        'description': te.description,
                        'hours_str': te.hours_str,
                        'workflow_state': te.workflow_state,
                        'tickettype': te.tickettype,
                        'invoice_number': te.invoice_number,
                        'location': te.location,
                        'id': te.id,
                    }

            if te.ticket is None:
                ticket_description = '(no ticket)'
            else:
                tkt = tkts[(te.project_id, te.ticket)]
                href = ticket_url(request=self.request,
                                  project=te.project,
                                  ticket_id=te.ticket)
                ticket_description = HTML.SPAN(
                                            HTML.A('#%(id)s - %(summary)s' % tkt, href=href),
                                            ' ',
                                            HTML.SUP(tkt['type']),
                                            )

            entries_tree[customer_request][ticket_description].append(entry)

        return {
                'entries_tree': entries_tree,
                }
Beispiel #2
0
    def search(self, customer_id, project_id, date_from, date_to,
               users, customer_requests, workflow_states, detail_level, render_links=True):

        # also search archived projects, if none are specified
        qry = DBSession.query(TimeEntry).join(TimeEntry.project).join(Project.customer).outerjoin(TimeEntry.author)
        qry = qry.options(lazyload(TimeEntry.project, TimeEntry.author, Project.customer))

        if customer_id is not colander.null:
            qry = qry.filter(Project.customer_id == customer_id)

        if project_id is not colander.null:
            qry = qry.filter(TimeEntry.project_id == project_id)

        if date_from is not colander.null:
            qry = qry.filter(TimeEntry.date>=date_from)

        if date_to is not colander.null:
            qry = qry.filter(TimeEntry.date<=date_to)

        if users:
            qry = qry.filter(TimeEntry.author_id.in_(users))

        if workflow_states:
            qry = qry.filter(TimeEntry.workflow_state.in_(workflow_states))

        qry = qry.filter(te_filter_by_customer_requests(customer_requests, request=self.request))

        qry = qry.order_by(sa.desc(TimeEntry.date), sa.desc(TimeEntry.start), sa.desc(TimeEntry.creation_date))

        time_entries = self.request.filter_viewables(qry)

        proj_tickets = collections.defaultdict(set)
        for te in time_entries:
            if te.ticket is None:
                continue
            proj_tickets[te.project_id].add(te.ticket)

        # projectsmap = {
        #    'project_id': {
        #         'ticket_id': 'customer_request_id',
        #         ...
        #    },
        #    ...
        # }

        projectsmap = {}
        for project_id, ticket_ids in proj_tickets.items():
            project = DBSession.query(Project).get(project_id)
            projectsmap[project_id] = dict(ticket_store.get_requests_from_tickets(
                                            project, tuple(ticket_ids), request=self.request))

        tkts = {}
        for project_id, ticket_ids in proj_tickets.items():
            project = DBSession.query(Project).get(project_id)
            for tkt in ticket_store.get_tickets_for_project(project, request=self.request):
                tkts[(project_id, tkt['id'])] = tkt

        rows = []

        cr_get = DBSession.query(CustomerRequest).get

        for te in time_entries:
            if te.ticket is None:
                rendered_request = NullCustomerRequest().name
                ticket_type = '-'
                ticket_summary = '-'
            else:
                cr_id = projectsmap[te.project_id].get(te.ticket)
                if not cr_id:
                    continue

                customer_request = cr_get(cr_id)
                if customer_request:
                    if render_links:
                        rendered_request = HTML.A(customer_request.name.strip(),
                                                  href="%s/admin/CustomerRequest/%s" % (
                                                      self.request.application_url,
                                                      customer_request.id
                                                      )
                                                  )
                    else:
                        rendered_request = customer_request.name.strip()
                else:
                    rendered_request = NullCustomerRequest().name


                tkt = tkts[(te.project_id, te.ticket)]

                ticket_type = tkt['type']
                ticket_summary = tkt['summary']
                if render_links:
                    ticket_summary = HTML.A(ticket_summary,
                                            href=ticket_url(request=self.request,
                                                            project=te.project,
                                                            ticket_id=te.ticket))

                description = HTML.A(te.description,
                                     href=timeentry_url(request=self.request,
                                                        time_entry=te))


            entry = {
                        'customer': te.project.customer.name.strip(),
                        'project': te.project.name.strip(),
                        'request': rendered_request,
                        'ticket_summary': ticket_summary,
                        'user': te.author.fullname.strip(),
                        'date': te.date.strftime('%Y-%m-%d'),
                        'description': description,
                        'location': te.location,
                        'ticket_type': ticket_type,
                        'sensitive': ['no', 'yes'][tkt['sensitive']],
                        'hours': te.hours,
                    }

            event = AfterEntryCreatedEvent(entry, te)
            self.request.registry.notify(event)

            rows.append(entry)

        columns = [
                    ('customer', u'Cliente'),
                    ('project', u'Progetto'),
                    ('request', u'Request'),
                    ('ticket_summary', u'Ticket'),
                    ('ticket_type', u'Tipologia'),
                    ('sensitive', u'Sensitive'),
                    ('user', u'Persona'),
                    ('date', u'Data'),
                    ('description', u'Descrizione attività'),
                    ('location', u'Sede'),
                    ('hours', u'Ore'),
                ]

        group_by = {
                    'project': ['customer', 'project', 'user'],
                    'request': ['customer', 'project', 'request', 'user'],
                    'ticket': ['customer', 'project', 'request', 'ticket_summary', 'ticket_type', 'sensitive', 'user'],
                    'timeentry': None,
                    'date': ['user', 'date', 'location'],
                }[detail_level]

        if group_by:
            rows, columns = self.group(rows, columns, group_by)

        return {
                'rows': rows,
                'columns': columns,
                }
    def search(self, customer_id, project_id, date_from, date_to,
               users, customer_requests, groupbyfirst):

        # also search archived projects, if none are specified
        qry = DBSession.query(TimeEntry).join(TimeEntry.project).join(Project.customer).outerjoin(TimeEntry.author)
        qry = qry.options(lazyload(TimeEntry.project, TimeEntry.author, Project.customer))

        groupby = ['customer']

        groupby.extend(groupbyfirst.split('.'))

        if customer_id is not colander.null:
            qry = qry.filter(Project.customer_id == customer_id)
            groupby.remove('customer')

        if project_id is not colander.null:
            qry = qry.filter(TimeEntry.project_id == project_id)
            try:
                groupby.remove('customer')
            except ValueError:
                pass
            groupby.remove('project')

        if date_from is not colander.null:
            qry = qry.filter(TimeEntry.date>=date_from)

        if date_to is not colander.null:
            qry = qry.filter(TimeEntry.date<=date_to)

        if date_from == date_to and date_from is not colander.null:
            groupby.remove('date')

        if users:
            qry = qry.filter(TimeEntry.author_id.in_(users))

        qry = qry.filter(te_filter_by_customer_requests(customer_requests, request=self.request))

        rows = []

        id_tree = IDTree()

        time_entries = list(self.request.filter_viewables(qry))

        proj_tickets = collections.defaultdict(set)
        for te in time_entries:
            if te.ticket is None:
                continue
            proj_tickets[te.project_id].add(te.ticket)

        # projectsmap = {
        #    'project_id': {
        #         'ticket_id': 'customer_request_id',
        #         ...
        #    },
        #    ...
        # }

        projectsmap = {}
        for project_id, ticket_ids in proj_tickets.items():
            project = DBSession.query(Project).get(project_id)
            if not self.request.has_permission('reports_all_entries_for_project', project):
                continue
            projectsmap[project_id] = dict(ticket_store.get_requests_from_tickets(
                                            project, tuple(ticket_ids), request=self.request))

        cr_get = DBSession.query(CustomerRequest).get

        nullcr = NullCustomerRequest()

        for te in time_entries:
            if te.ticket is None:
                customer_request = nullcr
            else:
                if not self.request.has_permission('reports_all_entries_for_project', te.project):
                    continue
                cr_id = projectsmap[te.project_id].get(te.ticket)
                if not cr_id:
                    continue
                customer_request = cr_get(cr_id) or nullcr

            entry = {
                        'customer': te.project.customer.name.strip(),
                        'project': te.project.name.strip(),
                        'request': customer_request.name.strip(),
                        'user': te.author.fullname.strip(),
                        'date': te.date.strftime('%Y-%m-%d'),
                        'description': te.description,
                        'seconds': total_seconds(te.hours),
                        'time': 'ore',
                    }

            rows.append(entry)
            id_tree.insert_entry(groupby, te.id, **entry)

        return {
                'groupby': groupby,
                'rows': rows,
                'id_tree': id_tree,
                }