예제 #1
0
 def dispatch(self):
     client_id = self.request.GET.get('client_id')
     client = Client.query.get(client_id)
     form = ProjectForm(self.request.POST)
     if self.request.method == 'POST' and form.validate():
         tracker_id = form.tracker_id.data
         coordinator_id = int(form.coordinator_id.data) if form.coordinator_id.data.isdigit() else None
         project = Project(
             client=client,
             name=form.name.data,
             coordinator_id=coordinator_id,
             tracker_id=tracker_id,
             turn_off_selectors=form.turn_off_selectors.data,
             project_selector=form.project_selector.data,
             component_selector=form.component_selector.data,
             version_selector=form.version_selector.data,
             ticket_id_selector=form.ticket_id_selector.data,
             active=form.active.data,
             google_card=form.google_card.data,
             google_wiki=form.google_wiki.data,
             mailing_url=form.mailing_url.data,
             working_agreement=form.working_agreement.data,
             definition_of_done=form.definition_of_done.data,
             definition_of_ready=form.definition_of_ready.data,
             continuous_integration_url=form.continuous_integration_url.data,
             backlog_url=form.backlog_url.data,
             status = form.status.data,
         )
         DBSession.add(project)
         DBSession.flush()
         self.flash(self._(u"Project added"))
         LOG(u"Project added")
         SelectorMapping.invalidate_for(tracker_id)
         return HTTPFound(location=self.request.url_for('/client/view', client_id=project.client_id))
     return dict(client=client, form=form)
예제 #2
0
    def get(self):
        check_role = self.request.GET.get('role')
        if not check_role or check_role == 'None':
            pivot_q = DBSession.query(User.id, User.name, User.start_work, User.stop_work, User.roles)\
                                .filter(User.is_not_client())\
                                .filter(User.is_active==True)\
                                .order_by(User.name)
        else:
            pivot_q = DBSession.query(User.id, User.name, User.start_work, User.stop_work, User.roles)\
                                .filter(User.is_not_client())\
                                .filter(User.is_active==True)\
                                .filter(User.roles.op('&&')('{%s}'%(check_role)))\
                                .order_by(User.name)

        users = {}
        for s in pivot_q:
            if s.start_work:
                users.setdefault(s.start_work.year,
                                 [0] * 24)[s.start_work.month - 1] += 1
            if s.stop_work:
                users.setdefault(s.stop_work.year,
                                 [0] * 24)[s.stop_work.month - 1 + 12] += 1
        role = User.ROLES
        return dict(
            start=users,
            roles=role,
            check=check_role,
            quarters_sum=self._quarters_sum,
            link_with_year=self._create_link_with_year,
            link_with_month=self._create_link_with_month,
            link_with_quarter=self._create_link_with_quarter,
        )
예제 #3
0
 def dispatch(self):
     form = SprintForm(self.request.POST)
     if self.request.method == 'POST' and form.validate():
         project = Project.query.get(int(form.project_id.data))
         sprint = Sprint(
             name=form.name.data,
             client_id=project.client_id,
             project_id=project.id,
             team_id=form.team_id.data or None,
             bugs_project_ids = map(int, form.bugs_project_ids.data),
             start=form.start.data,
             end=form.end.data,
             board=form.board.data,
             goal=form.goal.data,
             retrospective_note = form.retrospective_note.data,
         )
         DBSession.add(sprint)
         DBSession.flush()
         self.flash(self._(u"New sprint added"))
         LOG(u"Sprint added")
         url = self.request.url_for('/scrum/sprint/show', sprint_id=sprint.id)
         return HTTPFound(location=url)
     return dict(
         form=form,
     )
예제 #4
0
    def calculate_velocities(self):
        self.velocity = \
            8.0 * self.achieved_points / self.worked_hours \
            if self.worked_hours else 0.0

        self.story_velocity = \
            8.0 * self.achieved_points / self.bugs_worked_hours \
            if self.bugs_worked_hours else 0.0

        sprint_velocities = DBSession.query(
            Sprint.velocity,
            Sprint.story_velocity,
        ).filter(Sprint.project_id == self.project_id) \
            .filter(Sprint.id != self.id) \
            .all()

        sprint_velocities.append((self.velocity, self.story_velocity))

        velocities, story_velocities = zip(*sprint_velocities)

        self.velocity_mean = float(sum(velocities)) / len(velocities)

        self.story_velocity_mean = \
            float(sum(story_velocities)) / len(story_velocities)

        DBSession.add(self)
예제 #5
0
class UserChoices(object):
    def __init__(self, empty=False, inactive=False):
        self.empty = empty
        self.inactive = inactive
        self.session = DBSession()

    def __iter__(self):
        if self.empty:
            yield "", u"-- None --"
        query = (
            self.session.query(User.id, User.name)
            .filter(not_(User.is_client()))
            .filter(User.is_active == True)
            .order_by(User.name)
        )
        for id, name in query:
            yield str(id), name

        if self.inactive:
            yield "", " " * 8
            query = (
                self.session.query(User.id, User.name)
                .filter(User.is_client())
                .filter(User.is_active == False)
                .order_by(User.name)
            )
            for id, name in query:
                yield str(id), name
예제 #6
0
    def __init__(self, event):
        today = datetime.date.today()

        user = event['request'].user
        self.arrival = None
        if not user:
            return
        row = DBSession.query('ts').from_statement("""
            SELECT MIN(p.ts) as "ts"
            FROM presence_entry p
            WHERE DATE(p.ts) = :today
              AND p.user_id = :user_id
            """).params(today=today, user_id=user.id).first()

        if not (row and row.ts):
            return

        arrival = row.ts
        now = datetime.datetime.now()
        since_morning_hours = float((now - arrival).seconds) / 3600
        self.present = since_morning_hours
        noted = 0.0
        row = DBSession.query('time').from_statement("""
            SELECT COALESCE(SUM(t.time), 0.0) as "time"
            FROM time_entry t
            WHERE t.date = :today
              AND t.user_id = :user_id
              AND t.deleted = FALSE
            """).params(user_id=user.id, today=today).first()
        if row:
            noted = row.time
        self.noted = noted
        self.remaining = since_morning_hours - noted
        self.arrival = arrival
예제 #7
0
    def tmpl_ctx(self):

        sprint = self.v.get("sprint")
        if not sprint:
            sprint_id = self.request.GET.get("sprint_id")
            sprint = Sprint.query.get(sprint_id)
        project = Project.query.get(sprint.project_id)

        sprints = (
            DBSession.query(Sprint.project_id, Sprint.worked_hours, Sprint.bugs_worked_hours, Sprint.achieved_points)
            .filter(Sprint.project_id == sprint.project_id)
            .all()
        )

        sprint.calculate_velocities(sprints)

        self.v["project"] = project
        self.v["sprint"] = sprint

        prev_sprint = (
            DBSession.query(Sprint)
            .filter(Sprint.project_id == sprint.project_id)
            .filter(Sprint.start < sprint.start)
            .order_by(Sprint.start.desc())
            .first()
        )
        next_sprint = (
            DBSession.query(Sprint)
            .filter(Sprint.project_id == sprint.project_id)
            .filter(Sprint.start > sprint.start)
            .order_by(Sprint.start.asc())
            .first()
        )
        return dict(project=project, sprint=sprint, prev_sprint=prev_sprint, next_sprint=next_sprint)
