invoicexpress 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/CHANGELOG.md +0 -0
  2. data/README.md +322 -0
  3. data/Rakefile +19 -0
  4. data/invoicexpress.gemspec +26 -0
  5. data/lib/faraday/response/parse_xml.rb +23 -0
  6. data/lib/faraday/response/raise_invoicexpress_errors.rb +20 -0
  7. data/lib/invoicexpress.rb +26 -0
  8. data/lib/invoicexpress/authentication.rb +15 -0
  9. data/lib/invoicexpress/client.rb +56 -0
  10. data/lib/invoicexpress/client/cash_invoices.rb +110 -0
  11. data/lib/invoicexpress/client/charts.rb +57 -0
  12. data/lib/invoicexpress/client/clients.rb +215 -0
  13. data/lib/invoicexpress/client/credit_notes.rb +128 -0
  14. data/lib/invoicexpress/client/debit_notes.rb +129 -0
  15. data/lib/invoicexpress/client/invoices.rb +107 -0
  16. data/lib/invoicexpress/client/items.rb +82 -0
  17. data/lib/invoicexpress/client/purchase_orders.rb +126 -0
  18. data/lib/invoicexpress/client/schedules.rb +110 -0
  19. data/lib/invoicexpress/client/sequences.rb +71 -0
  20. data/lib/invoicexpress/client/simplified_invoices.rb +130 -0
  21. data/lib/invoicexpress/client/taxes.rb +82 -0
  22. data/lib/invoicexpress/client/users.rb +48 -0
  23. data/lib/invoicexpress/configuration.rb +51 -0
  24. data/lib/invoicexpress/connection.rb +40 -0
  25. data/lib/invoicexpress/error.rb +68 -0
  26. data/lib/invoicexpress/models.rb +29 -0
  27. data/lib/invoicexpress/models/chart.rb +41 -0
  28. data/lib/invoicexpress/models/client.rb +24 -0
  29. data/lib/invoicexpress/models/filter.rb +60 -0
  30. data/lib/invoicexpress/models/invoice.rb +235 -0
  31. data/lib/invoicexpress/models/purchase_order.rb +72 -0
  32. data/lib/invoicexpress/models/quarterly_result.rb +45 -0
  33. data/lib/invoicexpress/models/schedule.rb +87 -0
  34. data/lib/invoicexpress/models/sequence.rb +17 -0
  35. data/lib/invoicexpress/models/supplier.rb +17 -0
  36. data/lib/invoicexpress/models/top_client.rb +15 -0
  37. data/lib/invoicexpress/models/top_debtor.rb +14 -0
  38. data/lib/invoicexpress/models/user.rb +31 -0
  39. data/lib/invoicexpress/request.rb +63 -0
  40. data/lib/invoicexpress/version.rb +3 -0
  41. data/spec/fixtures/charts.invoicing.xml +21 -0
  42. data/spec/fixtures/charts.quarterly-results.xml +25 -0
  43. data/spec/fixtures/charts.top-clients.xml +10 -0
  44. data/spec/fixtures/charts.top-debtors.xml +10 -0
  45. data/spec/fixtures/charts.treasury.xml +49 -0
  46. data/spec/fixtures/clients.create.xml +6 -0
  47. data/spec/fixtures/clients.get.xml +21 -0
  48. data/spec/fixtures/clients.invoices.xml +11 -0
  49. data/spec/fixtures/clients.list.xml +18 -0
  50. data/spec/fixtures/clients.update.xml +1 -0
  51. data/spec/fixtures/credit_notes.create.xml +53 -0
  52. data/spec/fixtures/credit_notes.email_document.xml +9 -0
  53. data/spec/fixtures/credit_notes.list.xml +114 -0
  54. data/spec/fixtures/credit_notes.update_state.xml +7 -0
  55. data/spec/fixtures/invoices.create.xml +37 -0
  56. data/spec/fixtures/invoices.get.xml +50 -0
  57. data/spec/fixtures/invoices.list.xml +537 -0
  58. data/spec/fixtures/invoices.update_state.xml +7 -0
  59. data/spec/fixtures/ok.xml +0 -0
  60. data/spec/fixtures/po.create.xml +42 -0
  61. data/spec/fixtures/po.email_document.xml +0 -0
  62. data/spec/fixtures/po.get.xml +42 -0
  63. data/spec/fixtures/po.list.xml +44 -0
  64. data/spec/fixtures/po.update_state.xml +7 -0
  65. data/spec/fixtures/schedules.create.xml +48 -0
  66. data/spec/fixtures/schedules.get.xml +57 -0
  67. data/spec/fixtures/schedules.list.xml +40 -0
  68. data/spec/fixtures/sequences.create.xml +9 -0
  69. data/spec/fixtures/sequences.get.xml +10 -0
  70. data/spec/fixtures/sequences.list.xml +12 -0
  71. data/spec/fixtures/sequences.update.xml +10 -0
  72. data/spec/fixtures/simplified_invoices.create.xml +53 -0
  73. data/spec/fixtures/simplified_invoices.email_document.xml +9 -0
  74. data/spec/fixtures/simplified_invoices.get.xml +74 -0
  75. data/spec/fixtures/simplified_invoices.list.xml +114 -0
  76. data/spec/fixtures/simplified_invoices.update.xml +0 -0
  77. data/spec/fixtures/simplified_invoices.update_state.xml +7 -0
  78. data/spec/fixtures/taxes.create.xml +7 -0
  79. data/spec/fixtures/taxes.list.xml +18 -0
  80. data/spec/fixtures/taxes.update.xml +7 -0
  81. data/spec/fixtures/users.accounts.xml +12 -0
  82. data/spec/fixtures/users.change-account.xml +0 -0
  83. data/spec/fixtures/users.login.xml +11 -0
  84. data/spec/helper.rb +62 -0
  85. data/spec/invoicexpress/client/charts_spec.rb +69 -0
  86. data/spec/invoicexpress/client/clients_spec.rb +108 -0
  87. data/spec/invoicexpress/client/credit_notes_spec.rb +104 -0
  88. data/spec/invoicexpress/client/invoices_spec.rb +110 -0
  89. data/spec/invoicexpress/client/purchase_orders_spec.rb +116 -0
  90. data/spec/invoicexpress/client/schedules_spec.rb +111 -0
  91. data/spec/invoicexpress/client/sequences_spec.rb +68 -0
  92. data/spec/invoicexpress/client/simplified_invoices_spec.rb +116 -0
  93. data/spec/invoicexpress/client/taxes_spec.rb +70 -0
  94. data/spec/invoicexpress/client/users_spec.rb +40 -0
  95. data/spec/invoicexpress/client_spec.rb +24 -0
  96. data/spec/invoicexpress_spec.rb +19 -0
  97. metadata +279 -0
