invoicexpress 0.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.
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