예제 #8
0
    def post(self):
        tracker_id = self.request.GET.get('tracker_id')
        tracker = Tracker.query.get(tracker_id)
        credentials = self._get_current_users_credentials_for_tracker(tracker)
        form = TrackerLoginForm(self.request.POST, obj=credentials)

        _add_tracker_login_validator(tracker.name, form)

        if form.validate():
            if credentials is None:
                credentials = TrackerCredentials(
                    user_id=self.request.user.id,
                    tracker_id=tracker.id,
                    login=form.login.data,
                    password=form.password.data,
                )
                DBSession.add(credentials)
            else:
                credentials.login = form.login.data
                credentials.password = form.password.data
            self.flash(self._(u"Credentials saved"))
            LOG(u"Credentials saved")
            url = self.request.url_for('/tracker/list')
            return HTTPFound(location=url)
        return dict(form=form, tracker=tracker)
예제 #9
0
    def post(self):
        args = self.request.json
        year = int(args.pop('year'))
        if 1999 > year > 2099:
            return dict(status='nok', reason='Zły rok %s' % year)

        leaves = Leave.query.filter(Leave.year==year).all()
        leaves = groupby(leaves, lambda l: l.user_id)
        for user_id, (mandated, remarks) in args.iteritems():
            user_id = int(user_id)
            try:
                mandated = int(mandated)
            except Exception:
                user = User.query.get(user_id)
                return dict(
                    status='nok',
                    reason=self._(u'Wrong hours format: ${hours} for user ${name}', hours=mandated, name=user.name)
                )

            if 0 > mandated  or mandated > 99:
                user = User.query.get(user_id)
                return dict(
                    status='nok',
                    reason=self._(u'Wrong hours number: ${hours} for user ${name}', hours=mandated, name=user.name)
                )

            leave_obj = leaves.get(user_id)
            if not leave_obj:
                leave_obj = Leave(user_id=user_id, year=year)
            else:
                leave_obj = leave_obj[0]
            leave_obj.number = mandated
            leave_obj.remarks = remarks
            DBSession.add(leave_obj)
        return dict(status='ok')
예제 #10
0
    def get(self):
        check_role = self.request.GET.get('role')
        if not check_role or check_role == 'None':
            pivot_q = DBSession.query(User.id, User.name, User.start_work, User.stop_work, User.roles)\
                                .filter(User.is_not_client())\
                                .filter(User.is_active==True)\
                                .order_by(User.name)
        else:
            pivot_q = DBSession.query(User.id, User.name, User.start_work, User.stop_work, User.roles)\
                                .filter(User.is_not_client())\
                                .filter(User.is_active==True)\
                                .filter(User.roles.op('&&')('{%s}'%(check_role)))\
                                .order_by(User.name)

        users = {}
        for s in pivot_q:
            if s.start_work:
                users.setdefault(s.start_work.year, [0]*24)[s.start_work.month-1] += 1
            if s.stop_work:
                users.setdefault(s.stop_work.year, [0]*24)[s.stop_work.month-1+12] += 1
        role = User.ROLES
        return dict(
            start=users,
            roles=role,
            check=check_role,
            quarters_sum=self._quarters_sum,
            link_with_year=self._create_link_with_year,
            link_with_month=self._create_link_with_month,
            link_with_quarter=self._create_link_with_quarter,
        )
예제 #11
0
def make_admin(config_path):
    from intranet3.models import DBSession, Base
    from intranet3.models import User
    user_login = sys.argv[-1]
    if len(sys.argv) < 4:
        print u"Provide user login"
        return

    session = DBSession()

    user = session.query(User).filter(User.email==user_login).first()

    if not user:
        print u"No such user: %s" % user_login
        return

    if 'admin' in user.groups:
        print u'Removing %s from group admin' % user.name
        groups = list(user.groups)
        groups.remove('admin')
        user.groups = groups
    else:
        print u'Adding %s to group admin' % user.name
        groups = list(user.groups)
        groups.append('admin')
        user.groups = groups

    session.add(user)
    transaction.commit()
예제 #12
0
    def dispatch(self):
        form = AbsenceCreateForm(self.request.POST, request=self.request)
        days, mandated, used, left = 0, 0, 0, 0
        if form.popup_date_start.data:
            mandated, used, left = user_leave(self.request,
                                              form.popup_date_start.data.year)
            if form.popup_date_end.data:
                days = h.get_working_days(form.popup_date_start.data,
                                          form.popup_date_end.data)
                left -= days
        if self.request.method == 'POST' and form.validate():
            date_start = form.popup_date_start.data
            date_end = form.popup_date_end.data
            type = form.popup_type.data
            remarks = form.popup_remarks.data
            user_id = form.popup_user_id.data
            absence = Absence(
                user_id=user_id,
                date_start=date_start,
                date_end=date_end,
                days=days,
                type=type,
                remarks=remarks,
            )
            DBSession.add(absence)
            return Response(self._('Done') + RELOAD_PAGE)

        return dict(form=form,
                    days=days,
                    mandated=mandated,
                    used=used,
                    left=left)
예제 #13
0
def add_time(user_id, date, bug_id, project_id, hours, subject):
    # try finding existing entry for this bug
    session = DBSession()
    bug_id = str(bug_id)
    entry = TimeEntry.query.filter(TimeEntry.user_id==user_id) \
                           .filter(TimeEntry.date==date.date()) \
                           .filter(TimeEntry.ticket_id==bug_id) \
                           .filter(TimeEntry.project_id==project_id).first()
    if not entry:
        # create new entry
        entry = TimeEntry(
            user_id=user_id,
            date=date.date(),
            time=hours,
            description=subject,
            ticket_id=bug_id,
            project_id = project_id,
            modified_ts=date
        )
        session.add(entry)
        LOG(u'Adding new entry')
    else:
        # update existing entry
        if not entry.frozen:
            entry.time += hours
            entry.modified_ts = date # TODO: this might remove an already existing lateness
            session.add(entry)
            LOG(u'Updating existing entry')
        else:
            LOG(u'Omission of an existing entry because it is frozen')
예제 #14
0
    def tmpl_ctx(self):

        sprint = self.v.get('sprint')
        if not sprint:
            sprint_id = self.request.GET.get('sprint_id')
            sprint = Sprint.query.get(sprint_id)
        project = Project.query.get(sprint.project_id)

        sprint.calculate_velocities()

        self.v['project'] = project
        self.v['sprint'] = sprint

        prev_sprint = DBSession.query(Sprint)\
            .filter(Sprint.project_id == sprint.project_id)\
            .filter(Sprint.start < sprint.start)\
            .order_by(Sprint.start.desc()).first()

        next_sprint = DBSession.query(Sprint) \
            .filter(Sprint.project_id == sprint.project_id) \
            .filter(Sprint.start > sprint.start) \
            .order_by(Sprint.start.asc()).first()

        return dict(
            project=project,
            sprint=sprint,
            prev_sprint=prev_sprint,
            next_sprint=next_sprint,
        )
