class WorksController < ApplicationController in_place_edit_for :work, :hours in_place_edit_for :work, :invoice in_place_edit_for :work, :start_time in_place_edit_for :work, :completed_at_time skip_before_filter :populate_layout, :except => [:create, :destroy, :edit, :index, :list, :new, :show, :update] auto_complete_for :work, :description def index list render :action => 'list' end # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) verify :method => :post, :only => [ :destroy, :create, :update ], :redirect_to => { :action => :list } def list @period = params[:id] && Period.find(params[:id]) @works = Work.paginate :order => 'completed_at', :page => params[:page] end def show @work = Work.find(params[:id]) end def new unless @work @work = Work.new(params[:work]) @work.user = user end @estimate ||= Estimate.new(params[:estimate]) @work_accounts = WorkAccount.find(:all, :order => :name) @tasks = Task.find_open @users = User.find(:all) end def create if params[:work] backlog_name = params[:work].delete(:backlog_name) task_description = params[:work].delete(:task_description) if backlog_name && backlog_name.size > 0 && task_description && task_description.size > 0 backlog = Backlog.find_by_name(backlog_name) task = backlog.tasks_with_children.find{|t| t.description == task_description} params[:work][:task_id] = task.id if task end convert_work_account_param convert_customer_param unless convert_hours_param flash[:notice] = "Illegal time format" #@work.errors.add :hours_time, "Illegal time format." params[:work].delete(:hours_time) end @work = Work.new(params[:work]) @work.started_on ||= Date.today @work.completed_at = Time.now unless @work.start_time || @work.completed_at @work.calculate_hours! unless @work.hours && @work.hours.to_f > 0 @work.user_id = current_user.id end if @work && @work.save flash[:notice] = 'Work was successfully created.' @work.task.grab if @work.task else if params[:detour] flash[:notice] = 'Error creating new work record.' back else new render :action => 'new' end return end @work.task.estimates.create!(params[:estimate]) if @work.task && params[:estimate] back_or_redirect_to :controller => 'periods', :action => 'show', :id => @work.task && @work.task.period, :task_id => @work.task && @work.task.id end def convert_work_account_param account_name = params[:work].delete :work_account_name if account_name && account_name.size > 0 account = WorkAccount.find_by_name account_name params[:work][:work_account_id] = account.id end end private :convert_work_account_param def convert_customer_param customer_name = params[:work].delete :customer_name if customer_name && customer_name.size > 0 customer = Customer.find_by_name customer_name if (customer.nil?) customer = Customer.create! :name => customer_name end params[:work][:customer_id] = customer.id end end private :convert_customer_param def edit @work ||= Work.find(params[:id]) @work.attributes = params[:work] @estimate = Estimate.new(params[:estimate]) @work_accounts = WorkAccount.find(:all) @tasks = Task.find_open @tasks.unshift @work.task if @work.task @users = User.find(:all) end def update if update_work if @work.task back_or_redirect_to :controller => 'periods', :action => 'show', :id => @work.task.period, :task_id => @work.task.id else back_or_redirect_to :controller => 'welcome', :action => 'index' end else @task = @work.task edit render :action => 'edit' end end def update_row if update_work #flash.discard @next_field = params[:next_field] || 'description' works = Work.find_work_for_day((@work.started_on || @work.completed_at).to_date) @day_total = works.inject(BigDecimal('0')){|total,work|total+=work.hours} else @next_field = params[:field] || 'description' end @work_accounts = WorkAccount.find(:all, :order => :name) @customers = Customer.find(:all, :order => :name) end def update_time update_work flash.discard @field = params[:field] || 'start_time' end def update_work @work = Work.find(params[:id]) unless convert_hours_param flash[:notice] = "Illegal time format" @work.errors.add :hours_time, "Illegal time format." return false end if @work.update_attributes(params[:work]) if params[:work] && (params[:work][:start_time] || params[:work][:completed_at_time]) @work.calculate_hours! @work.save! end flash[:notice] = 'Work was successfully updated.' if @work.task if params[:estimate] if (@estimate = @work.task.estimates.create(params[:estimate])).errors.size == 0 return true end else return true end else return true end end return false end def destroy work = Work.find(params[:id]) period = work.task && work.task.period work.destroy back_or_redirect_to :controller => 'periods', :action => :list_work, :id => period end def daily_work_sheet @date = (params[:id] && Date.parse(params[:id])) || Date.today @year = @date.year @week = @date.cweek @periods = [] @works = Work.find_work_for_day @date @customers = Customer.find(:all, :order => :name) @started_works = Task.find_started @work = Work.new(:started_at => Time.now, :completed_at => Time.now) @work_accounts = WorkAccount.find(:all, :order => :name) @absence = Absence.find(:first, :conditions => {:on => @date, :user_id => current_user.id}) @public_holiday = PublicHoliday.find(:first, :conditions => {:on => @date}) render :layout => 'wide' end def weekly_work_sheet @year = (params[:year] && params[:year].to_i) || Date.today.year @week = (params[:week] && params[:week].to_i) || Date.today.cweek @rows = Work.works_for_week(@year, @week) @first_date = Date.commercial(@year, @week, 1) @last_date = @first_date + 6 @lock = WorkLock.find(:first, :conditions => ['user_id = ? AND start_on <= ? AND end_on >= ?', current_user.id, @first_date, @last_date]) render :layout => 'wide' end def weekly_work_sheet_by_work_account @year = (params[:year] && params[:year].to_i) || Date.today.year @week = (params[:week] && params[:week].to_i) || Date.today.cweek @user = params[:user_id] ? User.find(params[:user_id]) : current_user @work_accounts = Work.works_for_week_by_work_account(@year, @week, @user) @first_date = Date.commercial(@year, @week, 1) @last_date = @first_date + 6 @lock = WorkLock.find(:first, :conditions => ['user_id = ? AND start_on <= ? AND end_on >= ?', current_user.id, @first_date, @last_date]) @absences = Absence.find(:all, :conditions => ['"on" BETWEEN ? AND ?', @first_date, @last_date], :order => '"on"') (0..6).each do |day| @absences.insert(day, nil) if @absences[day] && @absences[day].on > @first_date + day end render :layout => 'wide' end def timeliste @year = (params[:year] && params[:year].to_i) || Date.today.year @week = (params[:week] && params[:week].to_i) || Date.today.cweek @work_totals_per_work_account = Work.work_totals_for_week(@year, @week) headers["Content-Type"] = "application/vnd.ms-excel" headers["Content-Disposition"] = 'attachment; filename="export.xml"' render :layout => false end def auto_complete_for_work_work_account_name @accounts = WorkAccount.find(:all, :conditions => [ 'LOWER(name) LIKE ?', '%' + params[:work][:work_account_name].downcase + '%' ], :order => 'name ASC', :limit => 16) render :partial => '/work_accounts/name_list' end def auto_complete_for_work_customer_name @customers = Customer.find(:all, :conditions => [ 'LOWER(name) LIKE ?', '%' + params[:work][:customer_name].downcase + '%' ], :order => 'name ASC', :limit => 16) render :partial => '/customers/name_list' end def auto_complete_for_work_backlog_name @backlogs = Backlog.find(:all, :conditions => [ 'LOWER(name) LIKE ?', '%' + params[:work][:backlog_name].downcase + '%' ], :order => 'name ASC', :limit => 16) render :partial => '/backlogs/name_list' end def auto_complete_for_work_task_id @tasks = [] if (search_id = params[:work][:task_id].to_i) > 0 @tasks += Task.find(:all, :conditions => [ "id = ? OR id BETWEEN ? AND ?", search_id, search_id * 10, ((search_id+1) * 10 -1) ], :order => 'id', :limit => 10) end @tasks += Task.find(:all, :conditions => [ "finished_at IS NULL AND LOWER(description) LIKE ?", '%' + params[:work][:task_id].downcase + '%' ], :order => 'description ASC', :limit => 10) render :partial => 'task_id_list' end def calculate_hours calculated_duration = (Time.parse(params[:completed_at]) - Time.parse(params[:started_at])) new_value = '%2d:%02d' % [calculated_duration / 3600, (calculated_duration % 3600) / 60] render :update do |page| page['work_hours_time'].value = new_value end end def update_new_row @field = params[:field] @next_field = params[:next_field] convert_work_account_param convert_customer_param raise "Unknown time format: #{params[:hours_time]}" unless convert_hours_param @work = Work.new(params[:work]) @updated_fields = [@field] if @work.hours == 0 && @work.started_on && @work.start_time && @work.completed_at @work.calculate_hours! @updated_fields << :hours_time end end private def convert_hours_param if params[:work] && params[:work][:hours_time] params[:work][:hours_time].strip! if params[:work][:hours_time].empty? params[:work].delete(:hours_time) params[:work][:hours] = 0 return true end if params[:work][:hours_time] =~ /^(\d*):(\d{2})?$/ new_hours = $1 new_minutes = $2.to_i new_value_str = "#{new_hours}.#{(new_minutes / 0.6).round}" new_value = BigDecimal(new_value_str) params[:work][:hours] = new_value elsif params[:work][:hours_time] =~ /^(\d*)[.,]?(\d*)$/ params[:work][:hours] = BigDecimal("#{$1.to_i}.#{$2.to_i}") else #raise "Unknown time format: '#{params[:work][:hours_time]}'" return false end params[:work].delete :hours_time end return true end end