summaryrefslogtreecommitdiff
path: root/lib/api/time_tracking_endpoints.rb
blob: 05b4b490e271a2ca2fc476f910585eb1ca0f42b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
module API
  module TimeTrackingEndpoints
    extend ActiveSupport::Concern

    included do
      helpers do
        def issuable_name
          declared_params.has_key?(:issue_iid) ? 'issue' : 'merge_request'
        end

        def issuable_key
          "#{issuable_name}_iid".to_sym
        end

        def update_issuable_key
          "update_#{issuable_name}".to_sym
        end

        def read_issuable_key
          "read_#{issuable_name}".to_sym
        end

        def load_issuable
          @issuable ||= begin
            case issuable_name
            when 'issue'
              find_project_issue(params.delete(issuable_key))
            when 'merge_request'
              find_project_merge_request(params.delete(issuable_key))
            end
          end
        end

        def update_issuable(attrs)
          custom_params = declared_params(include_missing: false)
          custom_params.merge!(attrs)

          issuable = update_service.new(user_project, current_user, custom_params).execute(load_issuable)
          if issuable.valid?
            present issuable, with: Entities::IssuableTimeStats
          else
            render_validation_error!(issuable)
          end
        end

        def update_service
          issuable_name == 'issue' ? ::Issues::UpdateService : ::MergeRequests::UpdateService
        end
      end

      issuable_name            = name.end_with?('Issues') ? 'issue' : 'merge_request'
      issuable_collection_name = issuable_name.pluralize
      issuable_key             = "#{issuable_name}_iid".to_sym

      desc "Set a time estimate for a project #{issuable_name}"
      params do
        requires issuable_key, type: Integer, desc: "The ID of a project #{issuable_name}"
        requires :duration, type: String, desc: 'The duration to be parsed'
      end
      post ":id/#{issuable_collection_name}/:#{issuable_key}/time_estimate" do
        authorize! update_issuable_key, load_issuable

        status :ok
        update_issuable(time_estimate: Gitlab::TimeTrackingFormatter.parse(params.delete(:duration)))
      end

      desc "Reset the time estimate for a project #{issuable_name}"
      params do
        requires issuable_key, type: Integer, desc: "The ID of a project #{issuable_name}"
      end
      post ":id/#{issuable_collection_name}/:#{issuable_key}/reset_time_estimate" do
        authorize! update_issuable_key, load_issuable

        status :ok
        update_issuable(time_estimate: 0)
      end

      desc "Add spent time for a project #{issuable_name}"
      params do
        requires issuable_key, type: Integer, desc: "The ID of a project #{issuable_name}"
        requires :duration, type: String, desc: 'The duration to be parsed'
      end
      post ":id/#{issuable_collection_name}/:#{issuable_key}/add_spent_time" do
        authorize! update_issuable_key, load_issuable

        update_issuable(spend_time: {
          duration: Gitlab::TimeTrackingFormatter.parse(params.delete(:duration)),
          user: current_user
        })
      end

      desc "Reset spent time for a project #{issuable_name}"
      params do
        requires issuable_key, type: Integer, desc: "The ID of a project #{issuable_name}"
      end
      post ":id/#{issuable_collection_name}/:#{issuable_key}/reset_spent_time" do
        authorize! update_issuable_key, load_issuable

        status :ok
        update_issuable(spend_time: { duration: :reset, user: current_user })
      end

      desc "Show time stats for a project #{issuable_name}"
      params do
        requires issuable_key, type: Integer, desc: "The ID of a project #{issuable_name}"
      end
      get ":id/#{issuable_collection_name}/:#{issuable_key}/time_stats" do
        authorize! read_issuable_key, load_issuable

        present load_issuable, with: Entities::IssuableTimeStats
      end
    end
  end
end