예제 #15
0
    def post(self):
        tracker_id = self.request.GET.get('tracker_id')
        tracker =  Tracker.query.get(tracker_id)
        credentials = self._get_current_users_credentials_for_tracker(tracker)
        form = TrackerLoginForm(self.request.POST, obj=credentials)

        _add_tracker_login_validator(tracker.name, form)

        if form.validate():
            if credentials is None:
                credentials = TrackerCredentials(
                    user_id=self.request.user.id,
                    tracker_id=tracker.id,
                    login=form.login.data,
                    password=form.password.data,
                )
                DBSession.add(credentials)
            else:
                credentials.login=form.login.data
                credentials.password=form.password.data
            self.flash(self._(u"Credentials saved"))
            LOG(u"Credentials saved")
            url = self.request.url_for('/tracker/list')
            return HTTPFound(location=url)
        return dict(form=form, tracker=tracker)
예제 #16
0
    def dispatch(self):
        subpage = self.request.GET.get('subpage', 'general')
        if subpage not in ['general', 'reports', 'spreadsheets', 'access']:
            return HTTPForbidden()

        config_obj = ApplicationConfig.get_current_config(allow_empty=True)

        FormRef = getattr(config_forms, "%sForm" % subpage.title())

        if config_obj is not None:
            LOG(u"Found config object from %s" % (config_obj.date, ))
            form = FormRef(self.request.POST, obj=config_obj)
        else:
            LOG(u"Config object not found")
            form = FormRef(self.request.POST)

        if self.request.method == 'POST' and form.validate():
            if config_obj is None:
                config_obj = ApplicationConfig()

            # Add/Edit data
            if subpage == 'general':
                config_obj.office_ip = form.office_ip.data
                config_obj.google_user_email = form.google_user_email.data
                config_obj.google_user_password = form.google_user_password.data
                config_obj.cleaning_time_presence = form.cleaning_time_presence.data
                config_obj.absence_project_id = form.absence_project_id.data if form.absence_project_id.data else None
                config_obj.monthly_late_limit = form.monthly_late_limit.data
                config_obj.monthly_incorrect_time_record_limit = form.monthly_incorrect_time_record_limit.data
            elif subpage == 'reports':
                config_obj.reports_project_ids = [
                    int(id) for id in form.reports_project_ids.data
                ]
                config_obj.reports_omit_user_ids = [
                    int(id) for id in form.reports_omit_user_ids.data
                ]
                config_obj.reports_without_ticket_project_ids = [
                    int(id)
                    for id in form.reports_without_ticket_project_ids.data
                ]
                config_obj.reports_without_ticket_omit_user_ids = [
                    int(id)
                    for id in form.reports_without_ticket_omit_user_ids.data
                ]
            elif subpage == 'spreadsheets':
                config_obj.holidays_spreadsheet = form.holidays_spreadsheet.data
                config_obj.hours_employee_project = form.hours_employee_project.data
                config_obj.hours_ticket_user_id = form.hours_ticket_user_id.data if form.hours_ticket_user_id.data else None
            elif subpage == "access":
                config_obj.freelancers = form.freelancers.data

            DBSession.add(config_obj)
            config_obj.invalidate_office_ip()

            LOG(u"Config object saved")
            self.flash(self._(u'Application Config saved'), klass='success')
            return HTTPFound(
                location=self.request.url_for('/config/view', subpage=subpage))

        return dict(form=form, subpage=subpage)
예제 #17
0
def make_admin(config_path):
    from intranet3.models import DBSession, Base
    from intranet3.models import User
    user_login = sys.argv[-1]
    if len(sys.argv) < 4:
        print u"Provide user login"
        return

    session = DBSession()

    user = session.query(User).filter(User.email == user_login).first()

    if not user:
        print u"No such user: %s" % user_login
        return

    if 'admin' in user.groups:
        print u'Removing %s from group admin' % user.name
        groups = list(user.groups)
        groups.remove('admin')
        user.groups = groups
    else:
        print u'Adding %s to group admin' % user.name
        groups = list(user.groups)
        groups.append('admin')
        user.groups = groups

    session.add(user)
    transaction.commit()
예제 #18
0
    def post(self):
        if not self.request.is_xhr:
            return HTTPBadRequest()

        date = self.v['date']
        form = TimeEntryForm(self.request.POST)

        if form.validate():
            project_id = form.project_id.data
            time = TimeEntry(date=date,
                             user_id=self.request.user.id,
                             time=form.time.data,
                             description=form.description.data,
                             ticket_id=form.ticket_id.data,
                             project_id=project_id if project_id else None)
            DBSession.add(time)
            LOG(u'Ajax - Time entry added')

            entries = self._get_time_entries(date)
            total_sum = sum(entry.time for (tracker, entry) in entries
                            if not entry.deleted)
            template = render('/times/_list.html',
                              dict(entries=entries, total_sum=total_sum),
                              request=self.request)

            return dict(status='success', html=template)

        errors = u'<br />'.join((u"%s - %s" % (field, u', '.join(errors))
                                 for field, errors in form.errors.iteritems()))
        return dict(status='error', errors=errors)
예제 #19
0
    def post(self):
        lateness = self.request.json.get('lateness')
        form = LateApplicationForm(MultiDict(**lateness), user=self.request.user)
        if form.validate():
            date = form.popup_date.data
            explanation = form.popup_explanation.data
            in_future = date > datetime.date.today()
            late = Late(
                user_id=self.request.user.id,
                date=date,
                explanation=explanation,
                justified=in_future or None,
                late_start=form.late_start.data,
                late_end=form.late_end.data,
                work_from_home=form.work_from_home.data,
            )

            DBSession.add(late)
            memcache.delete(MEMCACHED_NOTIFY_KEY % date)

            if in_future and is_production:
                event_id = self._add_event(date, explanation)

            return dict(
                entry=True
            )

        self.request.response.status = 400
        return form.errors
예제 #20
0
def migrate(config_path):
    from intranet3.models import DBSession, Sprint, SprintBoard
    import json

    def migrate_object(obj):
        board_json = obj.board

        if not board_json:
            return

        board = json.loads(board_json)

        if not isinstance(board, list):
            return

        board = {
            "board": board,
            "colors": [],
        }

        obj.board = json.dumps(board)

    for sprint_board in DBSession.query(SprintBoard):
        migrate_object(sprint_board)

    for sprint in DBSession.query(Sprint):
        migrate_object(sprint)

    transaction.commit()
예제 #21
0
    def calculate_velocities(self):
        self.velocity = \
            8.0 * self.achieved_points / self.worked_hours \
            if self.worked_hours else 0.0

        self.story_velocity = \
            8.0 * self.achieved_points / self.bugs_worked_hours \
            if self.bugs_worked_hours else 0.0

        sprint_velocities = DBSession.query(
            Sprint.velocity,
            Sprint.story_velocity,
        ).filter(Sprint.project_id == self.project_id) \
            .filter(Sprint.id != self.id) \
            .all()

        sprint_velocities.append((self.velocity, self.story_velocity))

        velocities, story_velocities = zip(*sprint_velocities)

        self.velocity_mean = float(sum(velocities)) / len(velocities)

        self.story_velocity_mean = \
            float(sum(story_velocities)) / len(story_velocities)

        DBSession.add(self)
