Class | TimesheetsController |
In: |
app/controllers/timesheets_controller.rb
|
Parent: | ApplicationController |
File: | timesheets_controller.rb |
(C): | Hipposoft 2008, 2009 |
Purpose: | Manage Timesheet objects. See models/timesheet.rb for more. |
07-Jan-2008 (ADH): Created.
Create a blank timesheet based on the year and week_number values in the params hash. Save and redirect to edit the timesheet immediately. Certain defaults are set up here - the model would be a better place, but it does not have access to the right instance variables or methods required to determine the appropriate values.
# File app/controllers/timesheets_controller.rb, line 122 122: def create 123: @timesheet = Timesheet.new() 124: @timesheet.year = params[ :year ] 125: @timesheet.week_number = params[ :week_number ] 126: @timesheet.user = @current_user 127: @timesheet.committed = false 128: 129: # Protect against people hacking around with forms submissions and 130: # attempting to create new timesheets for already-claimed weeks 131: 132: clash = Timesheet.find_by_user_id_and_year_and_week_number( 133: @current_user.id, 134: @timesheet.year, 135: @timesheet.week_number 136: ) 137: 138: if ( clash ) 139: flash[ :error ] = "A timesheet for week #{ @timesheet.week_number } has already been created." 140: elsif ( @timesheet.save ) 141: flash[ :notice ] = 'New timesheet created and ready for editing.' 142: redirect_to( edit_timesheet_path( @timesheet ) ) 143: return 144: end 145: 146: render( :action => 'new' ) 147: end
Timesheets should not normally be destroyed. Only administrators can do this.
# File app/controllers/timesheets_controller.rb, line 241 241: def delete 242: appctrl_delete( 'Timesheet' ) 243: end
# File app/controllers/timesheets_controller.rb, line 245 245: def delete_confirm 246: appctrl_delete_confirm( 'Timesheet' ) 247: end
Prepare to edit a timesheet. Any defaults are established by the models automatically. Rows and work packets are included in the editing form.
# File app/controllers/timesheets_controller.rb, line 153 153: def edit 154: @timesheet = Timesheet.find( params[ :id ] ) 155: return appctrl_not_permitted() unless @timesheet.can_be_modified_by?( @current_user ) 156: 157: set_next_prev_week_variables( @timesheet ) 158: end
List timesheets.
# File app/controllers/timesheets_controller.rb, line 24 24: def index 25: 26: # Set up the column data; see the index helper functions in 27: # application_helper.rb for details. 28: 29: @columns = [ 30: { :header_text => 'Year', :value_method => 'year', 31: :header_align => 'center', :value_align => 'center' }, 32: { :header_text => 'Week', :value_method => 'week_number', 33: :header_align => 'center', :value_align => 'center' }, 34: { :header_text => 'Start day', :value_method => 'start_day', :sort_by => 'year, week_number' }, 35: { :header_text => 'Owner', :value_helper => :timesheethelp_owner, :sort_by => 'users.name' }, 36: { :header_text => 'Last edited', :value_helper => :timesheethelp_updated_at, :sort_by => 'updated_at' }, 37: { :header_text => 'Committed', :value_helper => :timesheethelp_committed_at, :sort_by => 'committed_at' }, 38: { :header_text => 'Hours', :value_helper => :timesheethelp_hours, 39: :header_align => 'center', :value_align => 'center' }, 40: ] 41: 42: # Get the basic options hash from ApplicationController, then work out 43: # the conditions on objects being fetched, including handling the search 44: # form data. 45: 46: options = appctrl_index_assist( Timesheet ) 47: committed_vars = { :committed => true, :user_id => @current_user.id } 48: not_committed_vars = { :committed => false, :user_id => @current_user.id } 49: user_conditions_sql = "WHERE ( timesheets.committed = :committed ) AND ( users.id = :user_id )\n" 50: other_conditions_sql = "WHERE ( timesheets.committed = :committed ) AND ( users.id != :user_id )\n" 51: 52: # If asked to search for something, build extra conditions to do so. 53: 54: unless ( params[ :search ].nil? ) 55: if ( params[ :search ].empty? or params[ :search_cancel ] ) 56: params.delete( :search ) 57: else 58: search_num = params[ :search ].to_i 59: search_str = "%#{ params[ :search ] }%" # SQL wildcards either side of the search string 60: conditions_sql = "AND ( timesheets.year = :search_num OR timesheets.week_number = :search_num OR users.name ILIKE :search_str )" 61: vars = { :search_num => search_num, :search_str => search_str } 62: 63: user_conditions_sql << conditions_sql 64: other_conditions_sql << conditions_sql 65: 66: committed_vars.merge!( vars ) 67: not_committed_vars.merge!( vars ) 68: end 69: end 70: 71: # Sort order is already partially compiled in 'options' from the earlier 72: # call to 'appctrl_index_assist'. 73: 74: order_sql = "ORDER BY #{ options[ :order ] }" 75: options.delete( :order ) 76: 77: # Compile the main SQL statement. Select all columns of the project, fetching 78: # customers where the project's customer ID matches those customer IDs, with 79: # only projects containing tasks in the user's permitted task list (if any) 80: # are included, returned in the required order. 81: # 82: # Due to restrictions in the way that DISTINCT works, I just cannot figure out 83: # ANY way in SQL to only return unique projects while still matching the task 84: # permitted ID requirement for restricted users. So, fetch duplicates, then 85: # strip them out in Ruby afterwards (ouch). 86: 87: basic_sql = "SELECT timesheets.* FROM timesheets\n" << 88: "INNER JOIN users ON ( timesheets.user_id = users.id )" 89: 90: user_finder_sql = "#{ basic_sql }\n#{ user_conditions_sql }\n#{ order_sql }" 91: other_finder_sql = "#{ basic_sql }\n#{ other_conditions_sql }\n#{ order_sql }" 92: 93: # Now paginate using this SQL query. 94: 95: @user_committed_timesheets = Timesheet.paginate_by_sql( [ user_finder_sql, committed_vars ], options ) 96: @user_not_committed_timesheets = Timesheet.paginate_by_sql( [ user_finder_sql, not_committed_vars ], options ) 97: @other_committed_timesheets = Timesheet.paginate_by_sql( [ other_finder_sql, committed_vars ], options ) 98: @other_not_committed_timesheets = Timesheet.paginate_by_sql( [ other_finder_sql, not_committed_vars ], options ) 99: end
Prepare for the ‘new timesheet’ view.
# File app/controllers/timesheets_controller.rb, line 103 103: def new 104: @years = Timesheet.allowed_range() 105: 106: @year = params[ :menu ][ :year ].to_i if ( params[ :menu ] ) 107: @year = @year || ( Time.new ).year 108: 109: @year -= 1 unless( params[ :previous ].nil? ) 110: @year += 1 unless( params[ :next ].nil? ) 111: 112: @year = @years.first if ( @year < @years.first ) 113: @year = @years.last if ( @year > @years.last ) 114: end
Show timesheet details.
# File app/controllers/timesheets_controller.rb, line 231 231: def show 232: @timesheet = Timesheet.find( params[ :id ] ) 233: return appctrl_not_permitted() unless ( @timesheet and ( @current_user.privileged? or @timesheet.user_id == @current_user.id ) ) 234: 235: set_next_prev_week_variables_for_show( @timesheet ) 236: end
Update a timesheet, its rows and work packets.
# File app/controllers/timesheets_controller.rb, line 162 162: def update 163: 164: @timesheet = Timesheet.find( params[ :id ] ) 165: return appctrl_not_permitted() unless @timesheet.can_be_modified_by?( @current_user ) 166: 167: @errors = update_backend( @timesheet ) 168: 169: if ( @errors.nil? ) 170: flash[ :error ] = 'This timesheet was modified by someone else while you were making changes. Please examine the updated information before editing again.' 171: redirect_to( timesheet_path( @timesheet ) ) 172: return 173: end 174: 175: @timesheet.reload() 176: 177: if ( @errors.empty? ) 178: flash[ :notice ] = "Week #{ @timesheet.week_number } changes saved." 179: else 180: render( :action => :edit ) 181: return 182: end 183: 184: set_next_prev_week_variables( @timesheet ) 185: 186: # Save and edit next or previous editable week, creating a clone 187: # timesheet for a previously unused week if need be? 188: 189: if ( params[ :next ] or params[ :previous ] ) 190: another = params[ :next ] ? @next_week : @prev_week 191: 192: if ( another.nil? ) 193: flash[ :error ] = "Cannot find another week to edit in #{ @timesheet.year }." 194: redirect_to( new_timesheet_path() ) 195: return 196: end 197: 198: new_week = another[ :week_number ] 199: new_timesheet = another[ :timesheet ] 200: 201: if ( new_timesheet.nil? ) 202: new_timesheet = clone_timesheet( @timesheet, new_week ) 203: new_timesheet.committed = false 204: 205: if ( new_timesheet.nil? ) 206: flash[ :error ] = "Unable to create a new timesheet for week #{ new_week }." 207: else 208: flash[ :notice ] << " Now editing a new timesheet for week #{ new_week }." 209: end 210: else 211: flash[ :notice ] << " Now editing the timesheet for week #{ new_week }." 212: end 213: 214: if ( new_timesheet.nil? ) 215: redirect_to( new_timesheet_path() ) 216: else 217: redirect_to( edit_timesheet_path( new_timesheet ) ) 218: end 219: 220: elsif ( @timesheet.committed || params[ :commit ] == 'Save changes and exit' ) 221: redirect_to( new_timesheet_path() ) 222: 223: else 224: render( :action => :edit ) 225: 226: end 227: end