class TimesheetsController

File

timesheets_controller.rb

(C)

Hipposoft 2008

Purpose

Manage Timesheet objects. See models/timesheet.rb for more.


07-Jan-2008 (ADH): Created.

Public Instance Methods

create() click to toggle source

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 108
def create
  @timesheet             = Timesheet.new()
  @timesheet.year        = params[ :year ]
  @timesheet.week_number = params[ :week_number ]
  @timesheet.user        = @current_user
  @timesheet.committed   = false

  # Protect against people hacking around with forms submissions and
  # attempting to create new timesheets for already-claimed weeks

  clash = Timesheet.find_by_user_id_and_year_and_week_number(
    @current_user.id,
    @timesheet.year,
    @timesheet.week_number
  )

  if ( clash )
    flash[ :error ] = "A timesheet for week #{ @timesheet.week_number } has already been created."
  elsif ( @timesheet.save )
    flash[ :notice ] = 'New timesheet created and ready for editing.'
    redirect_to( edit_timesheet_path( @timesheet ) )
    return
  end

  render( :action => 'new' )
end
delete() click to toggle source

Timesheets should not normally be destroyed. Only administrators can do this.

# File app/controllers/timesheets_controller.rb, line 233
def delete
  appctrl_delete( 'Timesheet' )
end
destroy() click to toggle source
# File app/controllers/timesheets_controller.rb, line 237
def destroy
  appctrl_admin_destroy( Timesheet )
end
edit() click to toggle source

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 139
def edit
  @timesheet = Timesheet.find( params[ :id ] )
  return appctrl_not_permitted() unless @timesheet.can_be_modified_by?( @current_user )

  set_next_prev_week_variables( @timesheet )
  set_sections( @timesheet )

  @selected_rows = []
end
index() click to toggle source

List timesheets.

# File app/controllers/timesheets_controller.rb, line 25
def index

  # Set up the column data; see the index helper functions in
  # application_helper.rb for details.

  @columns = [
    { :header_text  => 'Start day',   :value_method => 'start_day',                 :sort_by => 'start_day_cache'             },
    { :header_text  => 'Owner',       :value_helper => :timesheethelp_owner,        :sort_by => 'users.name, start_day_cache' },
    { :header_text  => 'Last edited', :value_helper => :timesheethelp_updated_at,   :sort_by => 'updated_at'                  },
    { :header_text  => 'Committed',   :value_helper => :timesheethelp_committed_at, :sort_by => 'committed_at'                },
    { :header_text  => 'Hours',       :value_helper => :timesheethelp_hours,
      :header_align => 'center',      :value_align  => 'center'                                                               },
  ]

  # Get the basic options hash from ApplicationController, then work out
  # the conditions on objects being fetched, including handling the search
  # form data.

  options              = appctrl_index_assist( Timesheet )
  committed_vars       = { :committed => true,  :user_id => @current_user.id }
  not_committed_vars   = { :committed => false, :user_id => @current_user.id }
  user_conditions_sql  = "WHERE ( timesheets.committed = :committed ) AND ( users.id  = :user_id )\n"
  other_conditions_sql = "WHERE ( timesheets.committed = :committed ) AND ( users.id != :user_id )\n"

  range_sql, range_start, range_end = appctrl_search_range_sql( Timesheet, :start_day_cache )

  # If asked to search for something, build extra conditions to do so.

  unless ( range_sql.nil? )
    search_num = params[ :search ].to_i
    search_str = "%#{ params[ :search ] }%" # SQL wildcards either side of the search string

    conditions_sql = "AND #{ range_sql } ( timesheets.year = :search_num OR timesheets.week_number = :search_num OR users.name ILIKE :search_str )"
    vars           = { :search_num => search_num, :search_str => search_str, :range_start => range_start, :range_end => range_end }

    user_conditions_sql  << conditions_sql
    other_conditions_sql << conditions_sql

    committed_vars.merge!( vars )
    not_committed_vars.merge!( vars )
  end

  # Sort order is already partially compiled in 'options' from the earlier
  # call to 'appctrl_index_assist'.

  order_sql = "ORDER BY #{ options[ :order ] }"
  options.delete( :order )

  basic_sql = "SELECT timesheets.* FROM timesheets\n" <<
              "INNER JOIN users ON ( timesheets.user_id = users.id )"

  user_finder_sql  = "#{ basic_sql }\n#{ user_conditions_sql  }\n#{ order_sql }"
  other_finder_sql = "#{ basic_sql }\n#{ other_conditions_sql }\n#{ order_sql }"

  # Now paginate using this SQL query.

  @user_committed_timesheets      = Timesheet.paginate_by_sql( [ user_finder_sql,  committed_vars     ], options )
  @user_not_committed_timesheets  = Timesheet.paginate_by_sql( [ user_finder_sql,  not_committed_vars ], options )
  @other_committed_timesheets     = Timesheet.paginate_by_sql( [ other_finder_sql, committed_vars     ], options )
  @other_not_committed_timesheets = Timesheet.paginate_by_sql( [ other_finder_sql, not_committed_vars ], options )
