rexpense 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +22 -0
  3. data/.coveralls.yml +1 -0
  4. data/.gitignore +24 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +54 -0
  7. data/.travis.yml +9 -0
  8. data/CHANGELOG.md +1 -0
  9. data/Gemfile +4 -0
  10. data/Gemfile.lock +97 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +195 -0
  13. data/Rakefile +6 -0
  14. data/bin/console +14 -0
  15. data/bin/rspec +21 -0
  16. data/bin/setup +7 -0
  17. data/lib/rexpense/client.rb +39 -0
  18. data/lib/rexpense/configuration.rb +13 -0
  19. data/lib/rexpense/entities/activity.rb +11 -0
  20. data/lib/rexpense/entities/activity_collection.rb +14 -0
  21. data/lib/rexpense/entities/advancement.rb +14 -0
  22. data/lib/rexpense/entities/advancement_collection.rb +14 -0
  23. data/lib/rexpense/entities/advancement_devolution.rb +13 -0
  24. data/lib/rexpense/entities/attachment.rb +13 -0
  25. data/lib/rexpense/entities/attachment_collection.rb +14 -0
  26. data/lib/rexpense/entities/base.rb +9 -0
  27. data/lib/rexpense/entities/collection.rb +65 -0
  28. data/lib/rexpense/entities/comment.rb +13 -0
  29. data/lib/rexpense/entities/comment_collection.rb +14 -0
  30. data/lib/rexpense/entities/expense.rb +22 -0
  31. data/lib/rexpense/entities/expense_collection.rb +14 -0
  32. data/lib/rexpense/entities/membership.rb +10 -0
  33. data/lib/rexpense/entities/membership_collection.rb +14 -0
  34. data/lib/rexpense/entities/organization.rb +14 -0
  35. data/lib/rexpense/entities/organization_collection.rb +14 -0
  36. data/lib/rexpense/entities/pre_expense.rb +17 -0
  37. data/lib/rexpense/entities/pre_expense_collection.rb +14 -0
  38. data/lib/rexpense/entities/reimbursement.rb +14 -0
  39. data/lib/rexpense/entities/reimbursement_collection.rb +14 -0
  40. data/lib/rexpense/entities/tag.rb +8 -0
  41. data/lib/rexpense/entities/tag_collection.rb +14 -0
  42. data/lib/rexpense/entities/user.rb +14 -0
  43. data/lib/rexpense/entities/user_collection.rb +14 -0
  44. data/lib/rexpense/entities/webhook.rb +10 -0
  45. data/lib/rexpense/entities/webhook_collection.rb +14 -0
  46. data/lib/rexpense/exception.rb +11 -0
  47. data/lib/rexpense/http.rb +41 -0
  48. data/lib/rexpense/request.rb +56 -0
  49. data/lib/rexpense/resources/activity.rb +24 -0
  50. data/lib/rexpense/resources/advancement.rb +20 -0
  51. data/lib/rexpense/resources/advancement_devolution.rb +36 -0
  52. data/lib/rexpense/resources/base.rb +52 -0
  53. data/lib/rexpense/resources/expense.rb +39 -0
  54. data/lib/rexpense/resources/nested_endpoints/attachment.rb +48 -0
  55. data/lib/rexpense/resources/nested_endpoints/comment.rb +84 -0
  56. data/lib/rexpense/resources/nested_endpoints/membership.rb +74 -0
  57. data/lib/rexpense/resources/nested_endpoints/participant.rb +43 -0
  58. data/lib/rexpense/resources/organization.rb +31 -0
  59. data/lib/rexpense/resources/pre_expense.rb +56 -0
  60. data/lib/rexpense/resources/reimbursement.rb +20 -0
  61. data/lib/rexpense/resources/resource_base.rb +105 -0
  62. data/lib/rexpense/resources/tag.rb +82 -0
  63. data/lib/rexpense/resources/webhook.rb +82 -0
  64. data/lib/rexpense/response.rb +43 -0
  65. data/lib/rexpense/version.rb +3 -0
  66. data/lib/rexpense.rb +19 -0
  67. data/rexpense.gemspec +48 -0
  68. data/spec/lib/rexpense/client_spec.rb +47 -0
  69. data/spec/lib/rexpense/configuration_spec.rb +26 -0
  70. data/spec/lib/rexpense/entities/activity_collection_spec.rb +5 -0
  71. data/spec/lib/rexpense/entities/activity_spec.rb +9 -0
  72. data/spec/lib/rexpense/entities/advancement_collection_spec.rb +5 -0
  73. data/spec/lib/rexpense/entities/advancement_devolution_spec.rb +9 -0
  74. data/spec/lib/rexpense/entities/advancement_spec.rb +10 -0
  75. data/spec/lib/rexpense/entities/base_spec.rb +28 -0
  76. data/spec/lib/rexpense/entities/collection_spec.rb +70 -0
  77. data/spec/lib/rexpense/entities/comment_collection_spec.rb +5 -0
  78. data/spec/lib/rexpense/entities/comment_spec.rb +10 -0
  79. data/spec/lib/rexpense/entities/expense_collection_spec.rb +5 -0
  80. data/spec/lib/rexpense/entities/expense_spec.rb +14 -0
  81. data/spec/lib/rexpense/entities/membership_collection_spec.rb +5 -0
  82. data/spec/lib/rexpense/entities/membership_spec.rb +7 -0
  83. data/spec/lib/rexpense/entities/organization_collection_spec.rb +5 -0
  84. data/spec/lib/rexpense/entities/organization_spec.rb +8 -0
  85. data/spec/lib/rexpense/entities/pre_expense_collection_spec.rb +5 -0
  86. data/spec/lib/rexpense/entities/pre_expense_spec.rb +10 -0
  87. data/spec/lib/rexpense/entities/reimbursement_collection_spec.rb +5 -0
  88. data/spec/lib/rexpense/entities/reimbursement_spec.rb +10 -0
  89. data/spec/lib/rexpense/entities/user_collection_spec.rb +5 -0
  90. data/spec/lib/rexpense/entities/user_spec.rb +10 -0
  91. data/spec/lib/rexpense/entities/webhook_collection_spec.rb +5 -0
  92. data/spec/lib/rexpense/entities/webhook_spec.rb +7 -0
  93. data/spec/lib/rexpense/http_spec.rb +37 -0
  94. data/spec/lib/rexpense/request_spec.rb +29 -0
  95. data/spec/lib/rexpense/resources/activity_spec.rb +16 -0
  96. data/spec/lib/rexpense/resources/advancement_devolution_spec.rb +29 -0
  97. data/spec/lib/rexpense/resources/advancement_spec.rb +207 -0
  98. data/spec/lib/rexpense/resources/expense_spec.rb +227 -0
  99. data/spec/lib/rexpense/resources/organization_spec.rb +162 -0
  100. data/spec/lib/rexpense/resources/pre_expense_spec.rb +83 -0
  101. data/spec/lib/rexpense/resources/reimbursement_spec.rb +207 -0
  102. data/spec/lib/rexpense/resources/tag_specs.rb +77 -0
  103. data/spec/lib/rexpense/resources/webhook_spec.rb +51 -0
  104. data/spec/lib/rexpense/response_spec.rb +91 -0
  105. data/spec/lib/rexpense_spec.rb +34 -0
  106. data/spec/spec_helper.rb +39 -0
  107. data/spec/support/attachments/logo.png +0 -0
  108. data/spec/support/client.rb +3 -0
  109. data/spec/support/matchers/have_attr_accessor.rb +18 -0
  110. data/spec/support/shared_examples/entity_attributes.rb +9 -0
  111. data/spec/support/shared_examples/entity_collection.rb +19 -0
  112. data/spec/support/shared_examples/http_request_methods.rb +35 -0
  113. data/spec/support/vcr.rb +7 -0
  114. metadata +390 -0
