Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

time_entry_import.rb 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006- Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. class TimeEntryImport < Import
  19. AUTO_MAPPABLE_FIELDS = {
  20. 'activity' => 'field_activity',
  21. 'user' => 'field_user',
  22. 'issue_id' => 'field_issue',
  23. 'spent_on' => 'field_spent_on',
  24. 'hours' => 'field_hours',
  25. 'comments' => 'field_comments'
  26. }
  27. def self.menu_item
  28. :time_entries
  29. end
  30. def self.authorized?(user)
  31. user.allowed_to?(:import_time_entries, nil, :global => true)
  32. end
  33. # Returns the objects that were imported
  34. def saved_objects
  35. TimeEntry.where(:id => saved_items.pluck(:obj_id)).order(:id).preload(:activity, :project, :issue => [:tracker, :priority, :status])
  36. end
  37. def mappable_custom_fields
  38. TimeEntryCustomField.all
  39. end
  40. def allowed_target_projects
  41. Project.allowed_to(user, :log_time).order(:lft)
  42. end
  43. def allowed_target_activities
  44. project.activities
  45. end
  46. def allowed_target_users
  47. users = []
  48. if project
  49. users = project.members.active.preload(:user)
  50. users = users.map(&:user).select{|u| u.allowed_to?(:log_time, project)}
  51. end
  52. users << User.current if User.current.logged? && !users.include?(User.current)
  53. users
  54. end
  55. def project
  56. project_id = mapping['project_id'].to_i
  57. allowed_target_projects.find_by_id(project_id) || allowed_target_projects.first
  58. end
  59. def activity
  60. if mapping['activity'].to_s =~ /\Avalue:(\d+)\z/
  61. activity_id = $1.to_i
  62. allowed_target_activities.find_by_id(activity_id)
  63. end
  64. end
  65. def user_value
  66. if mapping['user'].to_s =~ /\Avalue:(\d+)\z/
  67. $1.to_i
  68. end
  69. end
  70. private
  71. def build_object(row, item)
  72. object = TimeEntry.new
  73. object.author = user
  74. activity_id = nil
  75. if activity
  76. activity_id = activity.id
  77. elsif activity_name = row_value(row, 'activity')
  78. activity_id = allowed_target_activities.named(activity_name).first.try(:id)
  79. end
  80. user_id = nil
  81. if user.allowed_to?(:log_time_for_other_users, project)
  82. if user_value
  83. user_id = user_value
  84. elsif user_name = row_value(row, 'user')
  85. user_id = Principal.detect_by_keyword(allowed_target_users, user_name).try(:id)
  86. end
  87. else
  88. user_id = user.id
  89. end
  90. attributes = {
  91. :activity_id => activity_id,
  92. :author_id => user.id,
  93. :user_id => user_id,
  94. :spent_on => row_date(row, 'spent_on'),
  95. :hours => row_value(row, 'hours'),
  96. :comments => row_value(row, 'comments')
  97. }
  98. if issue_id = row_value(row, 'issue_id').presence
  99. attributes[:issue_id] = issue_id
  100. object.project = issue_project(issue_id)
  101. else
  102. attributes[:project_id] = project.id
  103. object.project = project
  104. end
  105. attributes['custom_field_values'] = object.custom_field_values.inject({}) do |h, v|
  106. value =
  107. case v.custom_field.field_format
  108. when 'date'
  109. row_date(row, "cf_#{v.custom_field.id}")
  110. else
  111. row_value(row, "cf_#{v.custom_field.id}")
  112. end
  113. if value
  114. h[v.custom_field.id.to_s] = v.custom_field.value_from_keyword(value, object)
  115. end
  116. h
  117. end
  118. object.send(:safe_attributes=, attributes, user)
  119. object
  120. end
  121. def issue_project(issue_id)
  122. if issue_project_id = Issue.where(id: issue_id).limit(1).pick(:project_id)
  123. (@projects_cache ||= {})[issue_project_id] ||= allowed_target_projects.find_by_id(issue_project_id)
  124. end
  125. end
  126. end