tenk 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 093232af1d5cd795516e931877bbb4d530bb664d
4
- data.tar.gz: 016d76cb18cc7e7eb657b9f7ceec1048425cc010
3
+ metadata.gz: 481030d31a51a4b9af37b7610a1898e827741ffa
4
+ data.tar.gz: 2ba195e09023d21d85077ad2010d3ae0edd07b77
5
5
  SHA512:
6
- metadata.gz: f40f2afa5d45a2fc294463182409d73041de959ea34cdc8d8f7ac6ac78318f74c5b0d538ccba62cd3a639642adb0c1790a81969877a714de655b82bf507c0620
7
- data.tar.gz: e7b9564a844715ff09c7252bbe1d743dda79447541e92c11884899d183f44a217897941799cd267235bd9586d12c883fae91357fde27a58098059fca14581aff
6
+ metadata.gz: d8e47f142b68614f2c27604dc10620504ac59f17368582334c20b54c4626b86324cd1400607277c369309b6be25b3b372fb1c1d447974814d56e8f31ecd0b9bd
7
+ data.tar.gz: 1d3f00dc05feb8a07b5df4939143c804cb861ebc8f9c4ef38bad722a2a4a1b8a6d65f7fddcfa6da6ef3c0b5da0c5e6e21de87ad7caa8a09b42bc21930f98e4ca
data/bin/tenk ADDED
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler'
4
+ Bundler.setup(:default)
5
+ require 'optparse'
6
+ require 'tenk'
7
+
8
+ options = {}
9
+
10
+ opt_parser = OptionParser.new do |opt|
11
+ opt.banner = "Usage: tenk #{$PROGRAM_NAME} COMMAND"
12
+ opt.separator ''
13
+ opt.separator 'Commands'
14
+ opt.separator ' list_people: list people in your 10k account'
15
+ opt.separator ' list_projects: list projects in your 10k account'
16
+ opt.separator ''
17
+ opt.separator 'Options'
18
+
19
+ opt.on('-h', '--help', 'help') do
20
+ puts opt_parser
21
+ end
22
+ end
23
+
24
+ opts = opt_parser.parse!
25
+
26
+ def client
27
+ token = ENV['TENK_TOKEN'] || fail('No api token set. Set TENK_TOKEN environment variable.')
28
+ @_client ||= Tenk.new token: token, api_base: ENV['TENK_API_BASE']
29
+ end
30
+
31
+ def list_people
32
+ users = []
33
+ page = 1
34
+ loop do
35
+ response = client.users.list(page: page)
36
+ new_users = response.data
37
+ users << new_users
38
+ break unless response.paging.next
39
+ page += 1
40
+ end
41
+ users.flatten!
42
+ discipline_groups = users.group_by(&:discipline)
43
+ discipline_groups.map do |discipline, group|
44
+ puts ''
45
+ puts discipline
46
+ group.each do |person|
47
+ puts " - [ ] #{person.display_name}"
48
+ end
49
+ puts ''
50
+ end
51
+ end
52
+
53
+ def list_projects
54
+ projects = []
55
+ page = 1
56
+ loop do
57
+ response = client.projects.list(page: page)
58
+ new_projects = response.data
59
+ projects << new_projects
60
+ break unless response.paging.next
61
+ page += 1
62
+ end
63
+ projects.flatten!
64
+ project_groups = projects.sort_by(&:name).group_by(&:project_state)
65
+ project_groups.each do |state, projects|
66
+ puts ''
67
+ puts state
68
+ projects.each do |project|
69
+ puts " - [ ] #{project.name}"
70
+ end
71
+ puts ''
72
+ end
73
+ end
74
+
75
+ case ARGV[0]
76
+ when 'list_people'
77
+ list_people
78
+ when 'list_projects'
79
+ list_projects
80
+ else
81
+ puts opt_parser
82
+ end
data/lib/approvals.rb ADDED
@@ -0,0 +1,59 @@
1
+ require 'hashie'
2
+
3
+ module Tenk
4
+ # API actions for Approval resource which represents an approval of a time
5
+ # entry or expense item
6
+ class Approvals < ::Tenk::Resource
7
+ # The valid parameters for an Approval list request
8
+ class ListRequest < ::Hashie::Trash
9
+ property :fields, default: ''
10
+ property :per_page, default: 20
11
+ property :page, default: 1
12
+ end
13
+
14
+ # The valid parameters for an Approval get request
15
+ class GetRequest < ::Hashie::Trash
16
+ property :fields, default: ''
17
+ end
18
+
19
+ # The valid parameters for an approval create request
20
+ class CreateRequest < ::Hashie::Trash
21
+ property :approvables
22
+ property :status
23
+ end
24
+
25
+ # The valid parameters for an approval update request
26
+ class UpdateRequest < CreateRequest
27
+ end
28
+
29
+ # List Approvals from this 10k account
30
+ # @param opts [Hash] the query parameters for the list request
31
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
32
+ # @see Tenk::Approvals::ListRequest
33
+ def list(opts = {})
34
+ super(ListRequest.new(opts))
35
+ end
36
+
37
+ # Get one Approval from the 10k account
38
+ # @param id [Integer] the id of the Approval
39
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
40
+ # @see Tenk::Approvals::GetRequest
41
+ def get(id, opts = {})
42
+ super(id, GetRequest.new(opts))
43
+ end
44
+
45
+ # FIXME: CREATE does not work due to the permissions of API users
46
+
47
+ # def create(opts = {})
48
+ # @_client.logger.warn("Approvals currently cannot be created with API")
49
+ # @_client.post_with_body(resource_root, CreateRequest.new(opts))
50
+ # end
51
+
52
+ # FIXME: UPDATE does not work due to the permissions of API users
53
+
54
+ # def update(id, opts = {})
55
+ # @_client.logger.warn("Approvals currently cannot be updated with API")
56
+ # super(id, UpdateRequest.new(opts))
57
+ # end
58
+ end
59
+ end
data/lib/bill_rates.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'hashie'
2
+
3
+ module Tenk
4
+ # The API methods for obtaining and manipulating bill rats
5
+ class BillRates < ::Tenk::Resource
6
+ # The valid parameters for a BillRate list request
7
+ class ListRequest < ::Hashie::Trash
8
+ property :per_page, default: 20
9
+ property :page, default: 1
10
+ end
11
+
12
+ # The valid parameters for a BillRate get request
13
+ class GetRequest < ::Hashie::Trash; end
14
+
15
+ # The valid parameters for a BillRate create request
16
+ class CreateRequest < ::Hashie::Trash
17
+ property :discipline_id
18
+ property :role_id
19
+ property :assignable_id
20
+ property :user_id
21
+ property :rate
22
+ property :starts_at
23
+ property :ends_at
24
+ property :startdate
25
+ property :enddate
26
+ end
27
+
28
+ # The valid paramters for a BillRate update request
29
+ class UpdateRequest < CreateRequest; end
30
+
31
+ # FIXME: LIST does not work due to permissions of API users
32
+
33
+ # def list(opts = {})
34
+ # super(ListRequest.new(opts))
35
+ # end
36
+
37
+ # GET does not work due to permissions of API users
38
+
39
+ # def get(id)
40
+ # super(id, {})
41
+ # end
42
+
43
+ # FIXME: CREATE does not work
44
+
45
+ # def create(opts = {})
46
+ # super(CreateRequest.new(opts))
47
+ # end
48
+
49
+ # Update a BillRate for this 10k account
50
+ # @param id [Integer] the id of the bill rate
51
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
52
+ # @see UpdateRequest
53
+ def update(id, opts = {})
54
+ super(id, UpdateRequest.new(opts))
55
+ end
56
+ end
57
+ end
data/lib/client.rb ADDED
@@ -0,0 +1,153 @@
1
+ require 'faraday'
2
+ require 'hashie'
3
+ require 'json'
4
+
5
+ require_relative './configuration'
6
+ require_relative './resource'
7
+ require_relative './placeholder_resources'
8
+ require_relative './time_entries'
9
+ require_relative './users'
10
+ require_relative './bill_rates'
11
+ require_relative './projects'
12
+ require_relative './approvals'
13
+
14
+ module Tenk
15
+ # One client of the 10k API
16
+ class Client
17
+ attr_accessor :configuration
18
+ attr_accessor :logger
19
+
20
+ # Initialize a new Tenk client
21
+ # @param options [Hash] configuration options for the client
22
+ # @param block [Block] a block which will receive the new client as an arg
23
+ # @see Configuration
24
+ def initialize(options = {}, &block)
25
+ self.configuration = Configuration.new(options)
26
+ self.logger = configuration.logger
27
+
28
+ yield_or_eval(&block) if block_given?
29
+ end
30
+
31
+ # If a block is given, invoke it with this client. If the block takes no
32
+ # args, then just execute it as an instance of the client
33
+ def yield_or_eval(&block)
34
+ return unless block
35
+ block.arity > 0 ? yield(self) : instance_eval(&block)
36
+ end
37
+
38
+ # The Faraday connection used by this client
39
+ def connection
40
+ Faraday.new(url: configuration.api_base) do |faraday|
41
+ faraday.adapter Faraday.default_adapter
42
+ end
43
+ end
44
+
45
+ # Make a request to url, with a given method and options, and wrap the
46
+ # response in a Hashie::Mash
47
+ # @param url [String] the URL where to send the request
48
+ # @param method [Symbol] the HTTP method to use to send the request
49
+ # @param url_opts [Hash] the request payload, which will become query params
50
+ # @return [Hashie::Mash] the API response wrapped in a Hashie::Mash
51
+ def request(url, method, url_opts = {})
52
+ hashify_response(
53
+ connection.send(method) do |req|
54
+ req.url configuration.api_base + url, url_opts
55
+ req.headers['Content-Type'] = 'application/json'
56
+ req.headers['auth'] = configuration.token
57
+ end,
58
+ )
59
+ end
60
+
61
+ # Make a GET request to the API
62
+ # @param url [String] the URL where to send the request
63
+ # @param url_opts [Hash] the request payload, which will become query params
64
+ # @return [Hashie::Mash] the API response wrapped in a Hashie::Mash
65
+ def get(url, url_opts = {})
66
+ request(url, :get, url_opts)
67
+ end
68
+
69
+ # Make a POST request to the API
70
+ # @param url [String] the URL where to send the request
71
+ # @param url_opts [Hash] the request payload, which will become query params
72
+ # @return [Hashie::Mash] the API response wrapped in a Hashie::Mash
73
+ def post(url, url_opts = {})
74
+ request(url, :post, url_opts)
75
+ end
76
+
77
+ # Make a POST request to the API and use url_opts as a body payload instead
78
+ # of query params
79
+ # @param url [String] the URL where to send the request
80
+ # @param url_opts [Hash] the request payload, which will become the POST body
81
+ # @return [Hashie::Mash] the API response wrapped in a Hashie::Mash
82
+ def post_with_body(url, url_opts = {})
83
+ hashify_response(
84
+ get_connection.post do |req|
85
+ req.url configuration.api_base + url
86
+ req.body = JSON.generate(url_opts)
87
+ req.headers['Content-Type'] = 'application/json'
88
+ req.headers['auth'] = configuration.token
89
+ end,
90
+ )
91
+ end
92
+
93
+ # Make a PUT request to the API
94
+ # @param url [String] the URL where to send the request
95
+ # @param url_opts [Hash] the request payload, which will become query params
96
+ # @return [Hashie::Mash] the API response wrapped in a Hashie::Mash
97
+ def put(url, url_opts = {})
98
+ request(url, :put, url_opts)
99
+ end
100
+
101
+ # Make a DELETE request to the API
102
+ # @param url [String] the URL where to send the request
103
+ # @param url_opts [Hash] the request payload, which will become query params
104
+ # @return [Hashie::Mash] the API response wrapped in a Hashie::Mash
105
+ def delete(url, url_opts = {})
106
+ request(url, :delete, url_opts)
107
+ end
108
+
109
+ # Access the User resource using this client
110
+ # @return [Tenk::Users] a Users API class
111
+ def users
112
+ @_users ||= Tenk::Users.new(self)
113
+ end
114
+
115
+ # Access the PlaceholderResources resource using this client
116
+ # @return [Tenk::PlaceholderResources] a PlaceholderResources API class
117
+ def placeholder_resources
118
+ @_placeholder_resources ||= Tenk::PlaceholderResources.new(self)
119
+ end
120
+
121
+ # Access the Project resource using this client
122
+ # @return [Tenk::Projects] a Projects API class
123
+ def projects
124
+ @_projects ||= Tenk::Projects.new(self)
125
+ end
126
+
127
+ # Access the TimeEntry resource using this client
128
+ # @return [Tenk::TimeEntries] a TimeEntries API class
129
+ def time_entries
130
+ @_time_entries ||= Tenk::TimeEntries.new(self)
131
+ end
132
+
133
+ # Access the BillRates resource using this client
134
+ # @return [Tenk::BillRates] a BillRates API class
135
+ def bill_rates
136
+ @_bill_rates ||= Tenk::BillRates.new(self)
137
+ end
138
+
139
+ # Access the Approvals resource using this client
140
+ # @return [Tenk::Approvals] a Approvals API class
141
+ def approvals
142
+ @_approvals ||= Tenk::Approvals.new(self)
143
+ end
144
+
145
+ # Take a Farady response and turn it into a Hashie::Mash
146
+ # @param resp [Faraday::Response] a response provided by Faraday
147
+ # @return [Hashie::Mash] a Hashie::Mash version of the response body
148
+ def hashify_response(resp)
149
+ return true if resp.body.empty?
150
+ Hashie::Mash.new(JSON.parse(resp.body))
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,35 @@
1
+ require 'logger'
2
+
3
+ module Tenk
4
+ # Holds the configuration for a Tenk client (API key and base URL, and logger)
5
+ class Configuration
6
+ attr_accessor :token
7
+ attr_writer :api_base
8
+ attr_writer :logger
9
+
10
+ # Intialize a Tenk::Configuration
11
+ # @param opts [Hash] the configuration options
12
+ def initialize(opts = {})
13
+ opts.each do |key, value|
14
+ send("#{key}=", value)
15
+ end
16
+ end
17
+
18
+ # Return the base URL of the API
19
+ # @return [String] the base URL of the API
20
+ def api_base
21
+ @api_base || 'https://api.10000ft.com/api/v1'
22
+ end
23
+
24
+ # Return the current logger being used by the gem
25
+ # @return [Logger] the current logger
26
+ def logger
27
+ if @logger.blank?
28
+ @logger = Logger.new(STDERR)
29
+ @logger.level = Logger::WARN
30
+ end
31
+
32
+ @logger
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,51 @@
1
+ require 'hashie'
2
+
3
+ module Tenk
4
+ # API methods for PlaceholderResources, which are like Users, except they
5
+ # don't represent a specific person, but rather a Placeholder on the schedule
6
+ # for a certain kind of person / discipline
7
+ class PlaceholderResources < ::Tenk::Resource
8
+ # The valid parameters for a PlaceholderResources list request
9
+ class ListRequest < ::Hashie::Trash
10
+ property :fields, default: ''
11
+ property :per_page, default: 20
12
+ property :page, default: 1
13
+ end
14
+
15
+ # The valid parameters for a PlaceholderResources get request
16
+ class GetRequest < ::Hashie::Trash
17
+ property :fields, default: ''
18
+ end
19
+
20
+ # The valid parameters for a PlaceholderResources create request
21
+ class CreateRequest < ::Hashie::Trash
22
+ property :title
23
+ property :role
24
+ property :discipline
25
+ property :location
26
+ end
27
+
28
+ # The valid parameters for a PlaceholderResources update request
29
+ class UpdateRequest < CreateRequest
30
+ end
31
+
32
+ # FIXME: Can't test these on staging because Placeholders don't seem to
33
+ # be enabled on staging
34
+
35
+ # def list(opts = {})
36
+ # super(ListRequest.new(opts))
37
+ # end
38
+ #
39
+ # def get(id, opts = {})
40
+ # super(id, GetRequest.new(opts))
41
+ # end
42
+ #
43
+ # def create(opts = {})
44
+ # super(CreateRequest.new(opts))
45
+ # end
46
+ #
47
+ # def update(id, opts = {})
48
+ # super(id, UpdateRequest.new(opts))
49
+ # end
50
+ end
51
+ end
@@ -0,0 +1,80 @@
1
+ require 'hashie'
2
+
3
+ require_relative './project_resource'
4
+
5
+ module Tenk
6
+ # The API methods for Assignments which represent that a given user is
7
+ # assigned to a project or phase
8
+ class Projects::Assignments < ::Tenk::Projects::ProjectResource
9
+ # The valid parameters for an Assignment list request
10
+ class ListRequest < ::Hashie::Trash
11
+ property :from
12
+ property :to
13
+ property :per_page
14
+ property :page
15
+ end
16
+
17
+ # The valid parameters for an Assignment get request
18
+ class GetRequest < ::Hashie::Trash; end
19
+
20
+ # The valid parameters for an Assignment create request
21
+ class CreateRequest < ::Hashie::Trash
22
+ property :user_id
23
+ property :starts_at
24
+ property :ends_at
25
+ property :percent
26
+ property :fixed_hours
27
+ property :hours_per_day
28
+ property :allocation_mode
29
+ end
30
+
31
+ # The valid parameters for an Assignment update request
32
+ class UpdateRequest < CreateRequest; end
33
+
34
+ # List Assignments for a single project
35
+ # @param project_id [Integer] the id of the project
36
+ # @param opts [Hash] the query parameters to add to list request
37
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
38
+ # @see Tenk::Projects::Assignments::ListRequest
39
+ def list(project_id, opts = {})
40
+ super(project_id, ListRequest.new(opts))
41
+ end
42
+
43
+ # Get a single Assignment for this project
44
+ # @param project_id [Integer] the id of the project
45
+ # @param assignment_id [Integer] the id of the assignment
46
+ # @param opts [Hash] the query parameters to add to the get request
47
+ # @return [Hashie::Mash] the response as a Hashie::Mash
48
+ # @see Tenk::Projects::Assignments::GetRequest
49
+ def get(project_id, assignment_id, opts = {})
50
+ super(project_id, assignment_id, GetRequest.new(opts))
51
+ end
52
+
53
+ # Create a new Assignment for this project
54
+ # @param project_id [Integer] the id of the project
55
+ # @param opts [Hash] the post parameters to add to the create request
56
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
57
+ # @see Tenk::Projects::Assignments::CreateRequest
58
+ def create(project_id, opts = {})
59
+ super(project_id, CreateRequest.new(opts))
60
+ end
61
+
62
+ # Update an Assignment for this project
63
+ # @param project_id [Integer] the id of the project
64
+ # @param assignment_id [Integer] the id of the assignment
65
+ # @param opts [Hash] the post parameters to add to the create request
66
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
67
+ # @see Tenk::Projects::Assignments::UpdateRequest
68
+ def update(project_id, assignment_id, opts = {})
69
+ super(project_id, assignment_id, UpdateRequest.new(opts))
70
+ end
71
+
72
+ # Delete an Assignment for this project
73
+ # @param project_id [Integer] the id of the project
74
+ # @param assignment_id [Integer] the id of the assignment
75
+ # @return [bool] true if successful
76
+ def delete(project_id, assignment_id)
77
+ super(project_id, assignment_id)
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,52 @@
1
+ require 'hashie'
2
+
3
+ require_relative './project_resource'
4
+
5
+ module Tenk
6
+ # The API methods for BillRate resources
7
+ class Projects::BillRates < ::Tenk::Projects::ProjectResource
8
+ # The valid request parameters for listing BillRates
9
+ class ListRequest < ::Tenk::BillRates::ListRequest; end
10
+ # The valid request parameters for creating BillRates
11
+ class CreateRequest < ::Tenk::BillRates::CreateRequest; end
12
+ # The valid request parameters for updating BillRates
13
+ class UpdateRequest < ::Tenk::BillRates::UpdateRequest; end
14
+
15
+ # List BillRates for a single project
16
+ # @param project_id [Integer] the id of the project
17
+ # @param opts [Hash] the query parameters to add to list request
18
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
19
+ # @see Tenk::Projects::BillRates::ListRequest
20
+ def list(project_id, opts = {})
21
+ super(project_id, ListRequest.new(opts))
22
+ end
23
+
24
+ # Get a single BillRate for this project
25
+ # @param project_id [Integer] the id of the project
26
+ # @param bill_rate_id [Integer] the id of the bill_rate
27
+ # @return [Hashie::Mash] the response as a Hashie::Mash
28
+ # @see Tenk::Projects::BillRates::GetRequest
29
+ def get(project_id, bill_rate_id)
30
+ super(project_id, bill_rate_id, {})
31
+ end
32
+
33
+ # Create a new BillRate for this project
34
+ # @param project_id [Integer] the id of the project
35
+ # @param opts [Hash] the post parameters to add to the create request
36
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
37
+ # @see Tenk::Projects::BillRates::CreateRequest
38
+ def create(project_id, opts = {})
39
+ super(project_id, CreateRequest.new(opts))
40
+ end
41
+
42
+ # Update an BillRate for this project
43
+ # @param project_id [Integer] the id of the project
44
+ # @param bill_rate_id [Integer] the id of the bill_rate
45
+ # @param opts [Hash] the post parameters to add to the create request
46
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
47
+ # @see Tenk::Projects::BillRates::UpdateRequest
48
+ def update(project_id, bill_rate_id, opts = {})
49
+ super(project_id, bill_rate_id, UpdateRequest.new(opts))
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,63 @@
1
+ require 'hashie'
2
+
3
+ require_relative './project_resource'
4
+
5
+ module Tenk
6
+ # The API methods for Phases, which represent a part of a project with its own
7
+ # budget and resources
8
+ class Projects::Phases < ::Tenk::Projects::ProjectResource
9
+ # The valid parameters for a Phase list request
10
+ class ListRequest < Tenk::Projects::ListRequest; end
11
+
12
+ # The valid parameters for a Phase get request
13
+ class GetRequest < Tenk::Projects::GetRequest; end
14
+
15
+ # The valid parameters for a Phase create request
16
+ class CreateRequest < Tenk::Projects::CreateRequest
17
+ property :phase_name
18
+ end
19
+
20
+ # The valid parameters for a Phase update request
21
+ class UpdateRequest < Tenk::Projects::UpdateRequest
22
+ property :phase_name
23
+ end
24
+
25
+ # List Phases for a single project
26
+ # @param project_id [Integer] the id of the project
27
+ # @param opts [Hash] the query parameters to add to list request
28
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
29
+ # @see Tenk::Projects::Phases::ListRequest
30
+ def list(project_id, opts = {})
31
+ super(project_id, ListRequest.new(opts))
32
+ end
33
+
34
+ # Get a single Assignment for this project
35
+ # @param project_id [Integer] the id of the project
36
+ # @param phase_id [Integer] the id of the phase
37
+ # @param opts [Hash] the query parameters to add to the get request
38
+ # @return [Hashie::Mash] the response as a Hashie::Mash
39
+ # @see Tenk::Projects::Phases::GetRequest
40
+ def get(project_id, phase_id, opts = {})
41
+ super(project_id, phase_id, GetRequest.new(opts))
42
+ end
43
+
44
+ # Create a new Assignment for this project
45
+ # @param project_id [Integer] the id of the project
46
+ # @param opts [Hash] the post parameters to add to the create request
47
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
48
+ # @see Tenk::Projects::Phases::CreateRequest
49
+ def create(project_id, opts = {})
50
+ super(project_id, CreateRequest.new(opts))
51
+ end
52
+
53
+ # Update an Assignment for this project
54
+ # @param project_id [Integer] the id of the project
55
+ # @param phase_id [Integer] the id of the phase
56
+ # @param opts [Hash] the post parameters to add to the create request
57
+ # @return [Hashie::Mash] the API response as a Hashie::Mash
58
+ # @see Tenk::Projects::Phases::UpdateRequest
59
+ def update(project_id, phase_id, opts = {})
60
+ super(project_id, phase_id, UpdateRequest.new(opts))
61
+ end
62
+ end
63
+ end