bookyt_projects 0.11.2 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,2 +1,20 @@
1
1
  #overview-capture_hours
2
- display: none
2
+ display: none
3
+
4
+ .strong
5
+ font-weight: bold
6
+
7
+ // Timesheets
8
+ tr
9
+ &.due_hours
10
+ background-color: #D1EED1 // block-message success
11
+ &.overtime
12
+ background-color: #DDF4FB // block-message info
13
+ &.undertime
14
+ background-color: #FDDFDE // block-message error
15
+ &.free, &.future
16
+ color: #BFBFBF // subtitle
17
+
18
+ tr.future
19
+ td.overtime, td.overall-overtime
20
+ color: transparent
@@ -1,5 +1,6 @@
1
1
  class ActivitiesController < AuthorizedController
2
2
  belongs_to :project, :optional => true
3
+ belongs_to :person, :optional => true
3
4
 
4
5
  has_scope :by_date
5
6
 
@@ -1,9 +1,5 @@
1
1
  class TimesheetsController < ApplicationController
2
2
  def index
3
3
  @employee = Employee.find(params[:employee_id])
4
- @employment = @employee.employments.current
5
-
6
- days = (Date.today.beginning_of_month..Date.today.end_of_month).to_a
7
- @work_days = days.map{|day| WorkDay.new(day, @employment)}
8
4
  end
9
5
  end
@@ -0,0 +1,28 @@
1
+ module TimesheetHelper
2
+ # Calculate classes for WorkDay rows
3
+ #
4
+ # We add a 0.5h margin when determine over/undertime.
5
+ # Days in the future get the 'future' class.
6
+ def work_day_classes(day)
7
+ # No classes for days in the future
8
+ return 'future' if day.date > Date.today
9
+
10
+ classes = []
11
+
12
+ # TODO: make a setting
13
+ # +/- 0.5h is good
14
+ margin = 0.5
15
+
16
+ if day.overtime > margin
17
+ classes << 'overtime'
18
+ elsif day.overtime < -margin
19
+ classes << 'undertime'
20
+ elsif day.hours_due == 0.0
21
+ classes << 'free'
22
+ else
23
+ classes << 'due_hours'
24
+ end
25
+
26
+ classes.join(' ')
27
+ end
28
+ end
@@ -1,24 +1,71 @@
1
1
  class WorkDay
2
- attr_accessor :date, :employment
2
+ attr_accessor :date, :employee
3
3
 
4
- def initialize(date, employment)
5
- @date = date
6
- @employment = employment
4
+ def initialize(employee, date)
5
+ @date = date
6
+ @employee = employee
7
7
  end
8
8
 
9
+ # Get WorkDay instances for a range
10
+ #
11
+ # Returns an array of WorkDay instances. You probably want
12
+ # to feed it a first day of month kind of starting_date.
13
+ #
14
+ # params:
15
+ # :employee: Employee to build WorkDay instances for
16
+ # :range: Date range giving first and last day
17
+ def self.for_range(employee, range)
18
+ range.to_a.map{|day| WorkDay.new(employee, day)}
19
+ end
20
+
21
+ # Get WorkDay instances for a month
22
+ #
23
+ # params:
24
+ # :employee: Employee to build WorkDay instances for
25
+ # :date_in_month: Any day in the requested month. Uses today by default.
26
+ def self.for_month(employee, date_in_month = nil)
27
+ # Assume today if no date given
28
+ date_in_month ||= Date.today
29
+
30
+ start_date = date_in_month.beginning_of_month
31
+ end_date = date_in_month.end_of_month
32
+
33
+ self.for_range(employee, start_date..end_date)
34
+ end
35
+
36
+ # Helper to access daily workload
37
+ #
38
+ # Returns 0.0 if no current daily_workload can be determined
39
+ def daily_workload
40
+ # Guard
41
+ return 0.0 unless employee && employee.employments.current && employee.employments.current.daily_workload
42
+
43
+ employee.employments.current.daily_workload
44
+ end
45
+
46
+ # Working hours for this day
9
47
  def hours_due
10
48
  case date.wday
11
49
  when 6, 0
50
+ # Saturday and sunday are off
12
51
  0.0
13
52
  else
14
- employment.daily_workload
53
+ # Assume same working hours during the week
54
+ daily_workload
15
55
  end
16
56
  end
17
57
 
58
+ # Hours worked
59
+ #
60
+ # Calculates hours worked by summing up duration of all logged
61
+ # activities.
18
62
  def hours_worked
19
- employment.employee.activities.where(:date => date).to_a.sum(&:duration)
63
+ employee.activities.where(:date => date).to_a.sum(&:duration)
20
64
  end