예제 #22
0
    def dispatch(self):
        form = AbsenceCreateForm(self.request.POST, request=self.request)
        days, mandated, used, left = 0, 0, 0, 0
        if form.popup_date_start.data:
            mandated, used, left = user_leave(self.request, form.popup_date_start.data.year)
            if form.popup_date_end.data:
                days = h.get_working_days(form.popup_date_start.data, form.popup_date_end.data)
                left -= days
        if self.request.method == 'POST' and form.validate():
            date_start = form.popup_date_start.data
            date_end = form.popup_date_end.data
            type = form.popup_type.data
            remarks = form.popup_remarks.data
            user_id = form.popup_user_id.data
            absence = Absence(
                user_id=user_id,
                date_start=date_start,
                date_end=date_end,
                days=days,
                type=type,
                remarks=remarks,
            )
            DBSession.add(absence)
            return Response(self._('Done') + RELOAD_PAGE)

        return dict(
            form=form,
            days=days,
            mandated=mandated,
            used=used,
            left=left
        )
예제 #23
0
    def dispatch(self):
        client_id = self.request.GET.get('client_id')
        client = Client.query.get(client_id)
        form = ClientForm(self.request.POST, obj=client)
        if self.request.method == 'POST' and form.validate():
            coordinator_id = int(form.coordinator_id.data) if form.coordinator_id.data.isdigit() else None

            client.name = form.name.data
            client.active = client.active
            client.google_card = form.google_card.data
            client.google_wiki = form.google_wiki.data
            client.color=form.color.data
            client.selector = form.selector.data
            client.emails = form.emails.data
            client.coordinator_id = coordinator_id
            client.street = form.street.data
            client.city = form.city.data
            client.postcode = form.postcode.data
            client.nip = form.nip.data
            client.note = form.note.data
            client.wiki_url = form.wiki_url.data
            client.mailing_url = form.mailing_url.data

            DBSession.add(client)
            self.flash(self._(u"Client saved"))
            LOG(u"Client saved")
            return HTTPFound(location=self.request.url_for("/client/view", client_id=client.id))
        projects = client.projects
        return dict(client_id=client.id, form=form, projects=projects)
예제 #24
0
 def dispatch(self):
     form = ClientAddForm(self.request.POST)
     if self.request.method == 'POST' and form.validate():
         coordinator_id = int(form.coordinator_id.data) if form.coordinator_id.data.isdigit() else None
         client = Client(
             name=form.name.data,
             google_card=form.google_card.data,
             google_wiki=form.google_wiki.data,
             color=form.color.data,
             selector=form.selector.data,
             emails=form.emails.data,
             coordinator_id=coordinator_id,
             street=form.street.data,
             city=form.city.data,
             postcode=form.postcode.data,
             nip=form.nip.data,
             note=form.note.data,
             wiki_url=form.wiki_url.data,
             mailing_url=form.mailing_url.data
         )
         DBSession.add(client)
         DBSession.flush()
         self.flash(self._(u"New client added"))
         LOG(u"Client added")
         return HTTPFound(location=self.request.url_for("/client/view", client_id=client.id))
     return dict(form=form)
예제 #25
0
    def post(self):
        lateness = self.request.json.get('lateness')
        form = LateApplicationForm(MultiDict(**lateness),
                                   user=self.request.user)
        if form.validate():
            date = form.popup_date.data
            explanation = form.popup_explanation.data
            in_future = date > datetime.date.today()
            late = Late(
                user_id=self.request.user.id,
                date=date,
                explanation=explanation,
                justified=in_future or None,
                late_start=form.late_start.data,
                late_end=form.late_end.data,
                work_from_home=form.work_from_home.data,
            )

            DBSession.add(late)
            memcache.delete(MEMCACHED_NOTIFY_KEY % date)

            if in_future and is_production:
                event_id = self._add_event(date, explanation)

            return dict(entry=True)

        self.request.response.status = 400
        return form.errors
예제 #26
0
    def post(self):
        if not self.request.is_xhr:
            return HTTPBadRequest()

        date = self.v['date']
        form = TimeEntryForm(self.request.POST)

        if form.validate():
            project_id = form.project_id.data
            time = TimeEntry(
                date = date,
                user_id = self.request.user.id,
                time = form.time.data,
                description = form.description.data,
                ticket_id = form.ticket_id.data,
                project_id = project_id if project_id else None
            )
            DBSession.add(time)
            LOG(u'Ajax - Time entry added')

            entries = self._get_time_entries(date)
            total_sum = sum(entry.time for (tracker, entry) in entries if not entry.deleted)
            template = render(
                '/times/_list.html',
                dict(entries=entries, total_sum=total_sum),
                request=self.request
            )

            return dict(status='success', html=template)

        errors = u'<br />'.join((u"%s - %s" % (field, u', '.join(errors)) for field, errors in form.errors.iteritems()))
        return dict(status='error', errors=errors)
예제 #27
0
 def dispatch(self):
     sprint_id = self.request.GET.get('sprint_id')
     sprint = Sprint.query.get(sprint_id)
     form = SprintForm(self.request.POST, obj=sprint)
     if self.request.method == 'POST' and form.validate():
         project_id = form.project_id.data
         project = Project.query.get(project_id)
         sprint.name = form.name.data
         sprint.client_id = project.client_id
         sprint.project_id = project.id
         sprint.team_id = form.team_id.data or None
         sprint.bugs_project_ids = map(int, form.bugs_project_ids.data)
         sprint.start = form.start.data
         sprint.end = form.end.data
         sprint.goal = form.goal.data
         sprint.board = form.board.data
         sprint.retrospective_note = form.retrospective_note.data
         DBSession.add(sprint)
         self.flash(self._(u"Sprint edited"))
         LOG(u"Sprint edited")
         if self.request.POST.get('save-and-go'):
             url = self.request.url_for('/scrum/sprint/board', sprint_id=sprint.id)
         else:
             url = self.request.url_for('/scrum/sprint/edit', sprint_id=sprint.id)
         return HTTPFound(location=url)
     return dict(
         form=form,
         sprint=sprint
     )
예제 #28
0
def init_db(config_path):
    from intranet3.models import DBSession, Base
    setup_logging(config_path)
    settings = get_appsettings(config_path)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
    print 'Done'
예제 #29
0
def init_db(config_path):
    from intranet3.models import DBSession, Base
    setup_logging(config_path)
    settings = get_appsettings(config_path)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
    print 'Done'
