Fix the timesheet computation bug and reorganised by date range instead of week

This commit is contained in:
Sharoon Thomas 2012-12-20 17:39:23 +00:00
parent 943901f4ba
commit 6e0b566567
1 changed files with 37 additions and 30 deletions

View File

@ -997,23 +997,32 @@ class Project(ModelSQL, ModelView):
end = datetime.fromtimestamp(
request.args.get('end', type=int)
).date()
day_week_map = {}
if (end - start).days < 20:
# this is not a month call, just some smaller range
return start, end, day_week_map
return start, end
# This is a data call for a month, but fullcalendar tries to
# fill all the days in the first and last week from the prev
# and next month. So just return start and end date of the month
mid_date = start + relativedelta(days=((end - start).days / 2))
ignore, last_day = calendar.monthrange(mid_date.year, mid_date.month)
for week, days in enumerate(calendar.monthcalendar(mid_date.year, mid_date.month), 1):
day_week_map.update(dict.fromkeys(days, week))
return (
date(year=mid_date.year, month=mid_date.month, day=1),
date(year=mid_date.year, month=mid_date.month, day=last_day),
day_week_map
)
def get_week(self, day):
"""
Return the week for any given day
"""
if (day >= 1) and (day <= 7):
return '01-07'
elif (day >= 8) and (day <= 14):
return '08-14'
elif (day >= 15) and (day <= 21):
return '15-21'
else:
return '22-END'
def get_calendar_data(self, domain=None):
"""
Returns the calendar data
@ -1022,7 +1031,7 @@ class Project(ModelSQL, ModelView):
"""
timesheet_obj = Pool().get('timesheet.line')
start, end, day_week_map = self._get_expected_date_range()
start, end = self._get_expected_date_range()
if domain is None:
domain = []
@ -1039,31 +1048,28 @@ class Project(ModelSQL, ModelView):
domain, order=[('date', 'asc'), ('employee', 'asc')]
)
# Build an iterable
hours_by_day_employee = defaultdict(lambda: defaultdict(float))
hours_by_week_employee = defaultdict(lambda: defaultdict(float))
get_week = self.get_week
lines = timesheet_obj.browse(line_ids)
for line in lines:
hours_by_day_employee[line.date][line.employee] += line.hours
hours_by_week_employee[get_week(line.date.day)][line.employee] += line.hours
data = {}
data_by_week = {}
for date, g_by_date in groupby(lines, key=lambda line: line.date):
for k, g in groupby(g_by_date, key=lambda line: line.employee):
data.setdefault(date, {})[k] = sum(
[line.hours for line in g]
)
if day_week_map:
week = day_week_map[date.day]
data_by_week.setdefault(week, {}).setdefault(line.employee, 0)
data_by_week[week][line.employee] += line.hours
day_totals=[]
day_totals = []
color_map = {}
colors = cycle([
'grey', 'RoyalBlue', 'CornflowerBlue', 'DarkSeaGreen',
'SeaGreen', 'Silver', 'MediumOrchid', 'Olive',
'maroon', 'PaleTurquoise'
])
for date, employee_hours in data.iteritems():
day_totals_append = day_totals.append # Performance speedup
for date, employee_hours in hours_by_day_employee.iteritems():
for employee, hours in employee_hours.iteritems():
day_totals.append({
day_totals_append({
'id': '%s.%s' % (date, employee.id),
'title': '%s (%dh %dm)' % (
employee.name, hours, (hours * 60) % 60
@ -1076,21 +1082,22 @@ class Project(ModelSQL, ModelView):
task_id, = self.search([('work', '=', work.id)])
return self.browse(task_id)
reverse_lines = line_ids[::-1]
lines = [
render_template(
'project/timesheet-line.jinja', line=line,
related_task=get_task_from_work(line.work)
) \
for line in timesheet_obj.browse(line_ids)
for line in timesheet_obj.browse(reverse_lines)
]
total_by_employee = {}
for emp_hours_map in data_by_week.values():
for employee, hours in emp_hours_map.iteritems():
total_by_employee[employee] = total_by_employee.setdefault(
employee, 0
) + hours
total_by_employee = defaultdict(float)
for employee_hours in hours_by_week_employee.values():
for employee, hours in employee_hours.iteritems():
total_by_employee[employee] += hours
work_week = render_template(
'project/work-week.jinja', data_by_week=data_by_week,
'project/work-week.jinja', data_by_week=hours_by_week_employee,
total_by_employee=total_by_employee
)
return jsonify(day_totals=day_totals, lines=lines, work_week=work_week)