21
65
 
66
+ # Overtime
67
+ #
68
+ # Simply substract hours_due from hours_worked.
22
69
  def overtime
23
70
  hours_worked - hours_due
24
71
  end
@@ -2,6 +2,3 @@
2
2
  %td= activity.person
3
3
  %td= link_to activity.date, activity, {'data-href-container' => 'tr'}
4
4
  %td= t('bookyt.projects.minutes', :duration => activity.duration)
5
- %td.action-links
6
- = list_link_for(:edit, activity, :remote => true)
7
- = list_link_for(:delete, activity)
@@ -2,6 +2,5 @@
2
2
  %tr
3
3
  - [:person, :date, :duration].each do |attr|
4
4
  %th= t_attr(attr, Activity)
5
- %th.action-links
6
5
 
7
6
  = render collection
@@ -0,0 +1 @@
1
+ = render 'activities/list', :collection => resource.activities
@@ -0,0 +1 @@
1
+ = render 'timesheets/show'
@@ -1,11 +1,17 @@
1
1
  = semantic_form_for @project do |f|
2
2
  = f.semantic_errors
3
3
  = f.inputs do
4
- = f.input :name, :input_html => {'data-autofocus' => 'true'}
5
- = f.input :comment, :input_html => {:rows => 5}
6
- = f.input :duration_from, :as => :date_field
7
- = f.input :duration_to, :as => :date_field
8
- = f.input :project_state
9
- = f.input :client, :as => :combobox
4
+ .row
5
+ .span8
6
+ = f.input :name, :input_html => {'data-autofocus' => 'true'}
7
+ = f.input :duration_from, :as => :date_field
8
+ = f.input :client, :as => :combobox
9
+ .span8
10
+ = f.input :project_state
11
+ = f.input :duration_to, :as => :date_field
12
+ .row
13
+ .span16
14
+ = f.input :comment, :input_html => {:rows => 5, :class => 'span12'}
15
+
10
16
  = f.buttons do
11
17
  = f.commit_button
@@ -1,8 +1,7 @@
1
- .form-view
2
- = render 'form'
1
+ %ul.tabs
2
+ %li.active= link_to 'Details', '#details'
3
+ %li= link_to 'Stundenrapport', '#activities'
3
4
 
4
- .contextual
5
- = icon_link_to :new, new_project_activity_path(resource)
6
- %h2= t_title :index, Activity
7
-
8
- = render 'activities/list', :collection => @project.activities
5
+ .tab-content
6
+ #details.active= render "form"
7
+ #activities= render 'show_activities'
@@ -0,0 +1,5 @@
1
+ .contextual
2
+ = icon_link_to :new, new_project_activity_path(resource)
3
+ %h2= t_title :index, Activity
4
+
5
+ = render 'activities/list', :collection => @project.activities
@@ -0,0 +1,3 @@
1
+ - activities.each do |activity|
2
+ %h4= "#{activity.project.name}: #{activity.duration}"
3
+ %p= activity.comment
@@ -0,0 +1,20 @@
1
+ %table.condensed-table.span8
2
+ %tr
3
+ %th= t_attr :date, Activity
4
+ %th.number= t_attr :working_hours, Activity
5
+ %th.number= t_attr :overtime, Activity
6
+ %th.number= t_attr :overall_overtime, Activity
7
+
8
+ - overall_overtime = 0
9
+ - WorkDay.for_month(@employee).each do |day|
10
+ - overall_overtime += day.overtime
11
+ - activities = @employee.activities.where(:date => day.date)
12
+ - tr_params = {:class => work_day_classes(day)}
13
+ - tr_params.merge!(:rel => 'popover', 'data-content' => h(render 'activities_popover', :activities => activities), 'data-original-title' => 'Aktivitäten', 'data-html' => 'true') unless activities.empty?
14
+ %tr{tr_params}
15
+ %td= link_to l(day.date, :format => '%a, %d.%m.%Y'), person_activities_path(@employee, :by_date => day.date.to_s(:db)), 'data-href-container' => 'tr'
16
+ %td.number
17
+ %span.strong= "%0.1f" % day.hours_worked
18
+ = "(%0.1f)" % day.hours_due
19
+ %td.number.overtime.strong= day.overtime
20
+ %td.number.overall-overtime.strong= overall_overtime
@@ -1,24 +1,7 @@
1
1
  .contextual
2
2
  = contextual_link_to :new, Activity
3
3
 
4
- %h1= t_title
4
+ .page-header
5
+ %h1= t_title
5
6
 
