summaryrefslogtreecommitdiff
path: root/app/services
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2017-01-18 15:49:22 +0000
committerDouwe Maan <douwe@gitlab.com>2017-01-18 15:49:22 +0000
commitf208897ccbdb539eb16a72d32cce68881eaffca7 (patch)
tree1b731e73ac9bc08757c29f1fc157617221eb612c /app/services
parent5e9196b3bcc31ce7fd698ed49af5d39eae1da630 (diff)
parent63b36241945a7f9bb280f360b3b269de8c5be8f6 (diff)
downloadgitlab-ce-f208897ccbdb539eb16a72d32cce68881eaffca7.tar.gz
Merge branch 'backport-time-tracking-ce' into 'master'
Backport timetracking to CE See merge request !8195
Diffstat (limited to 'app/services')
-rw-r--r--app/services/issuable_base_service.rb26
-rw-r--r--app/services/slash_commands/interpret_service.rb47
-rw-r--r--app/services/system_note_service.rb51
3 files changed, 123 insertions, 1 deletions
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index 4ce5fd993d9..7491c256b99 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -36,6 +36,14 @@ class IssuableBaseService < BaseService
end
end
+ def create_time_estimate_note(issuable)
+ SystemNoteService.change_time_estimate(issuable, issuable.project, current_user)
+ end
+
+ def create_time_spent_note(issuable)
+ SystemNoteService.change_time_spent(issuable, issuable.project, current_user)
+ end
+
def filter_params(issuable)
ability_name = :"admin_#{issuable.to_ability_name}"
@@ -156,6 +164,7 @@ class IssuableBaseService < BaseService
def create(issuable)
merge_slash_commands_into_params!(issuable)
filter_params(issuable)
+ change_time_spent(issuable)
params.delete(:state_event)
params[:author] ||= current_user
@@ -198,13 +207,14 @@ class IssuableBaseService < BaseService
change_subscription(issuable)
change_todo(issuable)
filter_params(issuable)
+ time_spent = change_time_spent(issuable)
old_labels = issuable.labels.to_a
old_mentioned_users = issuable.mentioned_users.to_a
label_ids = process_label_ids(params, existing_label_ids: issuable.label_ids)
params[:label_ids] = label_ids if labels_changing?(issuable.label_ids, label_ids)
- if params.present? && update_issuable(issuable, params)
+ if (params.present? || time_spent) && update_issuable(issuable, params)
# We do not touch as it will affect a update on updated_at field
ActiveRecord::Base.no_touching do
handle_common_system_notes(issuable, old_labels: old_labels)
@@ -251,6 +261,12 @@ class IssuableBaseService < BaseService
end
end
+ def change_time_spent(issuable)
+ time_spent = params.delete(:spend_time)
+
+ issuable.spend_time(time_spent, current_user) if time_spent
+ end
+
def has_changes?(issuable, old_labels: [])
valid_attrs = [:title, :description, :assignee_id, :milestone_id, :target_branch]
@@ -272,6 +288,14 @@ class IssuableBaseService < BaseService
create_task_status_note(issuable)
end
+ if issuable.previous_changes.include?('time_estimate')
+ create_time_estimate_note(issuable)
+ end
+
+ if issuable.time_spent?
+ create_time_spent_note(issuable)
+ end
+
create_labels_note(issuable, old_labels) if issuable.labels != old_labels
end
end
diff --git a/app/services/slash_commands/interpret_service.rb b/app/services/slash_commands/interpret_service.rb
index d18844ac0e3..a6e35d340e9 100644
--- a/app/services/slash_commands/interpret_service.rb
+++ b/app/services/slash_commands/interpret_service.rb
@@ -255,6 +255,53 @@ module SlashCommands
@updates[:wip_event] = issuable.work_in_progress? ? 'unwip' : 'wip'
end
+ desc 'Set time estimate'
+ params '<1w 3d 2h 14m>'
+ condition do
+ current_user.can?(:"admin_#{issuable.to_ability_name}", project)
+ end
+ command :estimate do |raw_duration|
+ time_estimate = Gitlab::TimeTrackingFormatter.parse(raw_duration)
+
+ if time_estimate
+ @updates[:time_estimate] = time_estimate
+ end
+ end
+
+ desc 'Add or substract spent time'
+ params '<1h 30m | -1h 30m>'
+ condition do
+ current_user.can?(:"admin_#{issuable.to_ability_name}", issuable)
+ end
+ command :spend do |raw_duration|
+ reduce_time = raw_duration.sub!(/\A-/, '')
+ time_spent = Gitlab::TimeTrackingFormatter.parse(raw_duration)
+
+ if time_spent
+ time_spent *= -1 if reduce_time
+
+ @updates[:spend_time] = time_spent
+ end
+ end
+
+ desc 'Remove time estimate'
+ condition do
+ issuable.persisted? &&
+ current_user.can?(:"admin_#{issuable.to_ability_name}", project)
+ end
+ command :remove_estimate do
+ @updates[:time_estimate] = 0
+ end
+
+ desc 'Remove spent time'
+ condition do
+ issuable.persisted? &&
+ current_user.can?(:"admin_#{issuable.to_ability_name}", project)
+ end
+ command :remove_time_spent do
+ @updates[:spend_time] = :reset
+ end
+
# This is a dummy command, so that it appears in the autocomplete commands
desc 'CC'
params '@user'
diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb
index 7613ecd5021..5ca2551ee61 100644
--- a/app/services/system_note_service.rb
+++ b/app/services/system_note_service.rb
@@ -109,6 +109,57 @@ module SystemNoteService
create_note(noteable: noteable, project: project, author: author, note: body)
end
+ # Called when the estimated time of a Noteable is changed
+ #
+ # noteable - Noteable object
+ # project - Project owning noteable
+ # author - User performing the change
+ # time_estimate - Estimated time
+ #
+ # Example Note text:
+ #
+ # "Changed estimate of this issue to 3d 5h"
+ #
+ # Returns the created Note object
+
+ def change_time_estimate(noteable, project, author)
+ parsed_time = Gitlab::TimeTrackingFormatter.output(noteable.time_estimate)
+ body = if noteable.time_estimate == 0
+ "Removed time estimate on this #{noteable.human_class_name}"
+ else
+ "Changed time estimate of this #{noteable.human_class_name} to #{parsed_time}"
+ end
+
+ create_note(noteable: noteable, project: project, author: author, note: body)
+ end
+
+ # Called when the spent time of a Noteable is changed
+ #
+ # noteable - Noteable object
+ # project - Project owning noteable
+ # author - User performing the change
+ # time_spent - Spent time
+ #
+ # Example Note text:
+ #
+ # "Added 2h 30m of time spent on this issue"
+ #
+ # Returns the created Note object
+
+ def change_time_spent(noteable, project, author)
+ time_spent = noteable.time_spent
+
+ if time_spent == :reset
+ body = "Removed time spent on this #{noteable.human_class_name}"
+ else
+ parsed_time = Gitlab::TimeTrackingFormatter.output(time_spent.abs)
+ action = time_spent > 0 ? 'Added' : 'Subtracted'
+ body = "#{action} #{parsed_time} of time spent on this #{noteable.human_class_name}"
+ end
+
+ create_note(noteable: noteable, project: project, author: author, note: body)
+ end
+
# Called when the status of a Noteable is changed
#
# noteable - Noteable object