diff --git a/README.rdoc b/README.rdoc index 8d0e1d5d4..6bacf5903 100644 --- a/README.rdoc +++ b/README.rdoc @@ -31,6 +31,7 @@ The following configurations can be made on the plugin - Allow User filtering to My Issues - Public holidays can be configured - 'Approve time log' permission + - T&E Admin groups can be configured The Time & Expense sheets can be approved/rejected by supervisors after it is submitted by Project Members. Here is the workflow of Approval system.. @@ -72,9 +73,20 @@ If an apache passenger module is used then make sure the following settings are b) RailsAppSpawnerIdleTime 0 c) PassengerPreStart http://rails-app-url/ -Release Notes for 1.8.1 +Release Notes for 1.9 Features: - - Support for code hooks - - Filters will be remembered in list page. + - Permission changes + -- The project member with 'Edit time logs' can edit other member time/expense sheet with his permission. + - TE Admin users is introduced + - Empty time/expense sheet can be viewed. + - Sorting of timesheet rows. + - Allow entering time in different format. + - Non empty icon if detail time entry popup has no values. + - Comment box size increased. + - Name is shown for closed or inactive project, issue and activity. + + Bugs: + - Error message is shown if issue is blank when "Allow blank issue" is OFF. + - Closed date is considered instead of updated date for closed issues. -Please provide your review at http://www.redmine.org/plugins/wk-time +Please provide your rating at http://www.redmine.org/plugins/wk-time diff --git a/app/controllers/wkexpense_controller.rb b/app/controllers/wkexpense_controller.rb index bd7135328..f7517e62d 100644 --- a/app/controllers/wkexpense_controller.rb +++ b/app/controllers/wkexpense_controller.rb @@ -47,6 +47,10 @@ def showWorktimeHeader false end + def enterCustomFieldInRow(row) + false + end + def maxHour 0 end @@ -111,6 +115,9 @@ def deleteEntry end end + def textfield_size + 6 + end private def getSpecificField "amount" @@ -120,33 +127,42 @@ def getEntityNames ["#{Wkexpense.table_name}", "#{WkExpenseEntry.table_name}"] end - def findBySql(selectStr,sqlStr,wkSelectStr,wkSqlStr) - spField = getSpecificField() - result = WkExpenseEntry.find_by_sql("select count(*) as id from (" + selectStr + sqlStr + wkSqlStr + ") as v2") - @entry_count = result[0].id + def findBySql(selectStr,sqlStr,wkSelectStr,wkSqlStr, status, ids) + spField = getSpecificField() + dtRangeForUsrSqlStr = "(" + getAllWeekSql(@from, @to) + ") tmp1" + teSqlStr = "(" + wkSelectStr + " ,exp.currency" + sqlStr + " inner join wk_expense_entries exp on v1.id = exp.id " + wkSqlStr + ") tmp2" + query = "select tmp3.user_id, tmp3.spent_on, tmp3.#{spField}, tmp3.status, tmp3.status_updater, tmp3.created_on, tmp3.currency from (select tmp1.id as user_id, tmp1.created_on, tmp1.selected_date as spent_on, " + + "case when tmp2.#{spField} is null then 0 else tmp2.#{spField} end as #{spField}, " + + "case when tmp2.status is null then 'e' else tmp2.status end as status, tmp2.currency, tmp2.status_updater from " + query = query + dtRangeForUsrSqlStr + " left join " + teSqlStr + query = query + " on tmp1.id = tmp2.user_id and tmp1.selected_date = tmp2.spent_on where tmp1.id in (#{ids}) ) tmp3 " + query = query + " left outer join (select min( #{getDateSqlString('t.spent_on')} ) as min_spent_on, t.user_id as usrid from wk_expense_entries t, users u " + query = query + " where u.id = t.user_id and u.id in (#{ids}) group by t.user_id ) vw on vw.usrid = tmp3.user_id " + query = query + getWhereCond(status) + query = query + " order by tmp3.spent_on desc, tmp3.user_id " + result = WkExpenseEntry.find_by_sql("select count(*) as id from (" + query + ") as v2") + @entry_count = result[0].id setLimitAndOffset() rangeStr = formPaginationCondition() - - @entries = WkExpenseEntry.find_by_sql(wkSelectStr + " ,exp.currency" + sqlStr + - " inner join wk_expense_entries exp on v1.id = exp.id " + wkSqlStr + rangeStr) - + @entries = WkExpenseEntry.find_by_sql(query + rangeStr) @unit = @entries.blank? ? l('number.currency.format.unit') : @entries[0][:currency] - - #@total_hours = TimeEntry.visible.sum(:hours, :include => [:user], :conditions => cond.conditions).to_f - - result = WkExpenseEntry.find_by_sql("select sum(v2." + spField + ") as " + spField + " from (" + selectStr + sqlStr + wkSqlStr +") as v2") + result = WkExpenseEntry.find_by_sql("select sum(v2." + spField + ") as " + spField + " from (" + query + ") as v2") @total_hours = result[0].amount end + def getTEAllTimeRange(ids) + teQuery = "select #{getDateSqlString('t.spent_on')} as startday " + + "from wk_expense_entries t where user_id in (#{ids}) group by startday order by startday" + teResult = WkExpenseEntry.find_by_sql(teQuery) + end + def findWkTEByCond(cond) - #@wktimes = Wkexpense.find(:all, :conditions => cond) @wktimes = Wkexpense.where(cond) end def findEntriesByCond(cond) - #WkExpenseEntry.find(:all, :conditions => cond, :order => 'project_id, issue_id, activity_id, spent_on') - WkExpenseEntry.where(cond).order('project_id, issue_id, activity_id, spent_on') + WkExpenseEntry.joins(:project).joins(:activity).joins("LEFT OUTER JOIN issues ON issues.id = wk_expense_entries.issue_id").where(cond).order('projects.name, issues.subject, enumerations.name, wk_expense_entries.spent_on') end def setValueForSpField(teEntry,spValue,decimal_separator,entry) @@ -212,6 +228,7 @@ def validateEntry(stDate) def getTEName "expense" end + # Returns the ExpenseEntry scope for index and report actions def expense_entry_scope(options={}) scope = @query.results_scope(options) diff --git a/app/controllers/wktime_controller.rb b/app/controllers/wktime_controller.rb index aa50888df..b2337ae4f 100644 --- a/app/controllers/wktime_controller.rb +++ b/app/controllers/wktime_controller.rb @@ -32,55 +32,70 @@ def index end set_user_projects if (!@manage_view_spenttime_projects.blank? && @manage_view_spenttime_projects.size > 0) - @selected_project = getSelectedProject(@manage_view_spenttime_projects) - setMembers + @selected_project = getSelectedProject(@manage_view_spenttime_projects, false) end + setMembers ids = nil if user_id.blank? + #ids = is_member_of_any_project() ? User.current.id.to_s : '0' ids = User.current.id.to_s elsif user_id.to_i == 0 - @members.each_with_index do |users,i| - if i == 0 - ids = users[1].to_s - else - ids +=',' + users[1].to_s - end - end + unless @members.blank? + @members.each_with_index do |users,i| + if i == 0 + ids = users[1].to_s + else + ids +=',' + users[1].to_s + end + end + end ids = '0' if ids.nil? else - ids = user_id + ids = user_id end + + if @from.blank? && @to.blank? + getAllTimeRange(ids) + end + spField = getSpecificField() - entityNames = getEntityNames() - selectStr = "select v1.user_id, v1.startday as spent_on, v1." + spField - wkSelectStr = selectStr + ", w.status " + entityNames = getEntityNames() + teSelectStr = "select v1.user_id, v1.startday as spent_on, v1." + spField + wkSelectStr = teSelectStr + ", case when w.status is null then 'n' else w.status end as status " sqlStr = " from " sDay = getDateSqlString('t.spent_on') #Martin Dube contribution: 'start of the week' configuration if ActiveRecord::Base.connection.adapter_name == 'SQLServer' + wkSelectStr = wkSelectStr +", un.firstname + ' ' + un.lastname as status_updater " sqlStr += "(select ROW_NUMBER() OVER (ORDER BY " + sDay + " desc, user_id) AS rownum," + sDay + " as startday, " sqlStr += " t.user_id, sum(t." + spField + ") as " + spField + " ,max(t.id) as id" + " from " + entityNames[1] + " t, users u" + " where u.id = t.user_id and u.id in (#{ids})" sqlStr += " and t.spent_on between '#{@from}' and '#{@to}'" unless @from.blank? && @to.blank? sqlStr += " group by " + sDay + ", user_id ) as v1" else + if ActiveRecord::Base.connection.adapter_name == 'SQLite' + wkSelectStr = wkSelectStr +", un.firstname || ' ' || un.lastname as status_updater " + else + wkSelectStr = wkSelectStr +", concat(un.firstname,' ' ,un.lastname) as status_updater " + end sqlStr += "(select " + sDay + " as startday, " sqlStr += " t.user_id, sum(t." + spField + ") as " + spField + " ,max(t.id) as id" + " from " + entityNames[1] + " t, users u" + " where u.id = t.user_id and u.id in (#{ids})" sqlStr += " and t.spent_on between '#{@from}' and '#{@to}'" unless @from.blank? && @to.blank? sqlStr += " group by startday, user_id order by startday desc, user_id ) as v1" + end - wkSqlStr = " left outer join " + entityNames[0] + " w on v1.startday = w.begin_date and v1.user_id = w.user_id" + wkSqlStr = " left outer join " + entityNames[0] + " w on v1.startday = w.begin_date and v1.user_id = w.user_id left outer join users un on un.id = w.statusupdater_id" #status = params[:status] - if !status.blank? && status != 'all' - wkSqlStr += " WHERE w.status = '#{status}'" - if status == 'n' - wkSqlStr += " OR w.status IS NULL" - end - end - - findBySql(selectStr,sqlStr,wkSelectStr,wkSqlStr) + #if !status.blank? + # wkSqlStr += " WHERE w.status in ('#{status.join("','")}')" + # if status.include?('n') + # wkSqlStr += " OR w.status IS NULL" + # end + #end + + findBySql(teSelectStr,sqlStr,wkSelectStr,wkSqlStr, status, ids) respond_to do |format| format.html { render :layout => !request.xhr? @@ -95,6 +110,11 @@ def edit setup findWkTE(@startday) @editable = @wktime.nil? || @wktime.status == 'n' || @wktime.status == 'r' + hookPerm = call_hook(:controller_check_editable, {:editable => @editable, :user => @user}) + @editable = hookPerm.blank? ? @editable : hookPerm[0] + hookPerm = call_hook(:controller_check_locked, {:startdate => @startday}) + @locked = hookPerm.blank? ? false : hookPerm[0] + @editable = false if @locked set_edit_time_logs @entries = findEntries() set_project_issues(@entries) @@ -153,14 +173,25 @@ def update entrycount += 1 entrynilcount += 1 if (entry.hours).blank? allowSave = true - if (!entry.id.blank? && !entry.editable_by?(@user)) + if (!entry.id.blank? && !entry.editable_by?(User.current)) allowSave = false end if to_boolean(@edittimelogs) allowSave = true - end - errorMsg = updateEntry(entry) if allowSave - break unless errorMsg.blank? + end + if !((Setting.plugin_redmine_wktime['wktime_allow_blank_issue'].blank? || + Setting.plugin_redmine_wktime['wktime_allow_blank_issue'].to_i == 0) && + entry.issue.blank?) + if allowSave + errorMsg = updateEntry(entry) + else + errorMsg = l(:error_not_permitted_save) if !api_request? + end + break unless errorMsg.blank? + else + errorMsg = "#{l(:field_issue)} #{l('activerecord.errors.messages.blank')} " + break unless errorMsg.blank? + end end if !params[:wktime_submit].blank? && useApprovalSystem @wktime.submitted_on = Date.today @@ -199,18 +230,25 @@ def update end elsif !params[:wktime_unapprove].blank? && !@wktime.nil? && @wktime.status == 'a' && allowApprove errorMsg = updateStatus(:s) + elsif !params[:wktime_submit].blank? && !@wktime.nil? && ( @wktime.status == 'n' || @wktime.status == 'r') + #if TE sheet is read only mode with submit button + if !Setting.plugin_redmine_wktime['wktime_uuto_approve'].blank? && + Setting.plugin_redmine_wktime['wktime_uuto_approve'].to_i == 1 + errorMsg = updateStatus(:a) + else + errorMsg = updateStatus(:s) + end end end rescue Exception => e errorMsg = e.message end - if errorMsg.nil? #when the are entries or it is not a save action if !@entries.blank? || !params[:wktime_approve].blank? || (!params[:wktime_reject].blank? || !params[:hidden_wk_reject].blank?) || !params[:wktime_unsubmit].blank? || !params[:wktime_unapprove].blank? || - ((!params[:wktime_submit].blank? || !cvParams.blank?) && total > 0.0 && @wkvalidEntry) + ((!params[:wktime_submit].blank? || !cvParams.blank?) && total > 0.0) # && @wkvalidEntry respMsg = l(:notice_successful_update) else respMsg = l(:error_wktime_save_nothing) @@ -301,26 +339,41 @@ def destroy setup #cond = getCondition('spent_on', @user.id, @startday, @startday+6) #TimeEntry.delete_all(cond) - @entries = findEntries() - @entries.each do |entry| - entry.destroy() - end - cond = getCondition('begin_date', @user.id, @startday) - deleteWkEntity(cond) - respond_to do |format| - format.html { - flash[:notice] = l(:notice_successful_delete) - redirect_back_or_default :action => 'index', :tab => params[:tab] - } - format.api { - render_api_ok - } + hookPerm = call_hook(:controller_check_locked, {:startdate => @startday}) + locked = hookPerm.blank? ? false : hookPerm[0] + findWkTE(@startday) + if locked + flash[:error] = l(:error_time_entry_delete) + redirect_to :action => 'index' , :tab => params[:tab] + else + deletable = @wktime.nil? || @wktime.status == 'n' || @wktime.status == 'r' + if deletable + @entries = findEntries() + @entries.each do |entry| + entry.destroy() + end + cond = getCondition('begin_date', @user.id, @startday) + deleteWkEntity(cond) + end + respond_to do |format| + format.html { + flash[:notice] = l(:notice_successful_delete) + redirect_back_or_default :action => 'index', :tab => params[:tab] + } + format.api { + if deletable + render_api_ok + else + render_403 + end + } + end end end def new set_user_projects - @selected_project = getSelectedProject(@manage_projects) + @selected_project = getSelectedProject(@manage_projects, true) # get the startday for current week @startday = getStartDay(Date.today) render :action => 'new' @@ -353,7 +406,6 @@ def getissues end if Setting.plugin_redmine_wktime['wktime_closed_issue_ind'].to_i == 1 if !params[:tracker_id].blank? && params[:tracker_id] != ["0"] && params[:term].blank? - #issues = Issue.find_all_by_project_id(params[:project_id] || params[:project_ids] , #:conditions => ["#{Issue.table_name}.tracker_id in ( ?) #{issueAssignToUsrCond}", params[:tracker_id]] , :order => 'project_id') projIds = "#{(params[:project_id] || (!params[:project_ids].blank? ? params[:project_ids].join(",") : ''))}" projCond = !projIds.blank? ? "AND #{Issue.table_name}.project_id in (#{projIds})" : "" issues = Issue.where(["(#{Issue.table_name}.tracker_id in ( ?) #{issueAssignToUsrCond}) #{projCond}", params[:tracker_id]]).order('project_id') @@ -366,17 +418,15 @@ def getissues else cond = ["(LOWER(#{Issue.table_name}.subject) LIKE ? #{issueAssignToUsrCond} #{trackerIDCond}) #{projCond}", "%#{subjectPart.downcase}%"] end - #issues = Issue.find_all_by_project_id(params[:project_id] || params[:project_ids] || projectids, :conditions => cond , :order => 'project_id') issues = Issue.where(cond).order('project_id') end else if (!params[:issue_assign_user].blank? && params[:issue_assign_user].to_i == 1) projIds = "#{(params[:project_id] || (!params[:project_ids].blank? ? params[:project_ids].join(",") : '') || projectids)}" projCond = !projIds.blank? ? "AND #{Issue.table_name}.project_id in (#{projIds})" : "" - #issues = Issue.find_all_by_project_id(params[:project_id] || params[:project_ids]|| projectids,:conditions =>["(#{Issue.table_name}.assigned_to_id= ? OR #{Issue.table_name}.author_id= ?)#{trackerIDCond}", params[:user_id],params[:user_id]], :order => 'project_id') + issues = Issue.where(["((#{Issue.table_name}.assigned_to_id= ? OR #{Issue.table_name}.author_id= ?) #{trackerIDCond}) #{projCond}", params[:user_id], params[:user_id]]).order('project_id') else - #issues = Issue.find_all_by_project_id(params[:project_id] || params[:project_ids], :order => 'project_id') issues = Issue.where(:project_id => params[:project_id] || params[:project_ids]).order('project_id') end end @@ -385,23 +435,19 @@ def getissues projIds = "#{(params[:project_id] || (!params[:project_ids].blank? ? params[:project_ids].join(",") : '') || projectids)}" projCond = !projIds.blank? ? "AND #{Issue.table_name}.project_id in (#{projIds})" : "" if !params[:tracker_id].blank? && params[:tracker_id] != ["0"] && params[:term].blank? - cond = ["((#{IssueStatus.table_name}.is_closed = ? OR #{Issue.table_name}.updated_on >= ?) AND #{Issue.table_name}.tracker_id in ( ?) #{issueAssignToUsrCond}) #{projCond}", false, @startday,params[:tracker_id]] + cond = ["((#{IssueStatus.table_name}.is_closed = ? OR #{Issue.table_name}.closed_on >= ?) AND #{Issue.table_name}.tracker_id in ( ?) #{issueAssignToUsrCond}) #{projCond}", false, @startday,params[:tracker_id]] elsif !params[:term].blank? if subjectPart.present? if subjectPart.match(/^\d+$/) - cond = ["((LOWER(#{Issue.table_name}.subject) LIKE ? OR #{Issue.table_name}.id=?) AND #{IssueStatus.table_name}.is_closed = ? #{issueAssignToUsrCond} #{trackerIDCond}) #{projCond}", "%#{subjectPart.downcase}%","#{subjectPart.to_i}",false] + cond = ["((LOWER(#{Issue.table_name}.subject) LIKE ? OR #{Issue.table_name}.id=?) AND (#{IssueStatus.table_name}.is_closed = ? OR #{Issue.table_name}.closed_on >= ?) #{issueAssignToUsrCond} #{trackerIDCond}) #{projCond}", "%#{subjectPart.downcase}%","#{subjectPart.to_i}", false, @startday] else - cond = ["((LOWER(#{Issue.table_name}.subject) LIKE ? AND #{IssueStatus.table_name}.is_closed = ?) #{issueAssignToUsrCond} #{trackerIDCond}) #{projCond}", "%#{subjectPart.downcase}%",false] + cond = ["((LOWER(#{Issue.table_name}.subject) LIKE ? AND (#{IssueStatus.table_name}.is_closed = ? OR #{Issue.table_name}.closed_on >= ?)) #{issueAssignToUsrCond} #{trackerIDCond}) #{projCond}", "%#{subjectPart.downcase}%", false, @startday] end end else - cond =["((#{IssueStatus.table_name}.is_closed = ? OR #{Issue.table_name}.updated_on >= ?) #{issueAssignToUsrCond} #{trackerIDCond}) #{projCond}", false, @startday] + cond =["((#{IssueStatus.table_name}.is_closed = ? OR #{Issue.table_name}.closed_on >= ?) #{issueAssignToUsrCond} #{trackerIDCond}) #{projCond}", false, @startday] end - #issues= Issue.find_all_by_project_id(params[:project_id] || params[:project_ids] || projectids, - #:conditions => cond, - #:include => :status, :order => 'project_id') - issues = Issue.includes(:status).references(:status).where(cond).order('project_id') end #issues.compact! @@ -466,16 +512,18 @@ def getactivities def getusers project = Project.find(params[:project_id]) userStr = "" - userList = call_hook(:controller_project_member,{ :project_id => params[:project_id]}) + userList = call_hook(:controller_project_member, {:project_id => params[:project_id], :page => params[:page]}) if !userList.blank? projmembers = userList[0].blank? ? nil : userList[0] else - projmembers = project.members.order("#{User.table_name}.firstname ASC,#{User.table_name}.lastname ASC").distinct("#{User.table_name}.id") + projmembers = project.members.order("#{User.table_name}.firstname ASC,#{User.table_name}.lastname ASC") end - projmembers.each do |m| - userStr << m.user_id.to_s() + ',' + m.name + "\n" + if !projmembers.nil? + projmembers = projmembers.to_a.uniq + projmembers.each do |m| + userStr << m.user_id.to_s() + ',' + m.name + "\n" + end end - respond_to do |format| format.text { render :text => userStr } end @@ -535,6 +583,26 @@ def showWorktimeHeader Setting.plugin_redmine_wktime['wktime_work_time_header'].to_i == 1 end + def enterCommentInRow + !Setting.plugin_redmine_wktime['wktime_enter_comment_in_row'].blank? && + Setting.plugin_redmine_wktime['wktime_enter_comment_in_row'].to_i == 1 + end + + def enterCustomFieldInRow(row) + entry = nil + custom_field_values = entry.nil? ? @new_custom_field_values : entry.custom_field_values + cf_value = nil + if row.to_i == 1 + !Setting.plugin_redmine_wktime['wktime_enter_cf_in_row1'].blank? && + (cf_value = custom_field_values.detect { |cfv| + cfv.custom_field.id == Setting.plugin_redmine_wktime['wktime_enter_cf_in_row1'].to_i }) != nil + else + !Setting.plugin_redmine_wktime['wktime_enter_cf_in_row2'].blank? && + (cf_value = custom_field_values.detect { |cfv| + cfv.custom_field.id == Setting.plugin_redmine_wktime['wktime_enter_cf_in_row2'].to_i }) != nil + end + end + def maxHour Setting.plugin_redmine_wktime['wktime_restr_max_hour'].to_i == 1 ? (Setting.plugin_redmine_wktime['wktime_max_hour_day'].blank? ? 8 : Setting.plugin_redmine_wktime['wktime_max_hour_day']) : 0 @@ -549,7 +617,7 @@ def total_all(total) end def getStatus - status = getTimeEntryStatus(params[:startDate].to_date,User.current.id) + status = getTimeEntryStatus(params[:startDate].to_date,params[:user_id]) respond_to do |format| format.text { render :text => status } end @@ -592,18 +660,14 @@ def findTEProjects() def check_approvable_status te_projects=[] - ret = false + ret = false + if !@entries.blank? + @te_projects = @entries.collect{|entry| entry.project}.uniq + te_projects = @approvable_projects & @te_projects if !@te_projects.blank? + end hookPerm = call_hook(:controller_check_approvable, {:params => params}) if !hookPerm.blank? ret = hookPerm[0] - #if (approvable[0].to_s)=='true' - # ret = true - #end - else - if !@entries.blank? - @te_projects = @entries.collect{|entry| entry.project}.uniq - te_projects = @approvable_projects & @te_projects if !@te_projects.blank? - end end ret = ((ret || !te_projects.blank?) && (@user.id != User.current.id || (!Setting.plugin_redmine_wktime[:wktime_own_approval].blank? && Setting.plugin_redmine_wktime[:wktime_own_approval].to_i == 1 )))? true: false @@ -619,6 +683,21 @@ def testapi end end + def textfield_size + 4 + end + + def checkDDWidth + ret = true + project_dd_width = Setting.plugin_redmine_wktime['wktime_project_dd_width'].to_i + issue_dd_width = Setting.plugin_redmine_wktime['wktime_issue_dd_width'].to_i + actv_dd_width = Setting.plugin_redmine_wktime['wktime_actv_dd_width'].to_i + ddtotal = project_dd_width + issue_dd_width + actv_dd_width + if ddtotal > 50 + ret = false + end + ret + end private @@ -626,7 +705,7 @@ def check_permission ret = false setup set_user_projects - status = getTimeEntryStatus(@startday,@user_id) + status = getTimeEntryStatus(@startday, @user_id) approve_projects = @approvable_projects & @logtime_projects if (status != 'n' && (!approve_projects.blank? && approve_projects.size > 0)) #for approver @@ -643,16 +722,12 @@ def check_permission ret = (@user.id == User.current.id && @logtime_projects.size > 0) end end - editPermission = call_hook(:controller_check_permission,{:params => params}) - editPermission = editPermission.blank? ? '' : (editPermission.is_a?(Array) ? (editPermission[0].blank? ? '': editPermission[0]) : editPermission) + editPermission = call_hook(:controller_check_permission, {:params => params}) if !editPermission.blank? - ret = false - if editPermission - ret = true - end - end + ret = editPermission[0] || (@user.id == User.current.id && @logtime_projects.size > 0) + end return ret - end + end def getGrpMembers userList = [] @@ -775,7 +850,8 @@ def gatherEntries end #timeEntry.hours = hours[j].blank? ? nil : hours[j].to_f #to allow for internationalization on decimal separator - setValueForSpField(teEntry,hours[j],decimal_separator,entry) + #setValueForSpField(teEntry,hours[j],decimal_separator,entry) + teEntry.hours = hours[j].blank? ? nil : hours[j]#.to_f unless custom_fields.blank? teEntry.custom_field_values.each do |custom_value| @@ -942,7 +1018,11 @@ def user_allowed_to?(privilege, entity) def can_log_time?(project_id) ret = false set_loggable_projects - @logtime_projects.each do |lp| + loggable_projects = @logtime_projects + if !@manage_projects.blank? && @user != User.current + loggable_projects = @manage_projects & @logtime_projects + end + loggable_projects.each do |lp| if lp.id == project_id ret = true break @@ -954,9 +1034,9 @@ def can_log_time?(project_id) def check_editperm_redirect - hookPerm = call_hook(:controller_edit_timelog_permission) + hookPerm = call_hook(:controller_edit_timelog_permission, {:params => params}) if !hookPerm.blank? - allow = hookPerm[0] || check_editPermission + allow = hookPerm[0] || (check_editPermission && @user.id == User.current.id) else allow = check_editPermission end @@ -1121,6 +1201,7 @@ def retrieve_date_range def setMembers @groups = Group.sorted.all @members = Array.new + projMem = nil if !params[:tab].blank? && params[:tab] =='wkexpense' filter_type = session[:wkexpense][:filter_type] project_id = session[:wkexpense][:project_id] @@ -1133,21 +1214,24 @@ def setMembers hookProjMem = call_hook(:controller_project_member, { :project_id => project_id}) if !hookProjMem.blank? projMem = hookProjMem[0].blank? ? [] : hookProjMem[0] - else - projMem = @selected_project.members.order("#{User.table_name}.firstname ASC,#{User.table_name}.lastname ASC").distinct("#{User.table_name}.id") + else + projMem = @selected_project.members.order("#{User.table_name}.firstname ASC,#{User.table_name}.lastname ASC") if !@selected_project.blank? end - @members = projMem.collect{|m| [ m.name, m.user_id ] } + @members = projMem.collect{|m| [ m.name, m.user_id ] } if !projMem.blank? elsif filter_type == '2' userList = [] userList = getGrpMembers userList.each do |users| @members << [users.name,users.id.to_s()] end - else + else + projMem = @selected_project.members.order("#{User.table_name}.firstname ASC,#{User.table_name}.lastname ASC") if !@selected_project.blank? + @members = projMem.collect{|m| [ m.name, m.user_id ] } if !projMem.blank? if !hookMem.blank? @members = hookMem[0].blank? ? @members : hookMem[0] end end + @members = @members.uniq end def setup @@ -1189,8 +1273,13 @@ def set_managed_projects if !view_projects.blank? @manage_view_spenttime_projects = view_projects[0].blank? ? nil : view_projects[0] else - view_spenttime_projects ||= Project.where(Project.allowed_to_condition(User.current, :view_time_entries)).order('name') - @manage_view_spenttime_projects = @manage_projects & view_spenttime_projects + if isAccountUser + #@manage_view_spenttime_projects = Project.all + @manage_view_spenttime_projects = getAccountUserProjects + else + view_spenttime_projects ||= Project.where(Project.allowed_to_condition(User.current, :view_time_entries)).order('name') + @manage_view_spenttime_projects = @manage_projects & view_spenttime_projects + end end @manage_view_spenttime_projects = setTEProjects(@manage_view_spenttime_projects) @@ -1254,9 +1343,9 @@ def set_visible_issues(entry) end else if !Setting.plugin_redmine_wktime[getTFSettingName()].blank? && Setting.plugin_redmine_wktime[getTFSettingName()] != ["0"] && params[:tracker_ids].blank? - cond = ["((#{IssueStatus.table_name}.is_closed = ? OR #{Issue.table_name}.updated_on >= ?) AND #{Issue.table_name}.tracker_id in ( ?) #{issueAssignToUsrCond}) and #{Issue.table_name}.project_id in ( #{project_id} )",false, @startday,Setting.plugin_redmine_wktime[getTFSettingName()]] + cond = ["((#{IssueStatus.table_name}.is_closed = ? OR #{Issue.table_name}.closed_on >= ?) AND #{Issue.table_name}.tracker_id in ( ?) #{issueAssignToUsrCond}) and #{Issue.table_name}.project_id in ( #{project_id} )",false, @startday,Setting.plugin_redmine_wktime[getTFSettingName()]] else - cond =["((#{IssueStatus.table_name}.is_closed = ? OR #{Issue.table_name}.updated_on >= ?) #{issueAssignToUsrCond} #{trackerids}) and #{Issue.table_name}.project_id in ( #{project_id})",false, @startday] + cond =["((#{IssueStatus.table_name}.is_closed = ? OR #{Issue.table_name}.closed_on >= ?) #{issueAssignToUsrCond} #{trackerids}) and #{Issue.table_name}.project_id in ( #{project_id})",false, @startday] end #allIssues = Issue.find_all_by_project_id(project_id, :conditions => cond, :include => :status) allIssues = Issue.includes(:status).references(:status).where(cond) @@ -1277,20 +1366,94 @@ def getEntityNames ["#{Wktime.table_name}", "#{TimeEntry.table_name}"] end - def findBySql(selectStr,sqlStr,wkSelectStr,wkSqlStr) - spField = getSpecificField() - result = TimeEntry.find_by_sql("select count(*) as id from (" + selectStr + sqlStr + wkSqlStr + ") as v2") + def findBySql(selectStr,sqlStr,wkSelectStr,wkSqlStr, status, ids) + spField = getSpecificField() + dtRangeForUsrSqlStr = "(" + getAllWeekSql(@from, @to) + ") tmp1" + teSqlStr = "(" + wkSelectStr + sqlStr + wkSqlStr + ") tmp2" + + query = "select tmp3.user_id, tmp3.spent_on, tmp3.#{spField}, tmp3.status, tmp3.status_updater, tmp3.created_on from (select tmp1.id as user_id, tmp1.created_on, tmp1.selected_date as spent_on, " + + "case when tmp2.#{spField} is null then 0 else tmp2.#{spField} end as #{spField}, " + + "case when tmp2.status is null then 'e' else tmp2.status end as status, tmp2.status_updater from " + query = query + dtRangeForUsrSqlStr + " left join " + teSqlStr + query = query + " on tmp1.id = tmp2.user_id and tmp1.selected_date = tmp2.spent_on where tmp1.id in (#{ids}) ) tmp3 " + query = query + " left outer join (select min( #{getDateSqlString('t.spent_on')} ) as min_spent_on, t.user_id as usrid from time_entries t, users u " + query = query + " where u.id = t.user_id and u.id in (#{ids}) group by t.user_id ) vw on vw.usrid = tmp3.user_id " + query = query + getWhereCond(status) + query = query + " order by tmp3.spent_on desc, tmp3.user_id " + + result = TimeEntry.find_by_sql("select count(*) as id from (" + query + ") as v2") @entry_count = result[0].id setLimitAndOffset() - rangeStr = formPaginationCondition() - @entries = TimeEntry.find_by_sql(wkSelectStr + sqlStr + wkSqlStr + rangeStr) - @unit = nil - #@total_hours = TimeEntry.visible.sum(:hours, :include => [:user], :conditions => cond.conditions).to_f + rangeStr = formPaginationCondition() - result = TimeEntry.find_by_sql("select sum(v2." + spField + ") as " + spField + " from (" + selectStr + sqlStr + wkSqlStr + ") as v2") + @entries = TimeEntry.find_by_sql(query + rangeStr) + @unit = nil + result = TimeEntry.find_by_sql("select sum(v2." + spField + ") as " + spField + " from (" + query + ") as v2") @total_hours = result[0].hours end + def getWhereCond(status) + current_date = getEndDay(Date.today) + query = "WHERE ((tmp3.spent_on between " + query = query + "case when vw.min_spent_on is null then #{getDateSqlString('date(tmp3.created_on)')} else vw.min_spent_on end " + query = query + "and '#{current_date}') OR " + query = query + "((tmp3.spent_on < case when vw.min_spent_on is null then #{getDateSqlString('date(tmp3.created_on)')} else vw.min_spent_on end " + query = query + "and tmp3.status <> 'e') " + query = query + "OR (tmp3.spent_on > '#{current_date}' and tmp3.status <> 'e'))) " + if !status.blank? + query += " and tmp3.status in ('#{status.join("','")}') " + end + query + end + + def getAllWeekSql(from, to) + #to = to.blank? || to > Date.today ? getEndDay(Date.today) : to + entityNames = getEntityNames() + noOfDays = 't4.i*7*10000 + t3.i*7*1000 + t2.i*7*100 + t1.i*7*10 + t0.i*7' + sqlStr = "select u.id, u.created_on, v.selected_date from " + + "(select " + getAddDateStr(from, noOfDays) + " selected_date from " + + "(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0, " + + "(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1, " + + "(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2, " + + "(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3, " + + "(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v, " + + "(select distinct u.id, u.created_on from users u) u " + + "where selected_date between '#{from}' and '#{to}'" + end + + def getTEAllTimeRange(ids) + teQuery = "select #{getDateSqlString('t.spent_on')} as startday " + + "from time_entries t where user_id in (#{ids}) group by startday order by startday" + teResult = TimeEntry.find_by_sql(teQuery) + end + + def getUserAllTimeRange(ids) + usrQuery = "select date(min(created_on)) as startday from users where id in (#{ids})" + usrResult = User.find_by_sql(usrQuery) + end + + def getAllTimeRange(ids) + teResult = getTEAllTimeRange(ids) + usrResult = getUserAllTimeRange(ids) + currentWeekEndDay = getEndDay(Date.today) + @from = getStartDay(Date.today) + @to = currentWeekEndDay + if !teResult.blank? && teResult.size > 0 + @from = teResult[0].startday + @to = teResult[teResult.size - 1].startday + 6 + if currentWeekEndDay > @to + @to = currentWeekEndDay + end + end + if !usrResult.blank? && usrResult.size > 0 + stDate = usrResult[0].startday + stDate = getStartDay(stDate) if !stDate.blank? + if (!stDate.blank? && stDate < @from) + @from = stDate + end + end + end + def findWkTEByCond(cond) #@wktimes = Wktime.find(:all, :conditions => cond) @wktimes = Wktime.where(cond) @@ -1298,7 +1461,8 @@ def findWkTEByCond(cond) def findEntriesByCond(cond) #TimeEntry.find(:all, :conditions => cond, :order => 'project_id, issue_id, activity_id, spent_on') - TimeEntry.where(cond).order('project_id, issue_id, activity_id, spent_on') + #TimeEntry.where(cond).order('project_id, issue_id, activity_id, spent_on') + TimeEntry.joins(:project).joins(:activity).joins("LEFT OUTER JOIN issues ON issues.id = time_entries.issue_id").where(cond).order('projects.name, issues.subject, enumerations.name, time_entries.spent_on') end def setValueForSpField(teEntry,spValue,decimal_separator,entry) @@ -1407,15 +1571,15 @@ def getTEName "time" end - def getSelectedProject(projList) + def getSelectedProject(projList, setFirstProj) #selected_proj_id = params[:project_id] if !params[:tab].blank? && params[:tab] =='wkexpense' selected_proj_id = session[:wkexpense][:project_id].blank? ? params[:project_id] : session[:wkexpense][:project_id] elsif !session[:wktimes].blank? selected_proj_id = session[:wktimes][:project_id] end - if !selected_proj_id.blank? - sel_project = projList.select{ |proj| proj.id == selected_proj_id.to_i } + if !selected_proj_id.blank? && !setFirstProj #( !isAccountUser || !projList.blank? ) + sel_project = projList.select{ |proj| proj.id == selected_proj_id.to_i } if !projList.blank? selected_project ||= sel_project[0] if !sel_project.blank? else selected_project ||= projList[0] if !projList.blank? @@ -1466,6 +1630,12 @@ def set_edit_time_logs @edittimelogs = editPermission.blank? ? '' : editPermission[0].to_s end + def is_member_of_any_project + cond = "user_id = " + User.current.id.to_s + projMember = Member.where(cond) + ret = projMember.size > 0 + end + def set_filter_session if params[:searchlist].blank? && (session[:wktimes].nil? || session[:wkexpense].nil?) @@ -1473,7 +1643,7 @@ def set_filter_session session[:wktimes] = {:period_type => params[:period_type], :period => params[:period],:from => params[:from],:to => params[:to],:project_id => params[:project_id], :filter_type => params[:filter_type],:user_id => params[:user_id],:status => params[:status],:group_id => params[:group_id] } session[:wkexpense] = {:period_type => params[:period_type], :period => params[:period],:from => params[:from],:to => params[:to],:project_id => params[:project_id], :filter_type => params[:filter_type],:user_id => params[:user_id],:status => params[:status],:group_id => params[:group_id] } #session[:wkexpense] = session[:wktimes] - elsif params[:searchlist] =='wktime' + elsif params[:searchlist] =='wktime' || api_request? session[:wktimes][:period_type] = params[:period_type] session[:wktimes][:period] = params[:period] session[:wktimes][:from] = params[:from] @@ -1483,7 +1653,7 @@ def set_filter_session session[:wktimes][:user_id] = params[:user_id] session[:wktimes][:status] = params[:status] session[:wktimes][:group_id] = params[:group_id] - elsif params[:searchlist] =='wkexpense' + elsif params[:searchlist] =='wkexpense' || api_request? session[:wkexpense][:period_type] = params[:period_type] session[:wkexpense][:period] = params[:period] session[:wkexpense][:from] = params[:from] @@ -1494,5 +1664,5 @@ def set_filter_session session[:wkexpense][:status] = params[:status] session[:wkexpense][:group_id] = params[:group_id] end - end + end end \ No newline at end of file diff --git a/app/helpers/wktime_helper.rb b/app/helpers/wktime_helper.rb index cf883fcce..09833fb2a 100644 --- a/app/helpers/wktime_helper.rb +++ b/app/helpers/wktime_helper.rb @@ -15,12 +15,12 @@ def options_for_period_select(value) end def options_wk_status_select(value) - options_for_select([[l(:label_all), 'all'], + options_for_select([[l(:wk_status_empty), 'e'], [l(:wk_status_new), 'n'], + [l(:wk_status_rejected), 'r'], [l(:wk_status_submitted), 's'], - [l(:wk_status_approved), 'a'], - [l(:wk_status_rejected), 'r']], - value.blank? ? 'all' : value) + [l(:wk_status_approved), 'a']], + value.blank? ? ['e','n','r','s','a'] : value) end def statusString(status) @@ -31,7 +31,9 @@ def statusString(status) when 'r' statusStr = l(:wk_status_rejected) when 's' - statusStr = l(:wk_status_submitted) + statusStr = l(:wk_status_submitted) + when 'e' + statusStr = l(:wk_status_empty) else statusStr = l(:wk_status_new) end @@ -46,10 +48,12 @@ def options_for_wktime_project(projects, needBlankRow=false) end #Project.project_tree(projects) do |proj_name, level| - project_tree(projects) do |proj, level| - indent_level = (level > 0 ? (' ' * 2 * level + '» ').html_safe : '') - sel_project = projects.select{ |p| p.id == proj.id } - projArr << [ (indent_level + sel_project[0].name), sel_project[0].id ] + if !projects.blank? + project_tree(projects) do |proj, level| + indent_level = (level > 0 ? (' ' * 2 * level + '» ').html_safe : '') + sel_project = projects.select{ |p| p.id == proj.id } + projArr << [ (indent_level + sel_project[0].name), sel_project[0].id ] + end end projArr end @@ -551,9 +555,18 @@ def set_cf_value(col_values, custom_field_values, setting_name) end def getTimeEntryStatus(spent_on,user_id) - #result = Wktime.find(:all, :conditions => [ 'begin_date = ? AND user_id = ?', getStartDay(spent_on), user_id]) - result = Wktime.where(['begin_date = ? AND user_id = ?', getStartDay(spent_on), user_id]) - return result[0].blank? ? 'n' : result[0].status + #result = Wktime.find(:all, :conditions => [ 'begin_date = ? AND user_id = ?', getStartDay(spent_on), user_id]) + start_day = getStartDay(spent_on) + locked = call_hook(:controller_check_locked,{ :startdate => start_day}) + locked = locked.blank? ? '' : (locked.is_a?(Array) ? (locked[0].blank? ? '': locked[0].to_s) : locked.to_s) + locked = ( !locked.blank? && to_boolean(locked)) + if locked + result = 'l' + else + result = Wktime.where(['begin_date = ? AND user_id = ?', start_day, user_id]) + result = result[0].blank? ? 'n' : result[0].status + end + return result end def time_expense_tabs @@ -706,9 +719,9 @@ def checkViewPermission viewProjects = Project.where(Project.allowed_to_condition(User.current, :view_time_entries )) loggableProjects ||= Project.where(Project.allowed_to_condition(User.current, :log_time)) viewMenu = call_hook(:view_wktime_menu) - viewMenu = viewMenu.blank? ? '' : (viewMenu.is_a?(Array) ? (viewMenu[0].blank? ? '': viewMenu[0]) : viewMenu) - @manger_user = ( !viewMenu.blank? && viewMenu) - ret = (!viewProjects.blank? && viewProjects.size > 0) || (!loggableProjects.blank? && loggableProjects.size > 0) || @manger_user + viewMenu = viewMenu.blank? ? '' : (viewMenu.is_a?(Array) ? (viewMenu[0].blank? ? '': viewMenu[0].to_s) : viewMenu.to_s) + #@manger_user = (!viewMenu.blank? && to_boolean(viewMenu)) + ret = (!viewProjects.blank? && viewProjects.size > 0) || (!loggableProjects.blank? && loggableProjects.size > 0) || isAccountUser || (!viewMenu.blank? && to_boolean(viewMenu)) end ret end @@ -720,4 +733,64 @@ def is_number(val) def to_boolean(str) str == 'true' end + + def getStatus_Project_Issue(issue_id,project_id) + if !issue_id.blank? + cond = getIssueSqlString(issue_id) + end + if !project_id.blank? + cond = getProjectSqlString(project_id) + end + sDay = getDateSqlString('t.spent_on') + time_sqlStr = " SELECT t.* FROM time_entries t inner join wktimes w on w.begin_date = #{ sDay} and w.user_id =t.user_id #{cond}" + time_entry = TimeEntry.find_by_sql(time_sqlStr) + expense_sqlStr = " SELECT t.* FROM wk_expense_entries t inner join wkexpenses w on w.begin_date = #{ sDay} and w.user_id =t.user_id #{cond}" + expense_entry = WkExpenseEntry.find_by_sql(expense_sqlStr) + ret = (!time_entry.blank? && time_entry.size > 0) || (!expense_entry.blank? && expense_entry.size > 0) + end + + def getIssueSqlString(issue_id) + " where t.issue_id = #{issue_id} and (w.status ='s' OR w.status ='a')" + end + + def getProjectSqlString(project_id) + " where t.project_id = #{project_id} and (w.status ='s' OR w.status ='a')" + end + + def isAccountUser + group = nil + isAccountUser = false + groupusers = Array.new + accountGrpIds = Setting.plugin_redmine_wktime['wktime_account_groups'] if !Setting.plugin_redmine_wktime['wktime_account_groups'].blank? + if !accountGrpIds.blank? + accountGrpIds = accountGrpIds.collect{|i| i.to_i} + end + + if !accountGrpIds.blank? + accountGrpIds.each do |group_id| + scope = User.in_group(group_id) + groupusers << scope.all + end + end + grpUserIds = Array.new + grpUserIds = groupusers[0].collect{|user| user.id}.uniq if !groupusers.blank? && !groupusers[0].blank? + isAccountUser = grpUserIds.include?(User.current.id) + end + + def getAccountUserProjects + Project.where(:status => "#{Project::STATUS_ACTIVE}").order('name') + end + + def getAddDateStr(dtfield,noOfDays) + if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' + dateSqlStr = "date('#{dtfield}') + " + noOfDays.to_s + elsif ActiveRecord::Base.connection.adapter_name == 'SQLite' + dateSqlStr = "date('#{dtfield}' , '+' || " + noOfDays.to_s + " || ' days')" + elsif ActiveRecord::Base.connection.adapter_name == 'SQLServer' + dateSqlStr = "DateAdd(d, " + noOfDays.to_s + ",'#{dtfield}')" + else + dateSqlStr = "adddate('#{dtfield}', " + noOfDays.to_s + ")" + end + dateSqlStr + end end \ No newline at end of file diff --git a/app/views/settings/_tab_approval.html.erb b/app/views/settings/_tab_approval.html.erb index 8fc3e5d1d..d4e141451 100644 --- a/app/views/settings/_tab_approval.html.erb +++ b/app/views/settings/_tab_approval.html.erb @@ -15,7 +15,7 @@