6
- %table.list
7
- %tr
8
- %th= t_attr :date, Activity
9
- %th Wochentag
10
- %th.number= t_attr :hours_due, Activity
11
- %th.number= t_attr :hours_worked, Activity
12
- %th.number= t_attr :overtime, Activity
13
- %th.number= t_attr :overall_overtime, Activity
14
-
15
- - overall_overtime = 0
16
- - @work_days.each do |day|
17
- - overall_overtime += day.overtime
18
- %tr
19
- %td= day.date
20
- %td= l(day.date, :format => '%A')
21
- %td.number= day.hours_due
22
- %td.number= day.hours_worked
23
- %td.number= day.overtime
24
- %td.number= overall_overtime
7
+ = render 'show'
@@ -33,6 +33,7 @@ de:
33
33
  time: Zeitraum
34
34
  hours_due: Soll-Stunden
35
35
  hours_worked: Arbeitsstunden
36
+ working_hours: Stunden (Soll)
36
37
  overtime: Über-/Unterzeit
37
38
  overall_overtime: Saldo
38
39
 
@@ -51,3 +52,7 @@ de:
51
52
  activities:
52
53
  new:
53
54
  title: Zeit erfassen
55
+ list:
56
+ title: Aktivitäten
57
+ timesheet:
58
+ title: Stundenrapport
data/config/routes.rb CHANGED
@@ -9,4 +9,8 @@ Rails.application.routes.draw do
9
9
  resources :employees do
10
10
  resources :timesheets
11
11
  end
12
+
13
+ resources :people do
14
+ resources :activities
15
+ end
12
16
  end
@@ -2,9 +2,11 @@ module BookytProjects
2
2
  module Navigation
3
3
  def setup_bookyt_projects(navigation)
4
4
  navigation.item :projects, t('bookyt.main_navigation.projects'), projects_path, :if => Proc.new { user_signed_in? } do |projects|
5
- projects.item :capture_hours, t('activities.new.title'), new_batch_activity_path
6
5
  projects.item :project_index, t_title(:index, Project), projects_path, :highlights_on => /\/(projects|activities)($|\/[0-9]*($|\/.*))/
7
6
  projects.item :new_project, t_title(:new, Project), new_project_path
7
+ projects.item :divider, "", :class => 'divider'
8
+ projects.item :capture_hours, t('activities.new.title'), new_batch_activity_path
9
+ projects.item :divider, "", :class => 'divider'
8
10
  projects.item :project_states, t_model(ProjectState), project_states_path, :highlights_on => /\/project_states($|\/([0-9]*|new)($|\/.*))/
9
11
  end
10
12
  end
@@ -1,3 +1,3 @@
1
1
  module BookytPos
2
- VERSION = '0.11.2'
2
+ VERSION = '0.12.0'
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bookyt_projects
3
3
  version: !ruby/object:Gem::Version
4
- hash: 55
4
+ hash: 47
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 11
9
- - 2
10
- version: 0.11.2
8
+ - 12
9
+ - 0
10
+ version: 0.12.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Roman Simecek (CyT)
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2012-01-13 00:00:00 Z
19
+ date: 2012-01-16 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: rails
@@ -108,6 +108,7 @@ files:
108
108
  - app/controllers/project_states_controller.rb
109
109
  - app/controllers/projects_controller.rb
110
110
  - app/controllers/timesheets_controller.rb
111
+ - app/helpers/timesheet_helper.rb
111
112
  - app/models/activity.rb
112
113
  - app/models/bookyt_projects/person.rb
113
114
  - app/models/project.rb
@@ -118,11 +119,16 @@ files:
118
119
  - app/views/activities/_list.html.haml
119
120
  - app/views/batch_activities/_form.html.haml
120
121
  - app/views/batch_activities/new.html.haml
122
+ - app/views/people/_show_activities.html.haml
123
+ - app/views/people/_show_timesheet.html.haml
121
124
  - app/views/project_states/_form.html.haml
122
125
  - app/views/projects/_form.html.haml
123
126
  - app/views/projects/_list.html.haml
124
127
  - app/views/projects/_project.html.haml
125
128
  - app/views/projects/_show.html.haml
129
+ - app/views/projects/_show_activities.html.haml
130
+ - app/views/timesheets/_activities_popover.html.haml
131
+ - app/views/timesheets/_show.html.haml
126
132
  - app/views/timesheets/index.html.haml
127
133
  - config/application.rb
128
134
  - config/boot.rb
@@ -168,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
174
  requirements: []
169
175
 
170
176
  rubyforge_project:
171
- rubygems_version: 1.8.12
177
+ rubygems_version: 1.8.15
172
178
  signing_key:
173
179
  specification_version: 3
174
180
  summary: Project management plugin for bookyt