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] def index 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 backlog_name = (params[:backlog_id] && Backlog.find(params[:backlog_id]).name) || l(:all_accounts) @report_filter = WorksReportFilter.new(params[:report_filter]) @report_filter.title = "#{l :hours} for #{backlog_name} #{@report_filter.start_on && @report_filter.start_on.strftime('%Y-%m-%d - ')}#{@report_filter.end_on && @report_filter.end_on.strftime('%Y-%m-%d')}" @period = params[:id] && Period.find(params[:id]) @works = Work.paginate :conditions => ["started_on BETWEEN ? AND ? #{'AND backlog_id = ?' if @report_filter.backlog_id} #{@report_filter.invoice.nil? ? '' : 'AND invoice = ?'} #{@report_filter.user_id.nil? ? '' : 'AND user_id = ?'}", @report_filter.start_on, @report_filter.end_on, @report_filter.backlog_id, @report_filter.invoice, @report_filter.user_id].compact, :page => params[:page], :per_page => @report_filter.page_size, :order => 'started_on, start_time, completed_at' @backlogs = Backlog.find(:all, :order => :name) @users = User.find(:all, :order => 'first_name, last_name') if params[:export] == 'excel' @works = @works.sort_by {|w| [w.user_id || 0, w.task_id || 999999, w.started_on]} render :template => '/works/list_excel', :layout => false else render :template => '/works/list' end 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]) @backlogs = Backlog.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_backlog_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 params[:work][:task_id].strip! unless params[:work][:task_id].nil? @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.' flash[:work] = @work back else new render :action => 'new' end return end @work.task.estimates.create!(params[:estimate]) if @work.task && params[:estimate] if @work.task back_or_redirect_to :controller => 'periods', :action => 'show', :id => @work.task && @work.task.period, :task_id => @work.task && @work.task.id else back_or_redirect_to :controller => 'works', :action => 'daily_work_sheet', :id => @work.started_on.strftime('%Y-%m-%d') end end def convert_backlog_param account_name = params[:work].delete :backlog_name if account_name && account_name.size > 0 account = Backlog.find_by_name account_name params[:work][:backlog_id] = account.id end end private :convert_backlog_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]) @backlogs = Backlog.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 @backlogs = Backlog.find(:all, :order => :name) @customers = Customer.find(:all, :order => :name) if flash[:work] @new_work = flash[:work] elsif @works @new_work = Work.new((@works.last && @works.last.completed_at) ? {:started_at => @works.last.completed_at} : nil) else @new_work = Work.new end 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.cwyear @week = @date.cweek if params[:user_id] @user = User.find_by_id(params[:user_id]) if @user.nil? flash[:notice] = l(:cannot_find_user, params[:user_id]) back_or_redirect_to '/' return end else @user = current_user end @periods = [] @works = Work.find_work_for_day(@date, @user) @customers = Customer.find(:all, :order => :name) @started_works = Task.find_started @new_work = flash[:work] || Work.new(@works.last && @works.last.completed_at ? {:started_at => @works.last.completed_at} : nil) @backlogs = Backlog.find(:all, :order => :name) @absence = Absence.find(:first, :conditions => {:on => @date, :user_id => @user.id}) @public_holiday = PublicHoliday.find(:first, :conditions => {:on => @date}) render :layout => 'wide' end def weekly_work_sheet_details @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 @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 @backlogs = Work.works_for_week_by_backlog(@year, @week, @user) @first_date = Date.commercial(@year, @week, 1) @last_date = @first_date + 6 @lock = WorkLock.find_by_week(@year, @week) @absences = Absence.find_by_week(@year, @week, @user) @public_holidays = PublicHoliday.find_by_week(@year, @week) 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_backlog = 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_backlog_name @accounts = 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_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 auto_complete_for_work_description max = 16 works = Work.find(:all, :select => "description, count(*) as freq", :conditions => [ 'LOWER(description) LIKE ? AND backlog_id = ?', '%' + params[:description].downcase + '%', params[:backlog_id] ], :group => "description", :order => 'freq DESC, description ASC', :limit => max) if works.size < max works += Work.find(:all, :select => "description, count(*) as freq", :conditions => [ 'LOWER(description) LIKE ? AND backlog_id <> ?', '%' + params[:description].downcase + '%', params[:backlog_id] ], :group => "description", :order => 'freq DESC, description ASC', :limit => max - works.size) end works = works.map{|w| w.description} works.uniq! works = works[0..max-1] items = works.map{|w| %Q[