end
new() click to toggle source

Prepare for the ‘new timesheet’ view.

# File app/controllers/timesheets_controller.rb, line 89
def new
  @years = Timesheet.allowed_range()

  @year  = params[ :menu ][ :year ].to_i if ( params[ :menu ] )
  @year  = @year || ( Time.new ).year

  @year -= 1 unless( params[ :previous ].nil? )
  @year += 1 unless( params[ :next     ].nil? )

  @year  = @years.first if ( @year < @years.first )
  @year  = @years.last  if ( @year > @years.last  )
end
show() click to toggle source

Show timesheet details.

# File app/controllers/timesheets_controller.rb, line 222
def show
  @timesheet = Timesheet.find( params[ :id ] )
  return appctrl_not_permitted() unless ( @timesheet and ( @current_user.privileged? or @timesheet.user_id == @current_user.id ) )

  set_next_prev_week_variables_for_show( @timesheet )
  set_sections( @timesheet )
end
update() click to toggle source

Update a timesheet, its rows and work packets.

# File app/controllers/timesheets_controller.rb, line 151
def update

  @timesheet = Timesheet.find( params[ :id ] )
  return appctrl_not_permitted() unless @timesheet.can_be_modified_by?( @current_user )

  @errors = update_backend( @timesheet )

  if ( @errors.nil? )
    flash[ :error ] = 'This timesheet was modified by someone else while you were making changes. Please examine the updated information before editing again.'
    redirect_to( timesheet_path( @timesheet ) )
    return
  end

  @timesheet.reload()

  set_next_prev_week_variables( @timesheet )
  set_sections( @timesheet )

  if ( @errors.empty? )
    flash[ :notice ] = "Week #{ @timesheet.week_number } changes saved."
  else
    restore_errant_form_data()
    render( :action => :edit )
    return
  end

  # Save and edit next or previous editable week, creating a clone
  # timesheet for a previously unused week if need be?

  if ( params[ :next ] or params[ :previous ] )
    another = params[ :next ] ? @next_week : @prev_week

    if ( another.nil? )
      flash[ :error ] = "Cannot find another week to edit in #{ @timesheet.year }."
      redirect_to( new_timesheet_path() )
      return
    end

    new_week      = another[ :week_number ]
    new_timesheet = another[ :timesheet   ]

    if ( new_timesheet.nil? )
      new_timesheet           = clone_timesheet( @timesheet, new_week )
      new_timesheet.committed = false

      if ( new_timesheet.nil? )
        flash[ :error ] = "Unable to create a new timesheet for week #{ new_week }."
      else
        flash[ :notice ] << " Now editing a new timesheet for week #{ new_week }."
      end
    else
      flash[ :notice ] << " Now editing the timesheet for week #{ new_week }."
    end

    if ( new_timesheet.nil? )
      redirect_to( new_timesheet_path() )
    else
      redirect_to( edit_timesheet_path( new_timesheet ) )
    end

  elsif ( @timesheet.committed || params[ :commit ] == 'Save changes and exit' )
    redirect_to( new_timesheet_path() )

  else
    render( :action => :edit )

  end
end