예제 #30
0
    def add_time(cls, orig_bugs, sprint=None):
        """
        @param orig_bugs: list of bugs
        Add times to bugs, can be used inside and outside the class.
        """
        bugs = dict(((bug.id, bug.project_id), bug) for bug in orig_bugs if bug.project)
        where_condition = '(t.ticket_id = :bug_id_%s AND t.project_id = :project_id_%s)'
        conditions = []
        params = {}
        i = 1

        for bug in orig_bugs:
            bug.time = 0.0
            bug.sprint_time = 0.0

        for bug_id, project_id in bugs:
            conditions.append(where_condition % (i, i))
            params['bug_id_%s' % i] = bug_id
            params['project_id_%s' % i] = project_id
            i += 1

        if not conditions:
            return orig_bugs # short circuit to avoid useless (and incorrect) SQL query
        condition = ' OR '.join(conditions)
        sql = """
        SELECT t.ticket_id as "ticket_id", t.project_id as "project_id", SUM(t.time) as "time"
        FROM time_entry t
        WHERE t.deleted = FALSE AND (%s)
        GROUP BY t.ticket_id, t.project_id
        """ % (condition, )
        query = DBSession.query('ticket_id', 'project_id', 'time').from_statement(sql).params(**params)

        for bug_id, project_id, time in query:
            bug = bugs[(bug_id, project_id)]
            bug.time = time
            points = bug.scrum.points or 0.0
            velocity = ((points / time) * 8.0) if time else 0.0
            bug.scrum.velocity = velocity


        if sprint:
            params['sprint_start'] = sprint.start
            params['sprint_end'] = sprint.end
            sql = """
            SELECT t.ticket_id as "ticket_id", t.project_id as "project_id", SUM(t.time) as "time"
            FROM time_entry t
            WHERE t.deleted = FALSE AND (%s) AND t.date >= :sprint_start AND t.date <= :sprint_end
            GROUP BY t.ticket_id, t.project_id
            """ % (condition, )
            query = DBSession.query('ticket_id', 'project_id', 'time').from_statement(sql).params(**params)

            for bug in orig_bugs:
                bug.sprint_time = 0.0

            for bug_id, project_id, time in query:
                bugs[(bug_id, project_id)].sprint_time = time

        return orig_bugs
예제 #31
0
    def get(self):
        today = datetime.date.today()
        year = self.request.GET.get('year', today.year)
        year = int(year)
        year_start = datetime.date(year, 1, 1)
        year_end = datetime.date(year, 12, 31)
        if year == today.year:
            # if this is current year we calculate hours only to yesterday
            year_end = today-oneday

        pivot_q = DBSession.query('id', 'name', 'color', 'date', 'time').from_statement("""
        SELECT c.id as id, c.name as name, c.color as color, date_trunc('month', t.date) as date, SUM(t.time) as time
        FROM time_entry t, project p, client c
        WHERE t.project_id = p.id AND
              p.client_id = c.id AND
              t.date >= :year_start AND
              t.date <= :year_end AND
              t.deleted = false
        GROUP BY c.id, c.name, c.color, date_trunc('month', t.date)
        """).params(year_start=year_start, year_end=year_end)

        pivot = {}
        for p in pivot_q:
            pivot.setdefault((p.id, p.name, p.color), [0]*12)[p.date.month-1] = int(round(p.time))
        pivot = sorted(pivot.iteritems(), key=lambda p: p[0][1])

        stats_q = DBSession.query('date', 'time').from_statement("""
        SELECT date_trunc('month', t.date) as date, SUM(t.time) as time
        FROM time_entry t
        WHERE t.deleted = false
        GROUP BY date_trunc('month', t.date)
        """)

        stats = {}
        for s in stats_q:
            stats.setdefault(s.date.year, [0]*12)[s.date.month-1] = int(round(s.time))

        # estymation of expected worked hours for current month:
        month_approx = None
        if year == today.year and today.day > 1:
            month_start = datetime.date(today.year, today.month, 1)
            day_of_week, days_in_month = calendar.monthrange(today.year, today.month)
            month_end = datetime.date(today.year, today.month, days_in_month)
            days_worked, days_left = self._get_month_days(month_start, month_end)
            if not days_worked:
                days_worked = 1

            month_approx = (days_left + days_worked) / days_worked

        return dict(
            today=today,
            year_start=year_start,
            pivot=pivot,
            stats=stats,
            quarters_sum=self._quarters_sum,
            month_approx=month_approx,
        )
예제 #32
0
    def get(self):
        date = self.request.GET.get('date')
        if date:
            date = datetime.datetime.strptime(date, '%d.%m.%Y').date()
        else:
            date = datetime.date.today()
        current_data_late = memcache.get(MEMCACHED_NOTIFY_KEY % date)
        blacklist = self.request.user.notify_blacklist
        if current_data_late is not None:
            current_data_late['blacklist'] = blacklist
            return current_data_late

        late_query = DBSession.query(User.id, User.name, Late.id,
                                     Late.late_start, Late.late_end,
                                     Late.explanation, Late.work_from_home)
        late_query = late_query.filter(User.id == Late.user_id)\
                               .filter(Late.date == date)\
                               .filter(Late.deleted == False)\
                               .order_by(User.name)

        absences = DBSession.query(User.id, User.name, Absence.id,
                                   Absence.date_start, Absence.date_end,
                                   Absence.remarks)
        absences = absences.filter(User.id == Absence.user_id)\
                            .filter(Absence.deleted == False)\
                           .filter(Absence.date_start <= date)\
                           .filter(Absence.date_end >= date)\
                           .order_by(User.name)

        current_data_late = dict(
            lates=[
                dict(id=user_id,
                     name=user_name,
                     late_id=late_id,
                     start=start and start.isoformat()[:5] or None,
                     end=end and end.isoformat()[:5] or None,
                     explanation=explanation,
                     work_from_home=work_from_home) for user_id, user_name,
                late_id, start, end, explanation, work_from_home in late_query
            ],
            absences=[
                dict(id=user_id,
                     name=user_name,
                     absence_id=absence_id,
                     start=date_start and date_start.strftime('%d.%m.%y')
                     or None,
                     end=date_end and date_end.strftime('%d.%m.%y') or None,
                     remarks=remarks) for user_id, user_name, absence_id,
                date_start, date_end, remarks in absences
            ])
        memcache.add(
            MEMCACHED_NOTIFY_KEY % date,
            current_data_late,
            60 * 60 * 24,
        )
        current_data_late['blacklist'] = blacklist
        return current_data_late
예제 #33
0
    def delete(self):
        team_id = self.request.matchdict.get('team_id')
        team = Team_m.query.get(team_id)
        if not team:
            raise HTTPNotFound()

        TeamMember.query.filter(TeamMember.team_id==team.id).delete(synchronize_session=False)
        DBSession.delete(team)

        return HTTPOk('OK')
예제 #34
0
    def __call__(self, *args, **kwargs):
        config = ApplicationConfig.get_current_config(allow_empty=True)
        if config is None:
            WARN(u'Application config not found, emails cannot be checked')
            return
        trackers = dict(
            (tracker.mailer, tracker)
                for tracker in Tracker.query.filter(Tracker.mailer != None).filter(Tracker.mailer != '')
        )
        if not len(trackers):
            WARN(u'No trackers have mailers configured, email will not be checked')
            return

        username = config.google_user_email.encode('utf-8')
        password = config.google_user_password.encode('utf-8')

        # TODO
        logins_mappings = dict(
            (tracker.id, TrackerCredentials.get_logins_mapping(tracker))
                for tracker in trackers.itervalues()
        )
        selector_mappings = dict(
            (tracker.id, SelectorMapping(tracker))
                for tracker in trackers.itervalues()
        )

        # find all projects connected to the tracker
        projects = dict(
            (project.id, project)
                for project in Project.query.all()
        )

        # all pre-conditions should be checked by now

        # start fetching
        fetcher = MailFetcher(
            username,
            password,
        )

        # ok, we have all mails, lets create timeentries from them
        extractor = TimeEntryMailExtractor(
            trackers,
            logins_mappings,
            projects,
            selector_mappings,
        )

        for msg in fetcher:
            timeentry = extractor.get(msg)
            if timeentry:
                DBSession.add(timeentry)
        transaction.commit()
