@@ -132,6 +132,47 @@ module Freeagent
132132 end
133133 end
134134
135+ class Projects < Thor
136+ no_commands do
137+ def api
138+ @api ||= API . new
139+ end
140+
141+ def contacts
142+ @contacts ||= Hash . new { |cache , url | cache [ url ] = api . contact url . split ( '/' ) . last }
143+ end
144+
145+ def human project
146+ [
147+ project . name ,
148+ project . contact_name ,
149+ project . status ,
150+ project . starts_on ,
151+ project . ends_on ,
152+ project . budget
153+ ] . join ( "\t " )
154+ end
155+ end
156+
157+ desc 'list [-C CONTACT] [NAME [NAME ...]]' , 'List projects'
158+ method_option :contact , aliases : '-C' , type : :string , default : nil , desc : "Limit to a contact, identified by name or email"
159+ method_option :format , type : :string , default : 'human' , desc : 'Output format, one of human or json'
160+ def list *names
161+ contact = options [ :contact ] . nil? ? nil : match ( :contact , api . contacts , options [ :contact ] , :first_name , :last_name , :organisation_name , :email , :billing_email )
162+ contacts [ contact . url ] = contact unless contact . nil?
163+
164+ api . projects ( contact : contact ) . select do |project |
165+ names . empty? || names . include? ( project . name )
166+ end . each do |project |
167+ puts case options [ :format ] . downcase
168+ when 'human' ; human ( project )
169+ when 'json' ; project . to_json
170+ else raise ArgumentError , "unknown output format #{ options [ :format ] } "
171+ end
172+ end
173+ end
174+ end
175+
135176 class Invoices < Thor
136177 no_commands do
137178 def api
@@ -193,6 +234,9 @@ module Freeagent
193234 desc "timeslips" , "Create, read, update and delete timeslips"
194235 subcommand "timeslips" , Timeslips
195236
237+ desc "projects" , "Create, read, update and delete projects"
238+ subcommand "projects" , Projects
239+
196240 desc "invoices" , "Create, read, update and delete invoices"
197241 subcommand "invoices" , Invoices
198242 end
0 commit comments