rexpense 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.codeclimate.yml +22 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/.rubocop.yml +54 -0
- data/.travis.yml +9 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +97 -0
- data/LICENSE.txt +21 -0
- data/README.md +195 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/rspec +21 -0
- data/bin/setup +7 -0
- data/lib/rexpense/client.rb +39 -0
- data/lib/rexpense/configuration.rb +13 -0
- data/lib/rexpense/entities/activity.rb +11 -0
- data/lib/rexpense/entities/activity_collection.rb +14 -0
- data/lib/rexpense/entities/advancement.rb +14 -0
- data/lib/rexpense/entities/advancement_collection.rb +14 -0
- data/lib/rexpense/entities/advancement_devolution.rb +13 -0
- data/lib/rexpense/entities/attachment.rb +13 -0
- data/lib/rexpense/entities/attachment_collection.rb +14 -0
- data/lib/rexpense/entities/base.rb +9 -0
- data/lib/rexpense/entities/collection.rb +65 -0
- data/lib/rexpense/entities/comment.rb +13 -0
- data/lib/rexpense/entities/comment_collection.rb +14 -0
- data/lib/rexpense/entities/expense.rb +22 -0
- data/lib/rexpense/entities/expense_collection.rb +14 -0
- data/lib/rexpense/entities/membership.rb +10 -0
- data/lib/rexpense/entities/membership_collection.rb +14 -0
- data/lib/rexpense/entities/organization.rb +14 -0
- data/lib/rexpense/entities/organization_collection.rb +14 -0
- data/lib/rexpense/entities/pre_expense.rb +17 -0
- data/lib/rexpense/entities/pre_expense_collection.rb +14 -0
- data/lib/rexpense/entities/reimbursement.rb +14 -0
- data/lib/rexpense/entities/reimbursement_collection.rb +14 -0
- data/lib/rexpense/entities/tag.rb +8 -0
- data/lib/rexpense/entities/tag_collection.rb +14 -0
- data/lib/rexpense/entities/user.rb +14 -0
- data/lib/rexpense/entities/user_collection.rb +14 -0
- data/lib/rexpense/entities/webhook.rb +10 -0
- data/lib/rexpense/entities/webhook_collection.rb +14 -0
- data/lib/rexpense/exception.rb +11 -0
- data/lib/rexpense/http.rb +41 -0
- data/lib/rexpense/request.rb +56 -0
- data/lib/rexpense/resources/activity.rb +24 -0
- data/lib/rexpense/resources/advancement.rb +20 -0
- data/lib/rexpense/resources/advancement_devolution.rb +36 -0
- data/lib/rexpense/resources/base.rb +52 -0
- data/lib/rexpense/resources/expense.rb +39 -0
- data/lib/rexpense/resources/nested_endpoints/attachment.rb +48 -0
- data/lib/rexpense/resources/nested_endpoints/comment.rb +84 -0
- data/lib/rexpense/resources/nested_endpoints/membership.rb +74 -0
- data/lib/rexpense/resources/nested_endpoints/participant.rb +43 -0
- data/lib/rexpense/resources/organization.rb +31 -0
- data/lib/rexpense/resources/pre_expense.rb +56 -0
- data/lib/rexpense/resources/reimbursement.rb +20 -0
- data/lib/rexpense/resources/resource_base.rb +105 -0
- data/lib/rexpense/resources/tag.rb +82 -0
- data/lib/rexpense/resources/webhook.rb +82 -0
- data/lib/rexpense/response.rb +43 -0
- data/lib/rexpense/version.rb +3 -0
- data/lib/rexpense.rb +19 -0
- data/rexpense.gemspec +48 -0
- data/spec/lib/rexpense/client_spec.rb +47 -0
- data/spec/lib/rexpense/configuration_spec.rb +26 -0
- data/spec/lib/rexpense/entities/activity_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/activity_spec.rb +9 -0
- data/spec/lib/rexpense/entities/advancement_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/advancement_devolution_spec.rb +9 -0
- data/spec/lib/rexpense/entities/advancement_spec.rb +10 -0
- data/spec/lib/rexpense/entities/base_spec.rb +28 -0
- data/spec/lib/rexpense/entities/collection_spec.rb +70 -0
- data/spec/lib/rexpense/entities/comment_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/comment_spec.rb +10 -0
- data/spec/lib/rexpense/entities/expense_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/expense_spec.rb +14 -0
- data/spec/lib/rexpense/entities/membership_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/membership_spec.rb +7 -0
- data/spec/lib/rexpense/entities/organization_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/organization_spec.rb +8 -0
- data/spec/lib/rexpense/entities/pre_expense_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/pre_expense_spec.rb +10 -0
- data/spec/lib/rexpense/entities/reimbursement_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/reimbursement_spec.rb +10 -0
- data/spec/lib/rexpense/entities/user_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/user_spec.rb +10 -0
- data/spec/lib/rexpense/entities/webhook_collection_spec.rb +5 -0
- data/spec/lib/rexpense/entities/webhook_spec.rb +7 -0
- data/spec/lib/rexpense/http_spec.rb +37 -0
- data/spec/lib/rexpense/request_spec.rb +29 -0
- data/spec/lib/rexpense/resources/activity_spec.rb +16 -0
- data/spec/lib/rexpense/resources/advancement_devolution_spec.rb +29 -0
- data/spec/lib/rexpense/resources/advancement_spec.rb +207 -0
- data/spec/lib/rexpense/resources/expense_spec.rb +227 -0
- data/spec/lib/rexpense/resources/organization_spec.rb +162 -0
- data/spec/lib/rexpense/resources/pre_expense_spec.rb +83 -0
- data/spec/lib/rexpense/resources/reimbursement_spec.rb +207 -0
- data/spec/lib/rexpense/resources/tag_specs.rb +77 -0
- data/spec/lib/rexpense/resources/webhook_spec.rb +51 -0
- data/spec/lib/rexpense/response_spec.rb +91 -0
- data/spec/lib/rexpense_spec.rb +34 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/support/attachments/logo.png +0 -0
- data/spec/support/client.rb +3 -0
- data/spec/support/matchers/have_attr_accessor.rb +18 -0
- data/spec/support/shared_examples/entity_attributes.rb +9 -0
- data/spec/support/shared_examples/entity_collection.rb +19 -0
- data/spec/support/shared_examples/http_request_methods.rb +35 -0
- data/spec/support/vcr.rb +7 -0
- 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,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,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,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,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
|