예제 #35
0
    def dispatch(self):
        form = ClientTimeForm(self.request.POST)

        if not (self.request.method == 'POST' and form.validate()):
            return dict(form=form)

        date = form.date.data
        month_start, month_end = self._get_start_end_of_month(date)
        clients = form.clients.data
        groupby = form.groupby.data

        q = DBSession.query(Client.name, Project.name, func.sum(TimeEntry.time))\
                            .filter(TimeEntry.project_id==Project.id)\
                            .filter(Project.client_id==Client.id)\
                            .filter(Client.id.in_(clients))\
                            .filter(TimeEntry.date >= month_start)\
                            .filter(TimeEntry.date <= month_end)\
                            .filter(TimeEntry.deleted==False)\
                            .group_by(Client.name, Project.name)
        data = q.all()
        whole_sum = sum([row[2] for row in data])
        whole_sum_without_us = sum(
            [row[2] for row in data if row[0] != config['COMPANY_NAME']])

        q = DBSession.query(func.sum(TimeEntry.time))\
                            .filter(TimeEntry.project_id==Project.id)\
                            .filter(Project.client_id==Client.id)\
                            .filter(Client.id != 12)\
                            .filter(TimeEntry.date >= month_start)\
                            .filter(TimeEntry.date <= month_end)\
                            .filter(TimeEntry.deleted==False)
        our_monthly_hours = q.one()[0]

        if groupby == 'client':
            results = {}
            for client, project, time in data:
                results.setdefault(client, 0)
                results[client] += time
            results = results.items()

            data = results
            data.sort(key=itemgetter(0))  # client
        else:
            data.sort(key=itemgetter(0, 1))  # client,project

        return dict(
            form=form,
            groupby=groupby,
            data=data,
            whole_sum=whole_sum,
            whole_sum_without_us=whole_sum_without_us,
            our_monthly_hours=our_monthly_hours,
        )
예제 #36
0
    def dispatch(self):
        form = ClientTimeForm(self.request.POST)

        if not (self.request.method == 'POST' and form.validate()):
            return dict(form=form)

        date = form.date.data
        month_start, month_end = self._get_start_end_of_month(date)
        clients = form.clients.data
        groupby = form.groupby.data

        q = DBSession.query(Client.name, Project.name, func.sum(TimeEntry.time))\
                            .filter(TimeEntry.project_id==Project.id)\
                            .filter(Project.client_id==Client.id)\
                            .filter(Client.id.in_(clients))\
                            .filter(TimeEntry.date >= month_start)\
                            .filter(TimeEntry.date <= month_end)\
                            .filter(TimeEntry.deleted==False)\
                            .group_by(Client.name, Project.name)
        data = q.all()
        whole_sum = sum([row[2] for row in data])
        whole_sum_without_us = sum([row[2] for row in data if row[0] != config['COMPANY_NAME']])

        q = DBSession.query(func.sum(TimeEntry.time))\
                            .filter(TimeEntry.project_id==Project.id)\
                            .filter(Project.client_id==Client.id)\
                            .filter(Client.id != 12)\
                            .filter(TimeEntry.date >= month_start)\
                            .filter(TimeEntry.date <= month_end)\
                            .filter(TimeEntry.deleted==False)
        our_monthly_hours = q.one()[0]

        if groupby == 'client':
            results = {}
            for client, project, time in data:
                results.setdefault(client, 0)
                results[client] += time
            results = results.items()

            data = results
            data.sort(key=itemgetter(0)) # client
        else:
            data.sort(key=itemgetter(0,1)) # client,project


        return dict(
            form=form,
            groupby=groupby,
            data=data,
            whole_sum=whole_sum,
            whole_sum_without_us=whole_sum_without_us,
            our_monthly_hours=our_monthly_hours,
        )
예제 #37
0
파일: utils.py 프로젝트: adamgr/intranet
    def __iter__(self):
        if self.empty:
            yield '', u'-- None --'
        query = DBSession.query(User.id, User.name).filter(User.is_not_client()).filter(User.is_active==True).order_by(User.name)
        for id, name in query:
            yield str(id), name

        if self.inactive:
            yield '', ' '*8
            query = DBSession.query(User.id, User.name).filter(User.is_not_client()).filter(User.is_active==False).order_by(User.name)
            for id, name in query:
                yield str(id), name
예제 #38
0
def create_config(env):
    from intranet3.models import *
    import transaction
    config = ApplicationConfig(
        office_ip='',
        google_user_email='',
        google_user_password='',
        holidays_spreadsheet='',
        hours_employee_project='',
    )
    DBSession.add(config)
    transaction.commit()
예제 #39
0
def create_config(env):
    from intranet3.models import *
    import transaction
    config = ApplicationConfig(
        office_ip='',
        google_user_email='',
        google_user_password='',
        holidays_spreadsheet='',
        hours_employee_project='',
    )
    DBSession.add(config)
    transaction.commit()
예제 #40
0
    def dispatch(self):
        subpage = self.request.GET.get('subpage', 'general')
        if subpage not in ['general', 'reports', 'spreadsheets', 'access']:
            return HTTPForbidden()

        config_obj = ApplicationConfig.get_current_config(allow_empty=True)

        FormRef = getattr(config_forms, "%sForm"% subpage.title())

        if config_obj is not None:
            LOG(u"Found config object from %s" % (config_obj.date, ))
            form = FormRef(self.request.POST, obj=config_obj)
        else:
            LOG(u"Config object not found")
            form = FormRef(self.request.POST)

        if self.request.method == 'POST' and form.validate():
            if config_obj is None:
                config_obj =  ApplicationConfig()

            # Add/Edit data
            if subpage == 'general':
                config_obj.office_ip = form.office_ip.data
                config_obj.google_user_email = form.google_user_email.data
                config_obj.google_user_password = form.google_user_password.data
                config_obj.cleaning_time_presence = form.cleaning_time_presence.data
                config_obj.absence_project_id = form.absence_project_id.data if form.absence_project_id.data else None
                config_obj.monthly_late_limit = form.monthly_late_limit.data
                config_obj.monthly_incorrect_time_record_limit = form.monthly_incorrect_time_record_limit.data
            elif subpage == 'reports':
                config_obj.reports_project_ids = [int(id) for id in form.reports_project_ids.data]
                config_obj.reports_omit_user_ids = [int(id) for id in form.reports_omit_user_ids.data]
                config_obj.reports_without_ticket_project_ids = [int(id) for id in form.reports_without_ticket_project_ids.data]
                config_obj.reports_without_ticket_omit_user_ids = [int(id) for id in form.reports_without_ticket_omit_user_ids.data]
            elif subpage == 'spreadsheets':
                config_obj.holidays_spreadsheet = form.holidays_spreadsheet.data
                config_obj.hours_employee_project = form.hours_employee_project.data
                config_obj.hours_ticket_user_id = form.hours_ticket_user_id.data if form.hours_ticket_user_id.data else None
            elif subpage == "access":
                config_obj.freelancers = form.freelancers.data

            DBSession.add(config_obj)
            config_obj.invalidate_office_ip()

            LOG(u"Config object saved")
            self.flash(self._(u'Application Config saved'), klass='success')
            return HTTPFound(location=self.request.url_for('/config/view', subpage=subpage))

        return dict(
            form=form,
            subpage=subpage
        )