<%= text_area_tag 'settings[wktime_submission_ack]', @settings['wktime_submission_ack']%>

- <%= l(:label_wk_warning_nonsub_notification) %> + <%= l(:label_redmine_restart_warning) %>

<%= check_box_tag('settings[wktime_nonsub_mail_notification]', 1, @settings['wktime_nonsub_mail_notification'].to_i == 1) %> diff --git a/app/views/settings/_tab_expense.html.erb b/app/views/settings/_tab_expense.html.erb index 1ddc678c2..0e655ab2d 100644 --- a/app/views/settings/_tab_expense.html.erb +++ b/app/views/settings/_tab_expense.html.erb @@ -1,11 +1,12 @@

<%= l(:label_wkexpense) %> <% + trackers = Array.new tracker = Tracker.order('name') unless tracker.blank? trackers = tracker.collect {|t| [t.name, t.id] } - trackers.unshift(["",0]) end + trackers.unshift(["",0]) %>

diff --git a/app/views/settings/_tab_general.html.erb b/app/views/settings/_tab_general.html.erb index 030c00374..2ba6ddcea 100644 --- a/app/views/settings/_tab_general.html.erb +++ b/app/views/settings/_tab_general.html.erb @@ -27,5 +27,18 @@

<%= check_box_tag('settings[wktime_use_detail_popup]', 1, @settings['wktime_use_detail_popup'].to_i == 1) %>