@@ -0,0 +1,71 @@
1
+ module Invoicexpress
2
+ class Client
3
+ module Sequences
4
+
5
+ # Returns all your sequences.
6
+ #
7
+ # @return [Array<Invoicexpress::Models::Sequence>] An array with all the sequences
8
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
9
+ def sequences(options = {})
10
+ params = { :klass => Invoicexpress::Models::Sequence }
11
+
12
+ get("sequences.xml", params.merge(options))
13
+ end
14
+
15
+ # Returns a specific sequence.
16
+ #
17
+ # @param sequence [Invoicexpress::Models::Sequence, String] The sequence or sequence ID
18
+ # @return Invoicexpress::Models::Sequence The sequence
19
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
20
+ # @raise Invoicexpress::NotFound When the sequence doesn't exist
21
+ def sequence(sequence, options={})
22
+ params = { :klass => Invoicexpress::Models::Sequence }
23
+
24
+ get("sequences/#{id_from_sequence(sequence)}.xml", params.merge(options))
25
+ end
26
+
27
+ # Creates a new sequence.
28
+ #
29
+ # @param sequence [Invoicexpress::Models::Sequence] The sequence to create
30
+ # @return Invoicexpress::Models::Sequence The sequence
31
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
32
+ # @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
33
+ def create_sequence(sequence, options={})
34
+ raise(ArgumentError, "sequence has the wrong type") unless sequence.is_a?(Invoicexpress::Models::Sequence)
35
+
36
+ params = { :klass => Invoicexpress::Models::Sequence, :body => sequence }
37
+ post("sequences.xml", params.merge(options))
38
+ end
39
+
40
+ # Updates a specific sequence.
41
+ # Only sequences with no finalized invoices can be updated.
42
+ #
43
+ # @param sequence [Invoicexpress::Models::Sequence] The sequence to update
44
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
45
+ # @raise Invoicexpress::NotFound When the sequence doesn't exist
46
+ # @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
47
+ def update_sequence(sequence, options={})
48
+ raise(ArgumentError, "sequence has the wrong type") unless sequence.is_a?(Invoicexpress::Models::Sequence)
49
+ if !sequence.id
50
+ raise ArgumentError, "Sequence ID is required"
51
+ end
52
+ params = { :klass => Invoicexpress::Models::Sequence, :body => sequence }
53
+ put("sequences/#{sequence.id}.xml", params.merge(options))
54
+ end
55
+
56
+ private
57
+ def id_from_sequence(item)
58
+ if item.is_a?(Invoicexpress::Models::Sequence)
59
+ item.id
60
+ elsif item.is_a?(String)
61
+ item
62
+ elsif item.is_a?(Integer)
63
+ item.to_s
64
+ else
65
+ raise ArgumentError, "Cannot get sequence id from #{item}"
66
+ end
67
+ end
68
+
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,130 @@
1
+ require 'invoicexpress/models'
2
+
3
+ module Invoicexpress
4
+ class Client
5
+ module SimplifiedInvoices
6
+
7
+ # Returns all your simplified invoices
8
+ #
9
+ # @option options [Integer] page (1) You can ask a specific page of simplified invoices
10
+ #
11
+ # @return [Invoicexpress::Models::SimplifiedInvoices] A struct with results (pagination) and all the simplified invoices
12
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
13
+ def simplified_invoices(options={})
14
+ params = { :page => 1, :klass => Invoicexpress::Models::SimplifiedInvoice }
15
+
16
+ get("simplified_invoices.xml", params.merge(options))
17
+ end
18
+
19
+
20
+
21
+ # Returns all the information about a simplified invoice:
22
+ # - Basic information (date, status, sequence number)
23
+ # - Client
24
+ # - Document items
25
+ # - Document timeline
26
+ # Document timeline is composed by:
27
+ # - Date, time and the user who created it
28
+ # - Type of the event
29
+ # The complete list of timeline events is:
30
+ # - create
31
+ # - edited
32
+ # - send_email
33
+ # - canceled
34
+ # - deleted
35
+ # - settled
36
+ # - second_copy
37
+ # - archived
38
+ # - unarchived
39
+ # - comment
40
+ #
41
+ # @param simplified_invoice_id [String] Requested simplified invoice id
42
+ # @return [Invoicexpress::Models::SimplifiedInvoice] The requested simplified invoice
43
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
44
+ # @raise Invoicexpress::NotFound When the simplified_invoice doesn't exist
45
+ def simplified_invoice(simplified_invoice_id, options={})
46
+ params = { :klass => Invoicexpress::Models::SimplifiedInvoice }
47
+
48
+ get("simplified_invoices/#{simplified_invoice_id}.xml", params.merge(options))
49
+ end
50
+
51
+ # Creates a new simplified invoice. Also allows to create a new client and/or new items in the same request.
52
+ # If the client name does not exist a new one is created.
53
+ # If items do not exist with the given names, new ones will be created.
54
+ # If item name already exists, the item is updated with the new values.
55
+ # Regarding item taxes, if the tax name is not found, no tax is applyed to that item.
56
+ # Portuguese accounts should also send the IVA exemption reason if the invoice contains exempt items(IVA 0%)
57
+ #
58
+ # @param simplified_invoice [Invoicexpress::Models::SimplifiedInvoice] The simplified invoice to create
59
+ # @return [Invoicexpress::Models::SimplifiedInvoice] The created simplified invoice
60
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
61
+ # @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
62
+ def create_simplified_invoice(simplified_invoice, options={})
63
+ raise(ArgumentError, "simplified invoice has the wrong type") unless simplified_invoice.is_a?(Invoicexpress::Models::SimplifiedInvoice)
64
+
65
+ params = { :klass => Invoicexpress::Models::SimplifiedInvoice, :body => simplified_invoice }
66
+ post("simplified_invoices.xml", params.merge(options))
67
+ end
68
+
69
+ # Updates a simplified invoice
70
+ # It also allows you to create a new client and/or items in the same request.
71
+ # If the client name does not exist a new client is created.
72
+ # Regarding item taxes, if the tax name is not found, no tax will be applied to that item.
73
+ # If item does not exist with the given name, a new one will be created.
74
+ # If item exists it will be updated with the new values
75
+ # Be careful when updating the document items, any missing items from the original document will be deleted.
76
+ #
77
+ # @param simplified_invoice [Invoicexpress::Models::SimplifiedInvoice] The cash simplified invoice to update
78
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
79
+ # @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
80
+ # @raise Invoicexpress::NotFound When the simplified invoice doesn't exist
81
+ def update_simplified_invoice(simplified_invoice, options={})
82
+ raise(ArgumentError, "simplified invoice has the wrong type") unless simplified_invoice.is_a?(Invoicexpress::Models::SimplifiedInvoice)
83
+ if !simplified_invoice.id
84
+ raise ArgumentError, "Invoice ID is required"
85
+ end
86
+ params = { :klass => Invoicexpress::Models::SimplifiedInvoice, :body => simplified_invoice.to_core }
87
+ put("simplified_invoices/#{simplified_invoice.id}.xml", params.merge(options))
88
+ end
89
+
90
+ # Changes the state of a simplified invoice.
91
+ # Possible state transitions:
92
+ # - draft to final – finalized
93
+ # - draft to deleted – deleted
94
+ # - settled to final – unsettled
95
+ # - final to second copy – second_copy
96
+ # - final or second copy to canceled – canceled
97
+ # - final or second copy to settled – settled
98
+ # Any other transitions will fail.
99
+ # When canceling a simplified invoice you must specify a reason.
100
+ #
101
+ # @param simplified_invoice_id [String] The simplified invoice id to change
102
+ # @param simplified_invoice_state [Invoicexpress::Models::InvoiceState] The new state
103
+ # @return [Invoicexpress::Models::SimplifiedInvoice] The updated simplified invoice
104
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
105
+ # @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
106
+ # @raise Invoicexpress::NotFound When the simplified invoice doesn't exist
107
+ def update_simplified_invoice_state(simplified_invoice_id, simplified_invoice_state, options={})
108
+ raise(ArgumentError, "simplified invoice state has the wrong type") unless simplified_invoice_state.is_a?(Invoicexpress::Models::InvoiceState)
109
+
110
+ params = { :klass => Invoicexpress::Models::SimplifiedInvoice, :body => simplified_invoice_state }
111
+ put("simplified_invoices/#{simplified_invoice_id}/change-state.xml", params.merge(options))
112
+ end
113
+
114
+ # Sends the simplified invoice through email
115
+ #
116
+ # @param simplified_invoice_id [String] The simplified invoice id to send
117
+ # @param message [Invoicexpress::Models::Message] The message to send
118
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
119
+ # @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
120
+ # @raise Invoicexpress::NotFound When the simplified invoice doesn't exist
121
+ def simplified_invoice_mail(simplified_invoice_id, message, options={})
122
+ raise(ArgumentError, "message has the wrong type") unless message.is_a?(Invoicexpress::Models::Message)
123
+
124
+ params = { :body => message, :klass => Invoicexpress::Models::SimplifiedInvoice }
125
+ put("simplified_invoices/#{simplified_invoice_id}/email-document.xml", params.merge(options))
126
+ end
127
+
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,82 @@
1
+ module Invoicexpress
2
+ class Client
3
+ module Taxes
4
+
5
+ # Returns all your taxes (lol)
6
+ #
7
+ # @return [Array<Invoicexpress::Models::Tax>] An array with all your taxes
8
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
9
+ def taxes(options = {})
10
+ params = { :klass => Invoicexpress::Models::Tax }
11
+
12
+ get("taxes.xml", params.merge(options))
13
+ end
14
+
15
+ # Returns a specific tax.
16
+ #
17
+ # @param tax [Invoicexpress::Models::Tax, String] The tax or tax ID
18
+ # @return Invoicexpress::Models::Tax The tax
19
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
20
+ # @raise Invoicexpress::NotFound When the tax doesn't exist
21
+ def tax(tax, options={})
22
+ params = { :klass => Invoicexpress::Models::Tax }
23
+
24
+ get("taxes/#{id_from_tax(tax)}.xml", params.merge(options))
25
+ end
26
+
27
+ # Creates a tax.
28
+ #
29
+ # @param tax [Invoicexpress::Models::Tax] The tax to create
30
+ # @return Invoicexpress::Models::Tax The tax created
31
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
32
+ # @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
33
+ def create_tax(tax, options={})
34
+ raise(ArgumentError, "tax has the wrong type") unless tax.is_a?(Invoicexpress::Models::Tax)
35
+
36
+ params = { :klass => Invoicexpress::Models::Tax, :body => tax }
37
+ post("taxes.xml", params.merge(options))
38
+ end
39
+
40
+ # Updates a tax.
41
+ #
42
+ # @param tax [Invoicexpress::Models::Tax] The tax to update
43
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
44
+ # @raise Invoicexpress::NotFound When the tax doesn't exist
45
+ # @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
46
+ def update_tax(tax, options={})
47
+ raise(ArgumentError, "tax has the wrong type") unless tax.is_a?(Invoicexpress::Models::Tax)
48
+
49
+ if !tax.id
50
+ raise ArgumentError, "Tax ID is required"
51
+ end
52
+ params = { :klass => Invoicexpress::Models::Tax, :body => tax }
53
+ put("taxes/#{tax.id}.xml", params.merge(options))
54
+ end
55
+
56
+ # Deletes a tax.
57
+ #
58
+ # @param tax [Invoicexpress::Models::Tax, String] The tax or tax ID
59
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
60
+ # @raise Invoicexpress::NotFound When the tax doesn't exist
61
+ def delete_tax(tax, options={})
62
+ params = { :klass => Invoicexpress::Models::Tax }
63
+
64
+ delete("taxes/#{id_from_tax(tax)}.xml", params.merge(options))
65
+ end
66
+
67
+ private
68
+ def id_from_tax(item)
69
+ if item.is_a?(Invoicexpress::Models::Tax)
70
+ item.id
71
+ elsif item.is_a?(String)
72
+ item
73
+ elsif item.is_a?(Integer)
74
+ item.to_s
75
+ else
76
+ raise ArgumentError, "Cannot get tax id from #{item}"
77
+ end
78
+ end
79
+
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,48 @@
1
+ module Invoicexpress
2
+ class Client
3
+ module Users
4
+
5
+ # This endpoint does not require an API KEY to be acessible.
6
+ # Instead it requires your current login and password.
7
+ # Upon successful login it will return all the accounts which belong to you
8
+ #
9
+ # @param login [String] Login email
10
+ # @param password [String] Your password
11
+ # @return [Array<Invoicexpress::Models::Account>] The list of your accounts
12
+ # @raise Invoicexpress::Unauthorized When the login/password combination is wrong
13
+ def login(login, password, options={})
14
+ credentials = Invoicexpress::Models::Credentials.new(
15
+ :login => login,
16
+ :password => password
17
+ )
18
+
19
+ params = { :klass => Invoicexpress::Models::Account, :body => credentials }
20
+ post("login.xml", params.merge(options))
21
+ end
22
+
23
+ # This method allows you to view your accounts.
24
+ #
25
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
26
+ # @return [Array<Invoicexpress::Models::Account>] The list of accounts
27
+ def accounts(options = {})
28
+ params = { :klass => Invoicexpress::Models::Account }
29
+ get("users/accounts.xml", params.merge(options))
30
+ end
31
+
32
+ # Changes the current account to the account id submitte
33
+ #
34
+ # @param account_id [String] The account ID to change to
35
+ # @raise Invoicexpress::Unauthorized When the client is unauthorized
36
+ # @raise Invoicexpress::NotFound When the account doesn't exist
37
+ def change_account(account_id, options={})
38
+ change_account_to = Invoicexpress::Models::ChangeAccountTo.new(
39
+ :id => account_id
40
+ )
41
+
42
+ params = { :klass => Invoicexpress::Models::Account, :body => change_account_to }
43
+ put("users/change-account.xml", params.merge(options))
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,51 @@
1
+ require 'faraday'
2
+ require 'invoicexpress/version'
3
+
4
+ module Invoicexpress
5
+ module Configuration
6
+ VALID_OPTIONS_KEYS = [
7
+ :adapter,
8
+ :faraday_config_block,
9
+ :api_endpoint,
10
+ :screen_name,
11
+ :proxy,
12
+ :api_key,
13
+ :user_agent
14
+ ].freeze
15
+
16
+ DEFAULT_ADAPTER = Faraday.default_adapter
17
+ DEFAULT_API_ENDPOINT = ENV['INVOICEXPRESS_API_ENDPOINT'] || 'https://%s.invoicexpress.net/'
18
+ DEFAULT_USER_AGENT = "Invoicexpress Ruby Gem #{Invoicexpress::VERSION}".freeze
19
+
20
+ attr_accessor(*VALID_OPTIONS_KEYS)
21
+
22
+ def self.extended(base)
23
+ base.reset
24
+ end
25
+
26
+ def configure
27
+ yield self
28
+ end
29
+
30
+ def options
31
+ VALID_OPTIONS_KEYS.inject({}) { |o,k| o.merge!(k => send(k)) }
32
+ end
33
+
34
+ def api_endpoint=(value)
35
+ @api_endpoint = File.join(value, "")
36
+ end
37
+
38
+ def faraday_config(&block)
39
+ @faraday_config_block = block
40
+ end
41
+
42
+ def reset
43
+ self.adapter = DEFAULT_ADAPTER
44
+ self.api_endpoint = DEFAULT_API_ENDPOINT
45
+ self.user_agent = DEFAULT_USER_AGENT
46
+ self.api_key = nil
47
+ self.screen_name = nil
48
+ self.proxy = nil
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,40 @@
1
+ require 'faraday_middleware'
2
+ require 'faraday/response/parse_xml'
3
+ require 'faraday/response/raise_invoicexpress_errors'
4
+
5
+ module Invoicexpress
6
+ # @private
7
+ module Connection
8
+ private
9
+
10
+ def connection(options={})
11
+ klass = options.delete(:klass)
12
+
13
+ options = {
14
+ :raw => false,
15
+ :ssl => { :verify => false }
16
+ }.merge(options)
17
+
18
+ if !proxy.nil?
19
+ options.merge!(:proxy => proxy)
20
+ end
21
+
22
+ options.merge!(:params => authentication)
23
+
24
+ connection = Faraday.new(options) do |builder|
25
+ builder.request :url_encoded
26
+
27
+ builder.use FaradayMiddleware::FollowRedirects
28
+ builder.use Faraday::Response::ParseXML, klass
29
+ builder.use Faraday::Response::RaiseInvoicexpressErrors
30
+
31
+ faraday_config_block.call(builder) if faraday_config_block
32
+ builder.adapter *adapter
33
+ end
34
+
35
+ connection.headers[:user_agent] = user_agent
36
+ connection
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,68 @@
1
+ require 'happymapper'
2
+
3
+ module Invoicexpress
4
+ module Models
5
+ class Errors
6
+ include HappyMapper
7
+
8
+ has_many :error, String
9
+ alias :errors :error
10
+ end
11
+ end
12
+
13
+ # Custom error class for rescuing from all Invoicexpress errors
14
+ #
15
+ class Error < StandardError
16
+ attr_accessor :messages
17
+
18
+ def initialize(response=nil)
19
+ @response = response
20
+ @messages = []
21
+
22
+ super(build_error_message)
23
+ end
24
+
25
+ def response_body
26
+ @response_body ||=
27
+ if (body = @response[:body]) && !body.empty?
28
+ if body.is_a?(String) and body.start_with?("<")
29
+ Invoicexpress::Models::Errors.parse(body)
30
+ else
31
+ body
32
+ end
33
+ else
34
+ nil
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def build_error_message
41
+ return nil if @response.nil?
42
+
43
+ message = if response_body
44
+ if response_body.respond_to?(:errors)
45
+ ": " + response_body.errors.join(", ")
46
+ else
47
+ ": " + response_body
48
+ end
49
+ else
50
+ ''
51
+ end
52
+
53
+ "#{@response[:method].to_s.upcase} #{@response[:url].to_s}: #{@response[:status]}#{message}"
54
+ end
55
+ end
56
+
57
+ # Raised when Invoicexpress returns a 401 HTTP status code
58
+ class Unauthorized < Error; end
59
+
60
+ # Raised when Invoicexpress returns a 404 HTTP status code
61
+ class NotFound < Error; end
62
+
63
+ # Raised when Invoicexpress returns a 422 HTTP status code
64
+ class UnprocessableEntity < Error; end
65
+
66
+ # Raised when Invoicexpress server goes dark (500 HTTP status code)
67
+ class InternalServerError < Error; end
68
+ end