예제 #41
0
 def post(self):
     form = TrackerForm(self.request.POST)
     if form.validate():
         tracker = Tracker(type=form.type.data,
                           name=form.name.data,
                           url=form.url.data,
                           mailer=form.mailer.data)
         DBSession.add(tracker)
         self.flash(self._(u"New tracker added"))
         LOG(u"Tracker added")
         url = self.request.url_for('/tracker/list')
         return HTTPFound(location=url)
     return dict(form=form)
예제 #42
0
 def post(self):
     form = WrongTimeJustificationForm(self.request.POST, user=self.request.user)
     if form.validate():
         wrongtime = WrongTime(
             user_id=self.request.user.id,
             date=form.popup_date.data,
             explanation=form.popup_explanation.data,
         )
         DBSession.add(wrongtime)
         LOG(u"WrongTime added")
         response = '%s %s' % (self._(u'Explanation added'), CHANGE_STATUS % self._('Waits for verification'))
         return Response(response)
     return dict(form=form)
예제 #43
0
    def post(self):
        timeentry = self.v['timeentry']

        next_ = self.request.GET.get('next')
        if not next_:
            next_ = self.request.url_for(
                '/times/list',
                date=timeentry.date.strftime('%d.%m.%Y'),
            )

        form = TimeEntryForm(self.request.POST, obj=timeentry)
        date = timeentry.date
        today = datetime.date.today()

        if form.validate():
            if timeentry.project_id != int(
                    form.project_id.data) and today > date:
                timeentry.deleted = True
                timeentry.modified_ts = datetime.datetime.now()
                time = TimeEntry(date=date,
                                 user_id=timeentry.user_id,
                                 time=form.time.data,
                                 description=form.description.data,
                                 ticket_id=form.ticket_id.data,
                                 project_id=form.project_id.data
                                 if form.project_id.data else None,
                                 timer_ts=datetime.datetime.now()
                                 if form.timer.data else None)
                DBSession.add(time)
            else:
                ticket_id = form.ticket_id.data

                if timeentry.time != form.time.data or\
                   timeentry.project_id != form.project_id.data:
                    timeentry.modified_ts = datetime.datetime.now()

                timeentry.time = form.time.data
                timeentry.description = form.description.data
                timeentry.ticket_id = ticket_id
                timeentry.project_id = form.project_id.data if form.project_id.data else None

            self.flash(self._(u'Time entry saved'))
            LOG(u'Time entry saved')
            return HTTPFound(next_)

        return dict(
            timeentry_id=timeentry.id,
            form=form,
            date=date,
            next=next_,
        )
예제 #44
0
파일: bugs.py 프로젝트: pytlakp/intranet-1
    def add_time(cls, orig_bugs, sprint=None):
        """
        @param orig_bugs: list of bugs
        Add times to bugs, can be used inside and outside the class.
        """
        bugs = dict(((bug.id, bug.project_id), bug) for bug in orig_bugs
                    if bug.project)
        where_condition = '(t.ticket_id = :bug_id_%s AND t.project_id = :project_id_%s)'
        conditions = []
        params = {}
        i = 1
        for bug_id, project_id in bugs:
            conditions.append(where_condition % (i, i))
            params['bug_id_%s' % i] = bug_id
            params['project_id_%s' % i] = project_id
            i += 1
        if not conditions:
            return orig_bugs  # short circuit to avoid useless (and incorrect) SQL query
        condition = ' OR '.join(conditions)
        sql = """
        SELECT t.ticket_id as "ticket_id", t.project_id as "project_id", SUM(t.time) as "time"
        FROM time_entry t
        WHERE t.deleted = FALSE AND (%s)
        GROUP BY t.ticket_id, t.project_id
        """ % (condition, )
        query = DBSession.query('ticket_id', 'project_id',
                                'time').from_statement(sql).params(**params)

        for bug_id, project_id, time in query:
            bugs[(bug_id, project_id)].time = time

        if sprint:
            params['sprint_start'] = sprint.start
            params['sprint_end'] = sprint.end
            sql = """
            SELECT t.ticket_id as "ticket_id", t.project_id as "project_id", SUM(t.time) as "time"
            FROM time_entry t
            WHERE t.deleted = FALSE AND (%s) AND t.date >= :sprint_start AND t.date <= :sprint_end
            GROUP BY t.ticket_id, t.project_id
            """ % (condition, )
            query = DBSession.query(
                'ticket_id', 'project_id',
                'time').from_statement(sql).params(**params)

            for bug in bugs.itervalues():
                bug.sprint_time = 0.0

            for bug_id, project_id, time in query:
                bugs[(bug_id, project_id)].sprint_time = time

        return orig_bugs
예제 #45
0
    def post(self):
        timeentry = self.v['timeentry']

        next_ = self.request.GET.get('next')
        if not next_:
            next_ = self.request.url_for(
                '/times/list',
                date=timeentry.date.strftime('%d.%m.%Y'),
            )

        form = TimeEntryForm(self.request.POST, obj=timeentry)
        date = timeentry.date
        today = datetime.date.today()

        if form.validate():
            if timeentry.project_id != int(form.project_id.data) and today > date:
                timeentry.deleted = True
                timeentry.modified_ts = datetime.datetime.now()
                time = TimeEntry(
                    date=date,
                    user_id = timeentry.user_id,
                    time = form.time.data,
                    description = form.description.data,
                    ticket_id = form.ticket_id.data,
                    project_id = form.project_id.data if form.project_id.data else None,
                    timer_ts = datetime.datetime.now() if form.timer.data else None
                )
                DBSession.add(time)
            else:
                ticket_id = form.ticket_id.data

                if timeentry.time != form.time.data or\
                   timeentry.project_id != form.project_id.data:
                    timeentry.modified_ts = datetime.datetime.now()

                timeentry.time = form.time.data
                timeentry.description = form.description.data
                timeentry.ticket_id = ticket_id
                timeentry.project_id = form.project_id.data if form.project_id.data else None

            self.flash(self._(u'Time entry saved'))
            LOG(u'Time entry saved')
            return HTTPFound(next_)

        return dict(
            timeentry_id=timeentry.id,
            form=form,
            date=date,
            next=next_,
        )
