time_tracking_endpoints.rb 4.13 KB
Newer Older
1 2 3 4 5 6 7 8
module API
  module V3
    module TimeTrackingEndpoints
      extend ActiveSupport::Concern

      included do
        helpers do
          def issuable_name
9
            declared_params.key?(:issue_id) ? 'issue' : 'merge_request'
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 115 116
          end

          def issuable_key
            "#{issuable_name}_id".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: ::API::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}_id".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: ::API::Entities::IssuableTimeStats
        end
      end
    end
  end
end