@@ -0,0 +1,65 @@
1
+ module Rexpense
2
+ module Entities
3
+ #
4
+ # A wrapper to Rexpense collection returns from API.
5
+ # This wrapper represents a collection and it's responsible for
6
+ # processing pagination information as well.
7
+ #
8
+ class Collection < Base
9
+ PAGE_REGEX = /page=(\d+)/
10
+
11
+ attr_reader :response, :collection, :headers
12
+
13
+ def initialize(response)
14
+ @response = response
15
+ @collection = []
16
+ @headers = begin
17
+ response.headers["Link"].split(",")
18
+ rescue
19
+ []
20
+ end
21
+ end
22
+
23
+ def self.build(response)
24
+ new(response).build
25
+ end
26
+
27
+ def build
28
+ build_collection
29
+ self
30
+ end
31
+
32
+ def next_page
33
+ page_for(:next)
34
+ end
35
+
36
+ def last_page
37
+ page_for(:last)
38
+ end
39
+
40
+ def previous_page
41
+ page_for(:prev)
42
+ end
43
+
44
+ def first_page
45
+ page_for(:first)
46
+ end
47
+
48
+ private
49
+
50
+ def page_for(page_rel)
51
+ header_link_for(page_rel).match(PAGE_REGEX)[1].to_i
52
+ rescue
53
+ nil
54
+ end
55
+
56
+ def header_link_for(rel)
57
+ headers.select { |n| n =~ /rel=#{rel}/ }.first
58
+ end
59
+
60
+ def build_collection
61
+ raise NotImplementedError
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,13 @@
1
+ module Rexpense
2
+ module Entities
3
+ class Comment < Base
4
+ attribute :id, Integer
5
+ attribute :content, String
6
+ attribute :content_html, String
7
+ attribute :mentioned_users, Array[Rexpense::Entities::User]
8
+ attribute :user, Rexpense::Entities::User
9
+
10
+ [:created_at, :updated_at, :deleted_at].each { |n| attribute n, DateTime }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ #
4
+ # A wrapper to Comment collection
5
+ #
6
+ class CommentCollection < Collection
7
+ def build_collection
8
+ response.parsed_body['comments'].each do |attributes|
9
+ collection.push(Rexpense::Entities::Comment.new(attributes))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ module Rexpense
2
+ module Entities
3
+ class Expense < Base
4
+ [:id, :attachments_count, :comments_count, :activities_count,
5
+ :travel_time, :pre_expense_id].each { |n| attribute n, Integer }
6
+
7
+ [:description, :currency, :approved_amount_currency, :kind, :status,
8
+ :distance_kind, :destination, :origin].each { |n| attribute n, String }
9
+
10
+ [:amount, :approved_amount, :latitude, :longitude, :distance,
11
+ :destination_latitude, :destination_longitude, :origin_longitude,
12
+ :origin_latitude].each { |n| attribute n, Decimal }
13
+
14
+ attribute :tags, Array[String]
15
+ attribute :payer, Rexpense::Entities::Organization
16
+ attribute :receiver, Rexpense::Entities::User
17
+ attribute :liquidate_through_advancement, Boolean
18
+ attribute :created_at, DateTime
19
+ attribute :updated_at, DateTime
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ #
4
+ # A wrapper to Expense collection
5
+ #
6
+ class ExpenseCollection < Collection
7
+ def build_collection
8
+ response.parsed_body['expenses'].each do |attributes|
9
+ collection.push(Rexpense::Entities::Expense.new(attributes))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ module Rexpense
2
+ module Entities
3
+ class Membership < Base
4
+ attribute :id, Integer
5
+ attribute :role, String
6
+ attribute :organization, Rexpense::Entities::Organization
7
+ attribute :user, Rexpense::Entities::User
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ #
4
+ # A wrapper to Membership collection
5
+ #
6
+ class MembershipCollection < Collection
7
+ def build_collection
8
+ response.parsed_body['memberships'].each do |attributes|
9
+ collection.push(Rexpense::Entities::Membership.new(attributes))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ class Organization < Base
4
+ attribute :id, Integer
5
+ attribute :name, String
6
+ attribute :restricted_tags, Boolean
7
+ attribute :expired, Boolean
8
+ attribute :members_count, Integer
9
+ attribute :logo, Array[Hash]
10
+
11
+ [:created_at, :updated_at].each { |n| attribute n, String }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ #
4
+ # A wrapper to Organization collection
5
+ #
6
+ class OrganizationCollection < Collection
7
+ def build_collection
8
+ response.parsed_body['organizations'].each do |attributes|
9
+ collection.push(Rexpense::Entities::Organization.new(attributes))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module Rexpense
2
+ module Entities
3
+ class PreExpense < Base
4
+ attribute :id, Integer
5
+ attribute :amount, Decimal
6
+
7
+ [:description, :currency].each { |n| attribute n, String }
8
+
9
+ [:created_at, :converted_at, :updated_at,
10
+ :ignored_at, :occurred_at].each { |n| attribute n, String }
11
+
12
+ attribute :tags, Array[String]
13
+ attribute :payer, Rexpense::Entities::Organization
14
+ attribute :receiver, Rexpense::Entities::User
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ #
4
+ # A wrapper to PreExpense collection
5
+ #
6
+ class PreExpenseCollection < Collection
7
+ def build_collection
8
+ response.parsed_body['pre_expenses'].each do |attributes|
9
+ collection.push(Rexpense::Entities::PreExpense.new(attributes))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ class Reimbursement < Base
4
+ [:id, :comments_count, :activities_count].each { |n| attribute n, Integer }
5
+ [:description, :currency].each { |n| attribute n, String }
6
+ attribute :amount, Decimal
7
+ attribute :tags, Array[String]
8
+ attribute :created_at, DateTime
9
+ attribute :updated_at, DateTime
10
+ attribute :payer, Rexpense::Entities::Organization
11
+ attribute :receiver, Rexpense::Entities::User
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ #
4
+ # A wrapper to Reimbursement collection
5
+ #
6
+ class ReimbursementCollection < Collection
7
+ def build_collection
8
+ response.parsed_body['reimbursements'].each do |attributes|
9
+ collection.push(Rexpense::Entities::Reimbursement.new(attributes))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ module Rexpense
2
+ module Entities
3
+ class Tag < Base
4
+ attribute :id, Integer
5
+ attribute :name, String
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ #
4
+ # A wrapper to Tag collection
5
+ #
6
+ class TagCollection < Collection
7
+ def build_collection
8
+ response.parsed_body['tags'].each do |attributes|
9
+ collection.push(Rexpense::Entities::Tag.new(attributes))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ class User < Base
4
+ attribute :id, Integer
5
+ attribute :first_name, String
6
+ attribute :last_name, String
7
+ attribute :mention_name, String
8
+ attribute :default_currency, String
9
+ attribute :name, String
10
+ attribute :avatar, Array[Hash]
11
+ attribute :default_avatar, Boolean
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ #
4
+ # A wrapper to Tag collection
5
+ #
6
+ class UserCollection < Collection
7
+ def build_collection
8
+ response.parsed_body['participants'].each do |attributes|
9
+ collection.push(Rexpense::Entities::User.new(attributes))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ module Rexpense
2
+ module Entities
3
+ class Webhook < Base
4
+ attribute :id, Integer
5
+ attribute :url, String
6
+ attribute :description, String
7
+ attribute :secret, String
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ module Rexpense
2
+ module Entities
3
+ #
4
+ # A wrapper to Webhooks collection
5
+ #
6
+ class WebhookCollection < Collection
7
+ def build_collection
8
+ response.parsed_body['webhooks'].each do |attributes|
9
+ collection.push(Rexpense::Entities::Webhook.new(attributes))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ module Rexpense
2
+ class Exception < StandardError
3
+ attr_accessor :code, :body
4
+
5
+ def initialize(args = {})
6
+ super(args[:message])
7
+ @code = args[:code]
8
+ @body = args[:body]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ require "rexpense/request"
2
+ require "rexpense/response"
3
+
4
+ module Rexpense
5
+ class Http
6
+ attr_reader :token, :base_url
7
+
8
+ SANDBOX_URL = "https://sandbox.rexpense.com/api"
9
+ PRODUCTION_URL = "https://app.rexpense.com/api"
10
+
11
+ def initialize(token)
12
+ @token = token
13
+ @base_url = api_url + "/#{Rexpense.configuration.version}"
14
+ end
15
+
16
+ %w[get post delete put patch].each do |m|
17
+ define_method(m) do |path, options = {}, &block|
18
+ send_request(m.to_sym, path, options, &block)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def api_url
25
+ return PRODUCTION_URL if Rexpense.configuration.api_mode == 'production'
26
+ SANDBOX_URL
27
+ end
28
+
29
+ def send_request(method, path, options, &block)
30
+ request = Request.new(
31
+ options.merge!(
32
+ method: method,
33
+ token: token,
34
+ url: "#{base_url}#{path}",
35
+ user_agent: Rexpense.configuration.user_agent
36
+ )
37
+ )
38
+ Response.new(request.run).resolve!(&block)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,56 @@
1
+ module Rexpense
2
+ class Request
3
+ def initialize(args)
4
+ @args = args
5
+ end
6
+
7
+ def run
8
+ request.run
9
+ request.response
10
+ end
11
+
12
+ private
13
+
14
+ attr_reader :args
15
+
16
+ def request
17
+ @request ||= Typhoeus::Request.new(args[:url], options)
18
+ end
19
+
20
+ def options
21
+ {
22
+ method: args[:method],
23
+ params: args[:params],
24
+ body: body,
25
+ headers: headers,
26
+ accept_encoding: "gzip",
27
+ params_encoding: :rack
28
+ }.reject { |_k, v| v.nil? }
29
+ end
30
+
31
+ def headers
32
+ headers = args.fetch(:headers) { {} }
33
+
34
+ {
35
+ "Accept" => "application/json",
36
+ "Content-Type" => content_type,
37
+ "User-Agent" => args[:user_agent],
38
+ "Authorization" => "Basic #{authorization_hash}"
39
+ }.merge(headers).delete_if { |_, v| v.nil? || v.to_s.empty? }
40
+ end
41
+
42
+ def body
43
+ body = args[:body]
44
+ body = JSON.dump(body) if body.is_a?(Hash) && !args[:multipart]
45
+ body
46
+ end
47
+
48
+ def authorization_hash
49
+ ::Base64.strict_encode64("#{args[:token]}:X")
50
+ end
51
+
52
+ def content_type
53
+ args[:multipart] ? nil : "application/json"
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,24 @@
1
+ module Rexpense
2
+ module Resources
3
+ #
4
+ # A wrapper to Rexpense activity API
5
+ #
6
+ # [API]
7
+ # Documentation: http://developers.rexpense.com/api/v1/activities/
8
+ #
9
+ class Activity < Base
10
+ #
11
+ # Get user activities
12
+ #
13
+ # [API]
14
+ # Method: <tt>GET /api/v1/activities</tt>
15
+ #
16
+ # Documentation: http://developers.rexpense.com/api/activities#index
17
+ def find_all
18
+ http.get('/activities') do |response|
19
+ Rexpense::Entities::ActivityCollection.build response
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ module Rexpense
2
+ module Resources
3
+ #
4
+ # A wrapper to Rexpense advancements API
5
+ #
6
+ # [API]
7
+ # Documentation: http://developers.rexpense.com/api/v1/advancements/
8
+ #
9
+ class Advancement < ResourceBase
10
+ include Rexpense::Resources::Comment
11
+ include Rexpense::Resources::Participant
12
+
13
+ private
14
+
15
+ def endpoint_base
16
+ "/advancements"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,36 @@
1
+ module Rexpense
2
+ module Resources
3
+ #
4
+ # A wrapper to Rexpense advancement_devolutions API
5
+ #
6
+ # [API]
7
+ # Documentation: http://developers.rexpense.com/api/v1/advancement_devolutions/
8
+ #
9
+ class AdvancementDevolution < Base
10
+
11
+ #
12
+ # Create a resource
13
+ #
14
+ # [API]
15
+ # Method: <tt>POST /api/v1/expenses</tt>
16
+ # Method: <tt>POST /api/v1/advancements</tt>
17
+ # Method: <tt>POST /api/v1/reimbursements</tt>
18
+ #
19
+ # Documentation: http://developers.rexpense.com/api/v1/expenses/#create
20
+ # Documentation: http://developers.rexpense.com/api/v1/advancements/#create
21
+ # Documentation: http://developers.rexpense.com/api/v1/reimbursements/#create
22
+ #
23
+ def create(params)
24
+ http.post("#{endpoint_base}", body: params) do |response|
25
+ respond_with_object response
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def endpoint_base
32
+ "/advancement_devolutions"
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,52 @@
1
+ module Rexpense
2
+ module Resources
3
+ class Base
4
+
5
+ attr_accessor :http
6
+
7
+ def initialize(http)
8
+ @http = http
9
+ end
10
+
11
+ private
12
+
13
+ def build_search_endpoint(params)
14
+ return URI.encode("#{endpoint_base}") if params.empty?
15
+ query_string = uri_query(params).join("&")
16
+ URI.encode("#{endpoint_base}?#{query_string}")
17
+ end
18
+
19
+ def uri_query(params)
20
+ page = params.delete(:page)
21
+ query = []
22
+ params.each { |k, v| query += query_value(k, v) }
23
+ query << "page=#{page}" if page
24
+ query
25
+ end
26
+
27
+ def query_value(key, value)
28
+ [].tap do |query|
29
+ if value.is_a?(Array)
30
+ value.each { |v| query << "q[#{key}][]=#{v}" }
31
+ else
32
+ query << "q[#{key}]=#{value}"
33
+ end
34
+ end
35
+ end
36
+
37
+ def respond_with_collection(response)
38
+ collection_klass = Rexpense::Entities.const_get("#{entity_klass_name}Collection")
39
+ collection_klass.build(response)
40
+ end
41
+
42
+ def respond_with_object(response, key=nil)
43
+ entity_klass = Rexpense::Entities.const_get(entity_klass_name)
44
+ entity_klass.new(response.parsed_body(key))
45
+ end
46
+
47
+ def entity_klass_name
48
+ self.class.to_s.gsub("Resources", "Entities")
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,39 @@
1
+ module Rexpense
2
+ module Resources
3
+ #
4
+ # A wrapper to Rexpense expenses API
5
+ #
6
+ # [API]
7
+ # Documentation: http://developers.rexpense.com/api/v1/expenses/
8
+ #
9
+ class Expense < ResourceBase
10
+ include Rexpense::Resources::Comment
11
+ include Rexpense::Resources::Participant
12
+ include Rexpense::Resources::Attachment
13
+
14
+ def status(id)
15
+ http.get("#{search_endpoint}/#{id}/status") do |response|
16
+ Rexpense::Entities::ExpenseStatus.new response.parsed_body
17
+ end
18
+ end
19
+
20
+ def update_status(id, params)
21
+ http.put("#{search_endpoint}/#{id}/status", body: params) do |response|
22
+ Rexpense::Entities::ExpenseStatus.new response.parsed_body
23
+ end
24
+ end
25
+
26
+ def mentionables(id)
27
+ http.get("#{endpoint_base}/#{id}/mentionables") do |response|
28
+ Rexpense::Entities::UserCollection.build response.parsed_body
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def endpoint_base
35
+ "/expenses"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,48 @@
1
+ module Rexpense::Resources
2
+ module Attachment
3
+ #
4
+ # Get resource attachments
5
+ #
6
+ # [API]
7
+ # Method: <tt>GET /api/v1/expenses/:id/attachments</tt>
8
+ #
9
+ # Documentation: http://developers.rexpense.com/api/attachments#index
10
+ def attachments(resource_id)
11
+ http.get(attachment_endpoint(resource_id)) do |response|
12
+ Rexpense::Entities::AttachmentCollection.build response
13
+ end
14
+ end
15
+
16
+ #
17
+ # Get resource attachment
18
+ #
19
+ # [API]
20
+ # Method: <tt>GET /api/v1/expenses/:id/attachments/:id</tt>
21
+ #
22
+ # Documentation: http://developers.rexpense.com/api/attachments#show
23
+ def find_attachment(resource_id, attachment_id)
24
+ http.get("#{attachment_endpoint(resource_id)}/#{attachment_id}") do |response|
25
+ Rexpense::Entities::Attachment.new response.parsed_body
26
+ end
27
+ end
28
+
29
+ #
30
+ # Destroy resource attachment
31
+ #
32
+ # [API]
33
+ # Method: <tt>DELETE /api/v1/expenses/:id/attachments/:id</tt>
34
+ #
35
+ # Documentation: http://developers.rexpense.com/api/attachments#show
36
+ def destroy_attachment(resource_id, attachment_id)
37
+ http.delete("#{attachment_endpoint(resource_id)}/#{attachment_id}") do |response|
38
+ true
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def attachment_endpoint(resource_id)
45
+ "#{endpoint_base}/#{resource_id}/attachments"
46
+ end
47
+ end
48
+ end