예제 #46
0
class Team(ApiView):
    def get(self):
        team_id = self.request.matchdict.get('team_id')
        team = Team_m.query.get(team_id)
        if team:
            return team.to_dict()
        else:
            raise HTTPNotFound()

    @has_perm('can_edit_teams')
    def put(self):
        team_id = self.request.matchdict.get('team_id')
        team = Team_m.query.get(team_id)
        if not team:
            raise HTTPNotFound()

        try:
            json_team = self.request.json_body
        except ValueError:
            raise HTTPBadRequest('Expect json')

        team_schema = TeamUpdateSchema()
        try:
            team_des = team_schema.deserialize(json_team)
        except colander.Invalid, e:
            errors = e.asdict()
            raise HTTPBadRequest(errors)

        team.name = team_des.get('name') or team.name

        if 'users' in team_des:
            new_users = team_des['users']
            old_users = DBSession.query(TeamMember.user_id).filter(TeamMember.team_id==team.id).all()
            users_delete = list(set(old_users) - set(new_users))
            users_add = list(set(new_users) - set(old_users))

            if users_delete:
                TeamMember.query.filter(TeamMember.team_id==team.id)\
                                .filter(TeamMember.user_id.in_(users_delete))\
                                .delete(synchronize_session=False)

            if users_add:
                DBSession.add_all([TeamMember(user_id=u_id, team_id=team.id) for u_id in users_add])

        if team_des.get('swap_with_preview'):
            preview = Preview(self.request)
            if not preview.swap_avatar(type='teams', id=team.id):
                raise HTTPBadRequest('No preview to swap')

        return HTTPOk("OK")
예제 #47
0
    def post(self):
        form = LateJustificationForm(self.request.POST, user=self.request.user)

        if form.validate():
            late = Late(
                user_id=self.request.user.id,
                date=form.popup_date.data,
                explanation=form.popup_explanation.data,
            )
            DBSession.add(late)
            LOG(u"Late added")
            return Response(self._(u'Explanation added') + CHANGE_STATUS % self._('Waits for verification'))

        return dict(form=form)
예제 #48
0
    def __call__(self, *args, **kwargs):
        config = ApplicationConfig.get_current_config(allow_empty=True)
        if config is None:
            WARN(u'Application config not found, emails cannot be checked')
            return
        trackers = dict(
            (tracker.mailer, tracker) for tracker in Tracker.query.filter(
                Tracker.mailer != None).filter(Tracker.mailer != ''))
        if not len(trackers):
            WARN(
                u'No trackers have mailers configured, email will not be checked'
            )
            return

        username = config.google_user_email.encode('utf-8')
        password = config.google_user_password.encode('utf-8')

        # TODO
        logins_mappings = dict(
            (tracker.id, TrackerCredentials.get_logins_mapping(tracker))
            for tracker in trackers.itervalues())
        selector_mappings = dict((tracker.id, SelectorMapping(tracker))
                                 for tracker in trackers.itervalues())

        # find all projects connected to the tracker
        projects = dict(
            (project.id, project) for project in Project.query.all())

        # all pre-conditions should be checked by now

        # start fetching
        fetcher = MailFetcher(
            username,
            password,
        )

        # ok, we have all mails, lets create timeentries from them
        extractor = TimeEntryMailExtractor(
            trackers,
            logins_mappings,
            projects,
            selector_mappings,
        )

        for msg in fetcher:
            timeentry = extractor.get(msg)
            if timeentry:
                DBSession.add(timeentry)
        transaction.commit()
예제 #49
0
 def dispatch(self):
     sprint_id = self.request.GET.get('sprint_id')
     sprint =  Sprint.query.get(sprint_id)
     form = DeleteForm(self.request.POST)
     if self.request.method == 'POST' and form.validate():
         DBSession.delete(sprint)
         back_url = self.request.url_for('/scrum/sprint/list')
         return HTTPFound(location=back_url)
     return dict(
         type_name=u'sprint',
         title=u'%s' % sprint.name,
         url=self.request.url_for('/scrum/sprint/delete', sprint_id=sprint.id),
         back_url=self.request.url_for('/scrum/sprint/list'),
         form=form
     )
예제 #50
0
    def action(self):
        config_obj = ApplicationConfig.get_current_config()
        client = SpreadsheetConnector(config_obj.google_user_email, config_obj.google_user_password)
        worksheet = client.get_worksheet(config_obj.holidays_spreadsheet, 6)
        data = worksheet.GetRecords(1, 99999)  # Magic Constant
        dates_new = set([ datetime.datetime.strptime(d.content['data'], '%Y-%m-%d').date() for d in data ])
        dates_old = set(Holiday.all(cache=False))
        dates_diff = dates_new.difference(dates_old)

        if dates_diff:
            holidays = [ Holiday(date=date) for date in dates_diff ]
            DBSession.add_all(holidays)

        INFO(u'%s Holidays added: %s' % (len(dates_diff), dates_diff))
        return Response('ok')
예제 #51
0
    def post(self):
        _id = self.request.POST.get('id')
        name = self.request.POST.get('name')
        val = self.request.POST.get('val')
        val = bool(int(val))

        if name == 'late':
            late = m.Late.query.get(_id)
            late.justified = val
            DBSession.add(late)
        elif name == 'wrongtime':
            wrongtime = m.WrongTime.query.get(_id)
            wrongtime.justified = val
            DBSession.add(wrongtime)
        return Response('')
예제 #52
0
 def post(self):
     form = WrongTimeJustificationForm(self.request.POST,
                                       user=self.request.user)
     if form.validate():
         wrongtime = WrongTime(
             user_id=self.request.user.id,
             date=form.popup_date.data,
             explanation=form.popup_explanation.data,
         )
         DBSession.add(wrongtime)
         LOG(u"WrongTime added")
         response = '%s %s' % (self._(u'Explanation added'), CHANGE_STATUS %
                               self._('Waits for verification'))
         return Response(response)
     return dict(form=form)
예제 #53
0
    def delete(self):
        board_id = self.request.matchdict.get('board_id')
        board = m.SprintBoard.query.get(board_id)

        if not board:
            raise HTTPNotFound()

        can_delete = (board.user_id == self.request.user.id)

        if not can_delete:
            raise HTTPForbidden

        DBSession.delete(board)

        return HTTPOk('OK')
예제 #54
0
    def post(self):
        form = LateJustificationForm(self.request.POST, user=self.request.user)

        if form.validate():
            late = Late(
                user_id=self.request.user.id,
                date=form.popup_date.data,
                explanation=form.popup_explanation.data,
            )
            DBSession.add(late)
            LOG(u"Late added")
            return Response(
                self._(u'Explanation added') +
                CHANGE_STATUS % self._('Waits for verification'))

        return dict(form=form)
예제 #55
0
    def get(self):
        user_id = self.request.GET.get('user_id')
        month_start, month_end = self._get_month()
        user = User.query.filter(User.id == user_id).one()

        query = DBSession.query('date', 'incorrect_count').from_statement("""
            SELECT  date, COUNT(date) as incorrect_count
            FROM time_entry s
            WHERE DATE(s.modified_ts) > s.date AND
                  s.user_id = :user_id AND
                  s.date >= :month_start AND
                  s.date <= :month_end
            GROUP BY date
        """).params(month_start=month_start,
                    month_end=month_end,
                    user_id=user.id)
        data = query.all()

        data = self._group_by_user_monthly(data, user.id)

        holidays = Holiday.all()

        return dict(
            data=data,
            user=user,
            is_holiday=lambda date: Holiday.is_holiday(date, holidays=holidays
                                                       ),
            month_start=month_start,
            month_end=month_end,
            next_month=next_month(month_start),
            prev_month=previous_month(month_start),
            datetime=datetime,
        )