+ <% + accountGroups = Array.new + accGroup = Group.order('lastname') + unless accGroup.blank? + accountGroups = accGroup.collect {|t| [t.lastname, t.id] } + end + accountGroups.unshift(["",0]) + %> +

+ + <%= select_tag('settings[wktime_account_groups]', + options_for_select(accountGroups, :selected => @settings['wktime_account_groups'].blank? ? 0 : @settings['wktime_account_groups']), :multiple=> true)%> +

\ No newline at end of file diff --git a/app/views/settings/_tab_time.html.erb b/app/views/settings/_tab_time.html.erb index e6df462ea..5582b3ddb 100644 --- a/app/views/settings/_tab_time.html.erb +++ b/app/views/settings/_tab_time.html.erb @@ -31,11 +31,12 @@

<% end %> <% + trackers = Array.new tracker = Tracker.order('name') unless tracker.blank? trackers = tracker.collect {|t| [t.name, t.id] } - trackers.unshift(["",0]) end + trackers.unshift(["",0]) %>

diff --git a/app/views/wkexpense/_wkexpense_cf_in_row.erb b/app/views/wkexpense/_wkexpense_cf_in_row.erb index ec4211b7f..e69de29bb 100644 --- a/app/views/wkexpense/_wkexpense_cf_in_row.erb +++ b/app/views/wkexpense/_wkexpense_cf_in_row.erb @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/app/views/wkexpense/_wkexpense_cf_in_row_header.html.erb b/app/views/wkexpense/_wkexpense_cf_in_row_header.html.erb index b1905c691..e69de29bb 100644 --- a/app/views/wkexpense/_wkexpense_cf_in_row_header.html.erb +++ b/app/views/wkexpense/_wkexpense_cf_in_row_header.html.erb @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/app/views/wktime/_edit_header.html.erb b/app/views/wktime/_edit_header.html.erb index 8a870a303..385f4c535 100644 --- a/app/views/wktime/_edit_header.html.erb +++ b/app/views/wktime/_edit_header.html.erb @@ -9,7 +9,7 @@ - diff --git a/app/views/wktime/_edit_hours.html.erb b/app/views/wktime/_edit_hours.html.erb index 096af8910..ecf616dba 100644 --- a/app/views/wktime/_edit_hours.html.erb +++ b/app/views/wktime/_edit_hours.html.erb @@ -6,7 +6,7 @@ if @editable #hookCellEditPerm = call_hook(:view_cell_edit, :entry => entry) if @edittimelogs.blank? - disable = !@prev_template && !entry.nil? && !entry.editable_by?(@user) + disable = !@prev_template && !entry.nil? && !entry.editable_by?(User.current) else if (@edittimelogs == 'true') disable = !@prev_template && !entry.nil? && !(to_boolean(@edittimelogs)) @@ -14,7 +14,7 @@ if (!@manage_projects.blank? && @manage_projects.size > 0 && User.current.id != @user.id) disable = !@prev_template && !entry.nil? && !(to_boolean(@edittimelogs)) else - disable = !@prev_template && !entry.nil? && !entry.editable_by?(@user) + disable = !@prev_template && !entry.nil? && !entry.editable_by?(User.current) end end end @@ -22,7 +22,8 @@ %> <%#if this is from a previous template, don't print the hours%> - - - - - + + <% if controller.enterCommentInRow %> + + <% end %> + <% if !controller.getUnitLabel.blank? %> + + <% end %> + <% if controller.getUnitLabel.blank? %> + <% if controller.enterCustomFieldInRow(1) %> + + <% end %> + <% if controller.enterCustomFieldInRow(2) %> + + <% end %> + <% end %> <% thours.each_with_index do |th,i| %> <% end %> @@ -94,34 +104,34 @@ currencySym = "" <% end %>
<%=l(:field_user)%><%=h @user.login %> + <%=h @user.name %> <%=h hidden_field_tag('user_id', @user.id) %> - <%=h text_field_tag('hours' + @row.to_s() +'[]', entry.nil? || @prev_template ? '' : ("%.2f" % entry.hours) ,:size => 7, + + <%=h text_field_tag('hours' + @row.to_s() +'[]', entry.nil? || @prev_template ? '' : ("%.2f" % entry.hours) ,:size => "#{controller.textfield_size}", :disabled => disable, :onchange => "validateTotal(this, #{@wday_index},'#{controller.maxHour}');") %> @@ -65,8 +66,20 @@ <% if show_custfield_img %> - <% image_tg = image_tag('text_list_bullets.png', :id => 'custfield_img' + @row.to_s() +'_', :name => 'custfield_img' + @row.to_s() +'[]', - :title => "#{entry.nil? || @prev_template || cvs.blank? ? l(:label_custom_field_plural) : cvs.join(',')}") %> + <% imgname ="" %> + <% if !cvs.blank? || !comment.blank? %> + <% imgname = "withcommant.png" %> + <% else %> + <% imgname = "withoutcommant.png" %> + <% end %> + <% if !@new_custom_field_values.blank? || ( Setting.plugin_redmine_wktime['wktime_enter_comment_in_row'].blank? || + Setting.plugin_redmine_wktime['wktime_enter_comment_in_row'].to_i == 0) %> + <% image_tg = image_tag("#{imgname}", :id => 'custfield_img' + @row.to_s() +'_', :name => 'custfield_img' + @row.to_s() +'[]', + :plugin => "redmine_wktime",:title => "#{entry.nil? || @prev_template || cvs.blank? ? '' : cvs.join(',')}") %> + <% else %> + <%= image_tg ="" %> + <% end %> + <% if disable %> <%= image_tg %> <% else %> diff --git a/app/views/wktime/_edit_issues.html.erb b/app/views/wktime/_edit_issues.html.erb index ab81bd874..1db7865ad 100644 --- a/app/views/wktime/_edit_issues.html.erb +++ b/app/views/wktime/_edit_issues.html.erb @@ -73,11 +73,21 @@ currencySym = ""
<%= currencySym %> ><%= ("%.2f" % th) %>
- -<% if @wktime.nil? || @wktime.status == 'n' || @wktime.status == 'r' %> - <%= submit_tag l(:button_save), :id => 'wktime_save', :name => 'wktime_save', :disabled => !(@row > 0)%> - <%= submit_tag l(:button_save_continue), :id => 'wktime_save_continue', :name => 'wktime_save_continue' , :disabled => !(@row > 0)%> - <% if !Setting.plugin_redmine_wktime[:wktime_use_approval_system].blank? && - Setting.plugin_redmine_wktime[:wktime_use_approval_system].to_i == 1 %> - <%= submit_tag l(:button_submit),:id => 'wktime_submit', :name => 'wktime_submit', :onclick => "return validateMinhour('#{controller.minHour}','#{getNonWorkingDayColumn(params[:startday])}');" , :disabled => !(@row > 0)%> +<% if !@locked %> + <% if @wktime.nil? || @wktime.status == 'n' || @wktime.status == 'r' %> + <%= submit_tag l(:button_save), :id => 'wktime_save', :name => 'wktime_save', :disabled => !(@row > 0)%> + <%= submit_tag l(:button_save_continue), :id => 'wktime_save_continue', :name => 'wktime_save_continue' , :disabled => !(@row > 0)%> + <% if !Setting.plugin_redmine_wktime[:wktime_use_approval_system].blank? && + Setting.plugin_redmine_wktime[:wktime_use_approval_system].to_i == 1 %> + <%= submit_tag l(:button_submit),:id => 'wktime_submit', :name => 'wktime_submit', :onclick => "return validateMinhour('#{controller.minHour}','#{getNonWorkingDayColumn(params[:startday])}');" , :disabled => !(@row > 0)%> + <% end %> <% end %> -<% end %> -<% if !Setting.plugin_redmine_wktime[:wktime_use_approval_system].blank? && - Setting.plugin_redmine_wktime[:wktime_use_approval_system].to_i == 1 %> - <% if !@wktime.nil? && @wktime.status == 's' %> - <%= submit_tag l(:button_wk_unsubmit), :name => 'wktime_unsubmit', :disabled => !(@row > 0)%> + <% if !Setting.plugin_redmine_wktime[:wktime_use_approval_system].blank? && + Setting.plugin_redmine_wktime[:wktime_use_approval_system].to_i == 1 %> + <% if !@wktime.nil? && @wktime.status == 's' %> + <%= submit_tag l(:button_wk_unsubmit), :name => 'wktime_unsubmit', :disabled => !(@row > 0)%> <% if controller.check_approvable_status() %> - <%= submit_tag l(:button_wk_approve), :name => 'wktime_approve', :disabled => !(@row > 0)%> - <%=h hidden_field_tag('wktime_notes', "") %> - <% # the jquery dialog box doesn't port the reject button value%> - <%=h hidden_field_tag('hidden_wk_reject', "") %> - <%= submit_tag l(:button_wk_reject), :name => 'wktime_reject', :disabled => !(@row > 0), - :onclick => "return showNotes();" %> - <% end %> - <% elsif !@wktime.nil? && @wktime.status == 'a' %> - <% if controller.check_approvable_status() %> - <%= submit_tag l(:button_wk_unapprove), :id => 'wktime_unapprove', :name => 'wktime_unapprove'%> + <%= submit_tag l(:button_wk_approve), :name => 'wktime_approve', :disabled => !(@row > 0)%> + <%=h hidden_field_tag('wktime_notes', "") %> + <% # the jquery dialog box doesn't port the reject button value%> + <%=h hidden_field_tag('hidden_wk_reject', "") %> + <%= submit_tag l(:button_wk_reject), :name => 'wktime_reject', :disabled => !(@row > 0), + :onclick => "return showNotes();" %> + <% end %> + <% elsif !@wktime.nil? && @wktime.status == 'a' %> + <% if controller.check_approvable_status() %> + <%= submit_tag l(:button_wk_unapprove), :id => 'wktime_unapprove', :name => 'wktime_unapprove'%> + <% end %> <% end %> <% end %> <% end %> -

<% if @editable %> diff --git a/app/views/wktime/_edit_issues2.html.erb b/app/views/wktime/_edit_issues2.html.erb index 4ff718a89..ab62ed444 100644 --- a/app/views/wktime/_edit_issues2.html.erb +++ b/app/views/wktime/_edit_issues2.html.erb @@ -10,17 +10,22 @@ if params[:enter_issue_id].blank? project = projects.detect {|p| p[1].to_i == entry.project_id} unless entry.nil? #check if the project, which was previously reported time, is still visible #if it is not visible, just show the id alone - projects.unshift( [ entry.project_id, entry.project_id ] ) if !entry.nil? && project.blank? + projects.unshift( [ entry.project.name, entry.project_id ] ) if !entry.nil? && project.blank? %> - + + <% project_name = entry.nil? ? (@logtime_projects.blank? ? 0 : @logtime_projects[0].id) : entry.project.name %> <% if @editable %> <%=h select_tag(isTemplate ? '__template__time_entry[][project_id]' : 'time_entry[][project_id]', options_for_select(projects, :selected => project_id), :onchange => "projectChanged(this,#{@row.to_s()});", :style=> "width:#{Setting.plugin_redmine_wktime['wktime_project_dd_width']}px" ) %> <% else %> <% if project.blank? %> - <%= project_id %> + <% if entry.nil? %> + <%= '' %> + <% else %> + <%= project_name %> + <% end %> <% else %> <%= project[0] %> <% end %> @@ -47,7 +52,7 @@ if params[:enter_issue_id].blank? if !curr_issue_found if !entry.nil? if !entry.issue_id.nil? - issues.unshift([ entry.issue_id, entry.issue_id ]) + issues.unshift([ entry.issue.tracker.to_s() + " #" + entry.issue.id.to_s() + ": " + entry.issue.subject, entry.issue_id ]) else if Setting.plugin_redmine_wktime['wktime_allow_blank_issue'].blank? || Setting.plugin_redmine_wktime['wktime_allow_blank_issue'].to_i == 0 @@ -60,23 +65,24 @@ if params[:enter_issue_id].blank? %> - + <% if @editable %> <%=h select_tag(isTemplate ? '__template__time_entry[][issue_id]' : 'time_entry[][issue_id]', options_for_select(issues, :selected => entry.nil? ? 0 : entry.issue_id, :required => true), :style=> "width:#{Setting.plugin_redmine_wktime['wktime_issue_dd_width']}px" ) %> <% else %> - <%= entry.issue.subject if !entry.nil? && !entry.issue.nil? %> + <%= entry.issue.tracker.to_s() + " #" + entry.issue.id.to_s() + ": " + entry.issue.subject if !entry.nil? && !entry.issue.nil? %> <% end %> <% else %> - + <%=h hidden_field_tag(isTemplate ? '__template__time_entry[][project_id]' : 'time_entry[][project_id]', - entry.nil? ? '' : entry.project_id.to_s ) %> + (entry.nil? ? '' : entry.project_id.to_s) ) %> - + <%=h text_field_tag(isTemplate ? '__template__time_entry[][issue_id]' : 'time_entry[][issue_id]', - entry.nil? ? '' : entry.issue_id, :onkeypress => "issueAutocomplete(this,#{@row.to_s()});") %> + entry.nil? ? '' : entry.issue_id, :onkeypress => "issueAutocomplete(this,#{@row.to_s()});", + :style => "width:#{Setting.plugin_redmine_wktime['wktime_issue_dd_width']}px" ) %> <% end %> @@ -93,10 +99,10 @@ if params[:enter_issue_id].blank? #if it is not visible, just show the id alone activities = projActList.collect {|a| [a.name, a.id]} - activities.unshift( [ entry.activity_id, entry.activity_id ] )if !entry.nil? && activity.blank? + activities.unshift( [ entry.activity.name, entry.activity_id ] )if !entry.nil? && activity.blank? end %> - + <% if @editable %> <%=h select_tag(isTemplate ? '__template__time_entry[][activity_id]' : 'time_entry[][activity_id]', activities.blank? ? nil : options_for_select(activities, :selected => entry.nil? ? 0 : entry.activity_id), @@ -110,23 +116,21 @@ if params[:enter_issue_id].blank? Setting.plugin_redmine_wktime['wktime_enter_comment_in_row'].to_i == 1 %> <% if @editable %> - <%=h text_field_tag(isTemplate ? '__template__time_entry[][comments]' : 'time_entry[][comments]', - entry.nil? ? '' : entry.comments)%> + + <%=h text_field_tag(isTemplate ? '__template__time_entry[][comments]' : 'time_entry[][comments]', + (entry.nil? ? '' : entry.comments),:size => 35)%> <% else %> <%=h entry.nil? ? '' : entry.comments%> <% end %> -<% else %> -<% # leave a blank td %> - <% end %> - - <% if !(controller.getUnitDDHTML).blank? %> - <%= render :partial => controller.getUnitDDHTML , :locals => {:entry => entry} %> - <% end %> - +<% if !(controller.getUnitDDHTML).blank? %> + + <%= render :partial => controller.getUnitDDHTML , :locals => {:entry => entry} %> + +<% end %> <%= render :partial => controller.getCFInRowHTML , :locals => {:entry => entry, :isTemplate => false }%> diff --git a/app/views/wktime/_issue_header.html.erb b/app/views/wktime/_issue_header.html.erb index 7494669f2..6c69191f2 100644 --- a/app/views/wktime/_issue_header.html.erb +++ b/app/views/wktime/_issue_header.html.erb @@ -1,22 +1,25 @@ -<%= params[:enter_issue_id].blank? ? l(:field_project) : '' %> -<%= l(:field_issue) %> -<%= l(:field_activity) %> +<% if params[:enter_issue_id].blank? %> + <%= l(:field_project) %> +<% else %> + +<% end %> +<%= l(:field_issue) %> +<%= l(:field_activity) %> <% if !Setting.plugin_redmine_wktime['wktime_enter_comment_in_row'].blank? && Setting.plugin_redmine_wktime['wktime_enter_comment_in_row'].to_i == 1 %> <%= l(:field_comments)%> -<% else %> - <% end %> -<%= controller.getUnitLabel %> - +<% if !controller.getUnitLabel.blank? %> + <%= controller.getUnitLabel %> +<% end %> <%= render :partial => controller.getCFInRowHeaderHTML %> <% startOfWeek = getStartOfWeek %> <% for i in 0..6%> -<%= l('date.abbr_day_names')[(i+(startOfWeek))%7] %>
<%= I18n.localize(@startday+i, :format=>:short) unless @startday.nil? %> +<%= l('date.abbr_day_names')[(i+(startOfWeek))%7] %>
<%= I18n.localize(@startday+i, :format=>:short) unless @startday.nil? %> <% end %> diff --git a/app/views/wktime/_list.html.erb b/app/views/wktime/_list.html.erb index 6d17f22ea..69e3e4797 100644 --- a/app/views/wktime/_list.html.erb +++ b/app/views/wktime/_list.html.erb @@ -3,16 +3,11 @@ - + @@ -20,12 +15,11 @@ <% @entries.each do |entry| -%> "> - - - + + + :multiple=> true) %>
- <%= link_to image_tag('toggle_check.png'), - {}, - :onclick => 'toggleIssuesSelection(this); return false;', - :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %> - <%= l(:field_start_date) %> <%= l(:field_user) %> <%= controller.getLabelforSpField %> <%= l(:field_status) %><%= l(:field_status_modified_by) %>
<%= check_box_tag("ids[]", entry.spent_on, false, :id => nil) %><%=h format_date(entry.spent_on) %><%=h entry.user.login %><%=h entry.user.name %> <%= controller.getUnit(entry) %> <%=h html_hours("%.2f" % entry.hours) %> <%=h statusString(entry.status) unless entry.status.blank? %><%=h entry.status_updater %> <% #if entry.editable_by?(User.current) %> <%= link_to image_tag('edit.png'), {:controller => controller.controller_name, :action => 'edit', :startday => entry.spent_on, :user_id => entry.user_id, :tab => controller.controller_name}, diff --git a/app/views/wktime/_te_index.html.erb b/app/views/wktime/_te_index.html.erb index 5c8647ea1..f2c127317 100644 --- a/app/views/wktime/_te_index.html.erb +++ b/app/views/wktime/_te_index.html.erb @@ -9,7 +9,6 @@ <%= link_to l(:"button_new_#{controller_name}"), url_for(:controller => controller_name, :action => 'new'), :class => 'icon icon-time-add' %> <% end %> -

<%= form_tag({:controller => controller_name, :action => 'index'}, :method => :get, :id => 'query_form') do %> <%=h hidden_field_tag('tab', "#{controller_name}") %> @@ -94,7 +93,7 @@ $(document).ready(function()

<%=h select_tag('status', options_for_select(options_wk_status_select(status), :selected => status.nil? ? 0 : status.to_s ), - :onchange => "this.form.submit();") %>
<%= render :partial => 'wktime/date_range' %> diff --git a/app/views/wktime/_te_new.html.erb b/app/views/wktime/_te_new.html.erb index 891b6231c..526c0d3ad 100644 --- a/app/views/wktime/_te_new.html.erb +++ b/app/views/wktime/_te_new.html.erb @@ -2,7 +2,7 @@ <%= back_url_hidden_field_tag %> @@ -17,12 +17,13 @@ <% end %> - - <% end %> - \ No newline at end of file diff --git a/app/views/wktime/_wktime_cf_in_row_header.html.erb b/app/views/wktime/_wktime_cf_in_row_header.html.erb index c1a1e6de5..e0a7fddc0 100644 --- a/app/views/wktime/_wktime_cf_in_row_header.html.erb +++ b/app/views/wktime/_wktime_cf_in_row_header.html.erb @@ -1,19 +1,19 @@ - <% end %> - - <% end %> - \ No newline at end of file diff --git a/app/views/wktime/_worktime_header.html.erb b/app/views/wktime/_worktime_header.html.erb index e7095d80d..fb898953c 100644 --- a/app/views/wktime/_worktime_header.html.erb +++ b/app/views/wktime/_worktime_header.html.erb @@ -1,16 +1,23 @@ - - - - - + <% if controller.enterCommentInRow %> + + <% end %> + <% if controller.getUnitLabel.blank? %> + <% if controller.enterCustomFieldInRow(1) %> + + <% end %> + <% if controller.enterCustomFieldInRow(2) %> + + <% end %> + <% end %> + <% for i in 0..6%> <% if (isEditable) %> - + <% else %> <% end %> diff --git a/app/views/wktime/edit.html.erb b/app/views/wktime/edit.html.erb index edcad8acf..64fd116de 100644 --- a/app/views/wktime/edit.html.erb +++ b/app/views/wktime/edit.html.erb @@ -14,6 +14,15 @@ showWorkHeader = true; footerRows = 2; headerRows = 4; + <% if controller.enterCommentInRow %> + hStartIndex = hStartIndex + 1 ; + <% end %> + <% if controller.enterCustomFieldInRow(1) %> + hStartIndex = hStartIndex + 1 ; + <% end %> + <% if controller.enterCustomFieldInRow(2) %> + hStartIndex = hStartIndex + 1 ; + <% end %> <% end %> <% if !Setting.plugin_redmine_wktime['wktime_allow_blank_issue'].blank? && Setting.plugin_redmine_wktime['wktime_allow_blank_issue'].to_i == 1 %> diff --git a/app/views/wktime/testapi.html.erb b/app/views/wktime/testapi.html.erb index 8cb384912..46e96a1ca 100644 --- a/app/views/wktime/testapi.html.erb +++ b/app/views/wktime/testapi.html.erb @@ -1,6 +1,6 @@ Time & Expense
<%=l(:label_member)%> -<% ddMember = call_hook(:view_member_dropdown, {:project_id => @selected_project.id}) %> +<% ddMember = call_hook(:view_member_dropdown, {:project_id => @selected_project.id, :page => 'new'}) %> <% if !ddMember.blank? %> <%= ddMember %> <% else %> <% projmem = @selected_project.members.order("#{User.table_name}.firstname ASC,#{User.table_name}.lastname ASC") + projmem = projmem.to_a.uniq if !projmem.nil? %> <%=h select_tag('user_id', options_for_select( projmem.collect{|m| [ m.name, m.user_id ] }, diff --git a/app/views/wktime/_wktime_cf_in_row.erb b/app/views/wktime/_wktime_cf_in_row.erb index c131883fa..1b7035e9f 100644 --- a/app/views/wktime/_wktime_cf_in_row.erb +++ b/app/views/wktime/_wktime_cf_in_row.erb @@ -1,26 +1,27 @@ - <% custom_field_values = entry.nil? ? @new_custom_field_values : entry.custom_field_values cf_value = nil if !Setting.plugin_redmine_wktime['wktime_enter_cf_in_row1'].blank? && (cf_value = custom_field_values.detect { |cfv| cfv.custom_field.id == Setting.plugin_redmine_wktime['wktime_enter_cf_in_row1'].to_i }) != nil %> - <% if @editable %> - <%= custom_field_tag "time_entry[]", cf_value %> - <% else %> - <%= cf_value.value %> - <% end %> + + <% if @editable %> + <%= custom_field_tag "time_entry[]", cf_value %> + <% else %> + <%= cf_value.value %> + <% end %> + + <% cf_value = nil if !Setting.plugin_redmine_wktime['wktime_enter_cf_in_row2'].blank? && (cf_value = custom_field_values.detect { |cfv| cfv.custom_field.id == Setting.plugin_redmine_wktime['wktime_enter_cf_in_row2'].to_i }) != nil %> - <% if @editable %> - <%= custom_field_tag "time_entry[]", cf_value %> - <% else %> - <%= cf_value.value %> - <% end %> + + <% if @editable %> + <%= custom_field_tag "time_entry[]", cf_value %> + <% else %> + <%= cf_value.value %> + <% end %> + <% cf_value = nil if !Setting.plugin_redmine_wktime['wktime_enter_cf_in_row1'].blank? && (cf_value = @new_custom_field_values.detect { |cfv| cfv.custom_field.id == Setting.plugin_redmine_wktime['wktime_enter_cf_in_row1'].to_i }) != nil %> - + <%= cf_value.custom_field.name %> + + + <% cf_value = nil if !Setting.plugin_redmine_wktime['wktime_enter_cf_in_row2'].blank? && (cf_value = @new_custom_field_values.detect { |cfv| cfv.custom_field.id == Setting.plugin_redmine_wktime['wktime_enter_cf_in_row2'].to_i }) != nil %> - + <%= cf_value.custom_field.name %> +
<%= l(:"label_#{str}") %><%= text_field_tag "#{str}_#{(i+1)}" ,'0:00',:size => 7, :onchange => "validateHr(this,#{(i+1)});" %><%= text_field_tag "#{str}_#{(i+1)}" ,'0:00',:size => 4, :onchange => "validateHr(this,#{(i+1)});" %><%= value %>