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', 'presence', 'leave').from_statement(""" SELECT date_trunc('day', p.ts) as "date", MIN(p.ts) as "presence", MAX(p.ts) as "leave" FROM presence_entry p WHERE p.ts >= :month_start AND date_trunc('day', p.ts) <= :month_end AND p.user_id = :user_id GROUP BY date_trunc('day', p.ts) """).params(month_start=month_start, month_end=month_end, user_id=user_id) data = query.all() holidays = Holiday.all() data = self._group_by_user_monthly(data, user.id) 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), deltazero=deltazero, datetime=datetime, )
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 = self.session.query('date', 'presence', 'leave').from_statement(""" SELECT date_trunc('day', p.ts) as "date", MIN(p.ts) as "presence", MAX(p.ts) as "leave" FROM presence_entry p WHERE p.ts >= :month_start AND date_trunc('day', p.ts) <= :month_end AND p.user_id = :user_id GROUP BY date_trunc('day', p.ts) """).params(month_start=month_start, month_end=month_end, user_id=user_id) data = query.all() holidays = Holiday.all() data = self._group_by_user_monthly(data, user.id) 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), deltazero=deltazero, datetime=datetime, )
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, )
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, )
def _worked_hours(self, date): month_start, month_end = self._get_start_end_of_month(date) holidays = Holiday.all() today = datetime.date.today() count_of_required_month_hours = count_of_required_hours_to_today = 0 for date in dates_between(month_start, month_end): if not Holiday.is_holiday(date, holidays=holidays): count_of_required_month_hours += 8 if date <= today: count_of_required_hours_to_today += 8 return count_of_required_month_hours, count_of_required_hours_to_today
def get_working_days(date_start, date_end): from intranet3.models import Holiday if date_start > date_end: return 0 holidays = Holiday.all() date = date_start diff = datetime.timedelta(days=1) days = 0 while date <= date_end: if not Holiday.is_holiday(date, holidays=holidays): days += 1 date += diff return days
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')
def _group_by_user_monthly(self, data, excuses): """ dictionary: user -> [timedelta * 12] We sum only whole minutes """ result = {} holidays = Holiday.all() for user_id, date, presence in data: if presence.strftime('%Y-%m-%d') in excuses.get(user_id, []): continue user_data = result.setdefault(user_id, [deltazero] * 12) late = presence - datetime.datetime.combine(presence.date(), am9) late = late if late > datetime.timedelta(minutes=1) and not Holiday.is_holiday(date, holidays=holidays) else deltazero user_data[date.month - 1] += datetime.timedelta(days=late.days, minutes=int(late.seconds/60)) return result
def action(self): if Holiday.is_holiday(datetime.date.today()): LOG(u"Skipping missing hours reminder, because it's a holiday") return Response(self._(u"Won't remind")) LOG(u"Starting missing hours reminder") today = datetime.date.today() entries = self.session.query('email', 'name', 'time').from_statement(""" SELECT s.email, s.name, s.time FROM ( SELECT u.email as "email", u.name as "name", ( SELECT COALESCE(SUM(t.time), 0) FROM time_entry t WHERE t.user_id = u.id AND t.date = :today AND t.deleted = FALSE ) as "time" FROM "user" u WHERE NOT u.groups @> '{client}' AND u.is_active ) as s WHERE s.time < :min_hours """).params(today=today, min_hours=MIN_HOURS) for email, name, hours in entries: self._remind_missing_hours(email, name, hours, today) LOG(u"Ending resolved bugs reminder") return Response(self._(u'Reminded everybody'))
def _group_by_user_monthly(self, data, user_id): result = {} _excuses = excuses.presence() holidays = Holiday.all() for date, presence, leave in data: day_data = result.setdefault(date.day, [0, 0, deltazero]) day_data[0] = presence.strftime('%H:%M:%S') day_data[1] = leave.strftime('%H:%M:%S') late = presence - datetime.datetime.combine(presence.date(), am9) late = late if late > datetime.timedelta(minutes=1) and not Holiday.is_holiday(date, holidays=holidays) else deltazero excuse = '-' if presence.strftime('%Y-%m-%d') in _excuses.get(user_id, {}).keys(): excuse = _excuses[user_id][presence.strftime('%Y-%m-%d')] day_data[2] = late, excuse return result
def action(self): if Holiday.is_holiday(datetime.date.today()): LOG(u"Skipping resolved bugs reminder, because it's a holiday") return Response(u"Won't remind") LOG(u"Starting resolved bugs reminder") for user in User.query.all(): self._remind_resolved_bugs_user(user) LOG(u"Ending resolved bugs reminder") return Response(u'Reminded everybody')
def _group_by_user_monthly(self, data, user_id): result = {} _excuses = excuses.presence() holidays = Holiday.all() for date, presence, leave in data: day_data = result.setdefault(date.day, [0, 0, deltazero]) day_data[0] = presence.strftime('%H:%M:%S') day_data[1] = leave.strftime('%H:%M:%S') late = presence - datetime.datetime.combine(presence.date(), am9) late = late if late > datetime.timedelta( minutes=1) and not Holiday.is_holiday( date, holidays=holidays) else deltazero excuse = '-' if presence.strftime('%Y-%m-%d') in _excuses.get(user_id, {}).keys(): excuse = _excuses[user_id][presence.strftime('%Y-%m-%d')] day_data[2] = late, excuse return result
def _group_by_user_monthly(self, data, excuses): """ dictionary: user -> [timedelta * 12] We sum only whole minutes """ result = {} holidays = Holiday.all() for user_id, date, presence in data: if presence.strftime('%Y-%m-%d') in excuses.get(user_id, []): continue user_data = result.setdefault(user_id, [deltazero] * 12) late = presence - datetime.datetime.combine(presence.date(), am9) late = late if late > datetime.timedelta( minutes=1) and not Holiday.is_holiday( date, holidays=holidays) else deltazero user_data[date.month - 1] += datetime.timedelta( days=late.days, minutes=int(late.seconds / 60)) return result
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.FindRecords("") 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] self.session.add_all(holidays) INFO(u"%s Holidays added: %s" % (len(dates_diff), dates_diff)) return Response("ok")
def dispatch(self): form = AbsentApplicationForm(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(): memcache.clear() response = u'' date_start = form.popup_date_start.data date_end = form.popup_date_end.data type = form.popup_type.data remarks = form.popup_remarks.data absence = Absence( user_id=self.request.user.id, date_start=date_start, date_end=date_end, days=days, type=type, remarks=remarks, ) memcache.delete(MEMCACHED_NOTIFY_KEY % date_start) self.session.add(absence) if absence.type != 'inne': # let's add timeentries for this leave holidays = Holiday.all() date = date_start oneday = datetime.timedelta(days=1) description = self._(u'Auto Leave: ${type} - ${remarks}', type=dict(ABSENCE_TYPES)[type], remarks=remarks ) project_id = L4_PROJECT_ID if type == u'l4' else LEAVE_PROJECT_ID while date <= date_end: if not Holiday.is_holiday(date, holidays=holidays): timeentry = TimeEntry( user_id=self.request.user.id, date=date, time=8, description=description, project_id=project_id, ) self.session.add(timeentry) date += oneday ## let's send email deferred = self._send_mail( absence.type, date_start.strftime('%Y-%m-%d'), date_end.strftime('%Y-%m-%d'), days, remarks, ) response += self._(u'Request added<br>Hours added<br>') ## and add event to calendar: calendar = cal.Calendar(self.request.user) event = cal.Event( date_start, date_end+cal.oneday, u'NIEOB-[%s]' % self.request.user.name, remarks, ) event_id = calendar.addEvent(event) if event_id: response += self._(u'Calendar entry has been added') else: response += u'Calendar entry has <b class="red">NOT</b> beed added' return Response(response) return dict( form=form, days=days, mandated=mandated, used=used, left=left )
def post(self): absence = self.request.json.get('absence') form = AbsentApplicationForm(MultiDict(**absence), request=self.request) if form.validate(): response = { u'request': False, u'hours': False, u'calendar_entry': False, } memcache.clear() date_start = form.popup_date_start.data date_end = form.popup_date_end.data days = 0 if date_start and date_end: days = h.get_working_days(date_start, date_end) type = form.popup_type.data remarks = form.popup_remarks.data absence = Absence( user_id=self.request.user.id, date_start=date_start, date_end=date_end, days=days, type=type, remarks=remarks, ) DBSession.add(absence) memcache.delete(MEMCACHED_NOTIFY_KEY % date_start) if absence.type != 'inne': holidays = Holiday.all() date = date_start oneday = datetime.timedelta(days=1) description = self._(u'Auto Leave: ${type} - ${remarks}', type=dict(ABSENCE_TYPES)[type], remarks=remarks) project_id = L4_PROJECT_ID if type == u'l4' else LEAVE_PROJECT_ID while date <= date_end: if not Holiday.is_holiday(date, holidays=holidays): timeentry = TimeEntry( user_id=self.request.user.id, date=date, time=8, description=description, project_id=project_id, ) DBSession.add(timeentry) date += oneday self._send_email( absence.type, date_start.strftime('%Y-%m-%d'), date_end.strftime('%Y-%m-%d'), days, remarks, ) response[u'request'] = True response[u'hours'] = True calendar = cal.Calendar(self.request.user) event = cal.Event(date_start, date_end + cal.oneday, u'NIEOB-[%s]' % self.request.user.name, remarks) event_id = calendar.addEvent(event) response[u'calendar_entry'] = bool(event_id) return response self.request.response.status = 400 return form.errors
def get(self): month_start, month_end = self._get_month() entries = ( DBSession.query("user_id", "date", "time", "late_count") .from_statement( """ SELECT t.user_id as "user_id", t.date as "date", ( SELECT COALESCE(SUM(h.time), 0.0) FROM time_entry h WHERE h.user_id = t.user_id AND h.date = t.date AND h.deleted = FALSE ) as "time", ( SELECT COUNT(*) FROM time_entry s WHERE s.user_id = t.user_id AND s.date = t.date AND DATE(s.modified_ts) > s.date ) as "late_count" FROM time_entry t WHERE t.date >= :month_start AND t.date <= :month_end GROUP BY t.user_id, t.date; """ ) .params(month_start=month_start, month_end=month_end) ) if not self.request.has_perm("can_see_users_times"): users = [self.request.user] # TODO do we need to constrain entries also? locations = {self.request.user.location: ("", 1)} else: location_names = self.request.user.get_locations() users = {} for name, (fullname, shortcut) in location_names: usersq = ( User.query.filter(User.is_not_client()) .filter(User.is_active == True) .filter(User.location == name) .order_by(User.is_freelancer(), User.name) ) users[name] = usersq.all() locations = {name: [User.LOCATIONS[name][0], len(users)] for name, users in users.iteritems()} locations[self.request.user.location][1] -= 1 ordered_users = [] for name, (fullname, shortcut) in location_names: ordered_users.extend(users[name]) users = ordered_users # move current user to the front of the list current_user_index = None for i, user in enumerate(users): if user.id == self.request.user.id: current_user_index = i users.insert(0, users.pop(current_user_index)) today = datetime.date.today() grouped = defaultdict(lambda: defaultdict(lambda: 0.0)) late = defaultdict(lambda: defaultdict(lambda: False)) sums = defaultdict(lambda: 0.0) daily_sums = defaultdict(lambda: 0.0) for user_id, date, time, late_count in entries: grouped[user_id][date] = time if date <= today: sums[user_id] += time daily_sums[date] += time late[user_id][date] = late_count > 0 holidays = Holiday.all() count_of_required_month_hours = {} count_of_required_hours_to_today = {} for user in users: sftw = user.start_full_time_work if sftw: if sftw > month_end: start_work = datetime.date(today.year + 10, 1, 1) elif sftw < month_start: start_work = month_start else: start_work = sftw month_hours = h.get_working_days(start_work, month_end) * 8 today_ = today if today < month_end else month_end hours_to_today = h.get_working_days(start_work, today_) * 8 count_of_required_month_hours[user.id] = month_hours count_of_required_hours_to_today[user.id] = hours_to_today else: count_of_required_month_hours[user.id] = 0 count_of_required_hours_to_today[user.id] = 0 return dict( entries=grouped, users=users, sums=sums, late=late, excuses=excuses.wrongtime(), daily_sums=daily_sums, monthly_sum=sum(daily_sums.values()), dates=__builtin__.list(dates_between(month_start, month_end)), is_holiday=lambda date: Holiday.is_holiday(date, holidays=holidays), month_start=month_start, prev_date=previous_month(month_start), next_date=next_month(month_start), today=today, count_of_required_month_hours=count_of_required_month_hours, count_of_required_hours_to_today=count_of_required_hours_to_today, locations=locations, )
def get(self): month_start, month_end = self._get_month() entries = self.session.query('user_id', 'date', 'time', 'late_count').from_statement(""" SELECT t.user_id as "user_id", t.date as "date", ( SELECT COALESCE(SUM(h.time), 0.0) FROM time_entry h WHERE h.user_id = t.user_id AND h.date = t.date AND h.deleted = FALSE ) as "time", ( SELECT COUNT(*) FROM time_entry s WHERE s.user_id = t.user_id AND s.date = t.date AND DATE(s.modified_ts) > s.date ) as "late_count" FROM time_entry t WHERE t.date >= :month_start AND t.date <= :month_end GROUP BY t.user_id, t.date; """).params(month_start=month_start, month_end=month_end) if not self.request.has_perm('view'): users = [self.request.user] # TODO do we need to constrain entries also? locations= { self.request.user.location: ('', 1) } else: users_w = User.query.filter(User.is_not_client()) \ .filter(User.is_active==True) \ .filter(User.location=='wroclaw') \ .order_by(User.freelancer, User.name) \ .all() users_p = User.query.filter(User.is_not_client()) \ .filter(User.is_active==True) \ .filter(User.location=='poznan') \ .order_by(User.freelancer, User.name) \ .all() locations = { 'wroclaw': [u'Wrocław', len(users_w)], 'poznan': [u'Poznań', len(users_p)], } locations[self.request.user.location][1] -= 1 if self.request.user.location == 'wroclaw': users = users_w users.extend(users_p) else: users = users_p users.extend(users_w) today = datetime.date.today() grouped = defaultdict(lambda: defaultdict(lambda: 0.0)) late = defaultdict(lambda: defaultdict(lambda: False)) sums = defaultdict(lambda: 0.0) daily_sums = defaultdict(lambda: 0.0) for user_id, date, time, late_count in entries: grouped[user_id][date] = time if date <= today: sums[user_id] += time daily_sums[date] += time late[user_id][date] = late_count > 0 holidays = Holiday.all() count_of_required_month_hours = {} count_of_required_hours_to_today = {} for user in users: sftw = user.start_full_time_work or datetime.date(1970, 1, 1) if sftw > month_end: start_work = datetime.date(today.year+10, 1, 1) elif sftw < month_start: start_work = month_start else: start_work = sftw count_of_required_month_hours[user.id] = h.get_working_days(start_work, month_end) * 8 count_of_required_hours_to_today[user.id] = h.get_working_days(start_work, today if today < month_end else month_end) * 8 # move current user to the front of the list current_user_index = None for i, user in enumerate(users): if user.id == self.request.user.id: current_user_index = i users.insert(0, users.pop(current_user_index)) return dict( entries=grouped, users=users, sums=sums, late=late, excuses=excuses.wrongtime(), daily_sums=daily_sums, monthly_sum=sum(daily_sums.values()), dates=__builtin__.list(dates_between(month_start, month_end)), is_holiday=lambda date: Holiday.is_holiday(date, holidays=holidays), month_start=month_start, prev_date=previous_month(month_start), next_date=next_month(month_start), today=today, count_of_required_month_hours=count_of_required_month_hours, count_of_required_hours_to_today=count_of_required_hours_to_today, locations=locations, )
def post(self): absence = self.request.json.get('absence') form = AbsentApplicationForm(MultiDict(**absence), request=self.request) if form.validate(): response = { u'request': False, u'hours': False, u'calendar_entry': False, } memcache.clear() date_start = form.popup_date_start.data date_end = form.popup_date_end.data days = 0 if date_start and date_end: days = h.get_working_days(date_start, date_end) type = form.popup_type.data remarks = form.popup_remarks.data absence = Absence( user_id=self.request.user.id, date_start=date_start, date_end=date_end, days=days, type=type, remarks=remarks, ) DBSession.add(absence) memcache.delete(MEMCACHED_NOTIFY_KEY % date_start) if absence.type != 'inne': holidays = Holiday.all() date = date_start oneday = datetime.timedelta(days=1) description = self._( u'Auto Leave: ${type} - ${remarks}', type=dict(ABSENCE_TYPES)[type], remarks=remarks ) project_id = L4_PROJECT_ID if type == u'l4' else LEAVE_PROJECT_ID while date <= date_end: if not Holiday.is_holiday(date, holidays=holidays): timeentry = TimeEntry( user_id=self.request.user.id, date=date, time=8, description=description, project_id=project_id, ) DBSession.add(timeentry) date += oneday self._send_email( absence.type, date_start.strftime('%Y-%m-%d'), date_end.strftime('%Y-%m-%d'), days, remarks, ) response[u'request'] = True response[u'hours'] = True calendar = cal.Calendar(self.request.user) event = cal.Event( date_start, date_end + cal.oneday, u'NIEOB-[%s]' % self.request.user.name, remarks ) event_id = calendar.addEvent(event) response[u'calendar_entry'] = bool(event_id) return response self.request.response.status = 400 return form.errors