quaderno 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.
Files changed (55) hide show
  1. data/.document +5 -0
  2. data/Gemfile +23 -0
  3. data/Gemfile.lock +53 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.md +264 -0
  6. data/Rakefile +53 -0
  7. data/VERSION +1 -0
  8. data/build_install.sh +2 -0
  9. data/lib/quaderno-ruby/base.rb +71 -0
  10. data/lib/quaderno-ruby/behavior/crud.rb +83 -0
  11. data/lib/quaderno-ruby/behavior/deliver.rb +18 -0
  12. data/lib/quaderno-ruby/behavior/payment.rb +38 -0
  13. data/lib/quaderno-ruby/contact.rb +8 -0
  14. data/lib/quaderno-ruby/estimate.rb +8 -0
  15. data/lib/quaderno-ruby/exceptions/exceptions.rb +42 -0
  16. data/lib/quaderno-ruby/expense.rb +8 -0
  17. data/lib/quaderno-ruby/invoice.rb +9 -0
  18. data/lib/quaderno-ruby/item.rb +4 -0
  19. data/lib/quaderno-ruby/payment.rb +6 -0
  20. data/lib/quaderno-ruby.rb +11 -0
  21. data/quaderno-ruby.gemspec +114 -0
  22. data/test/fixtures/quaderno_cassettes/all_contacts.yml +46 -0
  23. data/test/fixtures/quaderno_cassettes/all_estimates.yml +44 -0
  24. data/test/fixtures/quaderno_cassettes/all_expenses.yml +44 -0
  25. data/test/fixtures/quaderno_cassettes/all_invoices.yml +44 -0
  26. data/test/fixtures/quaderno_cassettes/deleted_contact.yml +127 -0
  27. data/test/fixtures/quaderno_cassettes/deleted_estimate.yml +123 -0
  28. data/test/fixtures/quaderno_cassettes/deleted_expense.yml +123 -0
  29. data/test/fixtures/quaderno_cassettes/deleted_invoice.yml +124 -0
  30. data/test/fixtures/quaderno_cassettes/delivered_estimate.yml +127 -0
  31. data/test/fixtures/quaderno_cassettes/delivered_invoice.yml +127 -0
  32. data/test/fixtures/quaderno_cassettes/found_contact.yml +87 -0
  33. data/test/fixtures/quaderno_cassettes/found_estimate.yml +85 -0
  34. data/test/fixtures/quaderno_cassettes/found_expense.yml +85 -0
  35. data/test/fixtures/quaderno_cassettes/found_invoice.yml +85 -0
  36. data/test/fixtures/quaderno_cassettes/new_contact.yml +44 -0
  37. data/test/fixtures/quaderno_cassettes/new_estimate.yml +87 -0
  38. data/test/fixtures/quaderno_cassettes/new_expense.yml +128 -0
  39. data/test/fixtures/quaderno_cassettes/new_invoice.yml +87 -0
  40. data/test/fixtures/quaderno_cassettes/paid_expense.yml +85 -0
  41. data/test/fixtures/quaderno_cassettes/paid_invoice.yml +86 -0
  42. data/test/fixtures/quaderno_cassettes/rate_limit.yml +44 -0
  43. data/test/fixtures/quaderno_cassettes/unpay_an_expense.yml +123 -0
  44. data/test/fixtures/quaderno_cassettes/unpay_an_invoice.yml +123 -0
  45. data/test/fixtures/quaderno_cassettes/updated_contact.yml +87 -0
  46. data/test/fixtures/quaderno_cassettes/updated_estimate.yml +86 -0
  47. data/test/fixtures/quaderno_cassettes/updated_expense.yml +85 -0
  48. data/test/fixtures/quaderno_cassettes/updated_invoice.yml +86 -0
  49. data/test/helper.rb +27 -0
  50. data/test/test_quaderno-ruby.rb +4 -0
  51. data/test/unit/test_quaderno_contacts.rb +86 -0
  52. data/test/unit/test_quaderno_estimates.rb +99 -0
  53. data/test/unit/test_quaderno_expenses.rb +110 -0
  54. data/test/unit/test_quaderno_invoices.rb +121 -0
  55. metadata +232 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "bundler", ">= 1.0.0"
10
+ gem 'debugger'
11
+ gem 'httparty'
12
+ gem "jeweler", "~> 1.8.4"
13
+ gem "shoulda", ">= 0"
14
+ gem "rcov", "~> 0.9.11" #">= 0"
15
+ gem "rdoc", "~> 3.12"
16
+ gem 'vcr', :require => 'vcr'
17
+ end
18
+
19
+ group :test do
20
+ gem 'debugger', :require => 'ruby-debug'
21
+ gem 'fakeweb'
22
+ gem 'vcr', :require => 'vcr'
23
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,53 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.2.8)
5
+ i18n (~> 0.6)
6
+ multi_json (~> 1.0)
7
+ columnize (0.3.6)
8
+ debugger (1.2.1)
9
+ columnize (>= 0.3.1)
10
+ debugger-linecache (~> 1.1.1)
11
+ debugger-ruby_core_source (~> 1.1.4)
12
+ debugger-linecache (1.1.2)
13
+ debugger-ruby_core_source (>= 1.1.1)
14
+ debugger-ruby_core_source (1.1.4)
15
+ fakeweb (1.3.0)
16
+ git (1.2.5)
17
+ httparty (0.9.0)
18
+ multi_json (~> 1.0)
19
+ multi_xml
20
+ i18n (0.6.1)
21
+ jeweler (1.8.4)
22
+ bundler (~> 1.0)
23
+ git (>= 1.2.5)
24
+ rake
25
+ rdoc
26
+ json (1.7.5)
27
+ multi_json (1.3.6)
28
+ multi_xml (0.5.1)
29
+ rake (0.9.2.2)
30
+ rcov (0.9.11)
31
+ rdoc (3.12)
32
+ json (~> 1.4)
33
+ shoulda (3.1.1)
34
+ shoulda-context (~> 1.0)
35
+ shoulda-matchers (~> 1.2)
36
+ shoulda-context (1.0.0)
37
+ shoulda-matchers (1.3.0)
38
+ activesupport (>= 3.0.0)
39
+ vcr (2.3.0)
40
+
41
+ PLATFORMS
42
+ ruby
43
+
44
+ DEPENDENCIES
45
+ bundler (>= 1.0.0)
46
+ debugger
47
+ fakeweb
48
+ httparty
49
+ jeweler (~> 1.8.4)
50
+ rcov (~> 0.9.11)
51
+ rdoc (~> 3.12)
52
+ shoulda
53
+ vcr
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Carlos Hernandez
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,264 @@
1
+ # Quaderno-ruby
2
+
3
+ Quaderno-ruby is a ruby wrapper for [quaderno api] (https://github.com/recrea/quaderno-api).
4
+
5
+ As the api, it's mostly crud.
6
+
7
+ ## Installation & Configuration
8
+
9
+ To install add the following to your Gemfile:
10
+
11
+ ```ruby
12
+ gem 'quaderno-ruby', require 'quaderno-ruby'
13
+ ```
14
+
15
+ To configure just add this to your initializers
16
+
17
+ ```ruby
18
+ Quaderno::Base.configure do |config|
19
+ config.auth_token = 'my_authenticate_token'
20
+ config.subdomain = 'my_account_subdomain'
21
+ end
22
+ ```
23
+
24
+ ## Ping the service
25
+ You can ping the service in order to check if it is up with:
26
+
27
+ ```ruby
28
+ Quaderno::Base.ping #=> Boolean
29
+ ```
30
+
31
+ This will return true if the service is up or false if it is not.
32
+
33
+ ## Check the rate limit
34
+
35
+ ```ruby
36
+ Quaderno::Base.rate_limit_info #=> { :limit => 100, :remaining => 100 }
37
+ ```
38
+
39
+ This will return a hash with information about the rate limit and your remaining requestes
40
+
41
+ ## Reading the values
42
+
43
+ Quaderno-ruby parses all the json responses in human readable data, so you can access each value just like this:
44
+
45
+ ```ruby
46
+ contact.id
47
+ invoice.items
48
+ estimates.payments
49
+ etc.
50
+ ```
51
+
52
+ ## Managing contacts
53
+
54
+ ### Getting contacts
55
+ ```ruby
56
+ Quaderno::Contact.all(1) #=> Array
57
+ ```
58
+
59
+ will return an array with all your contacts on the first page.
60
+
61
+ ### Finding a contact
62
+ ```ruby
63
+ Quaderno::Contact.find(id) #=> Quaderno::Contact
64
+ ```
65
+
66
+ will return the contact with the id passed as parameter.
67
+
68
+ ### Creating a new contact
69
+ ```ruby
70
+ Quaderno::Contact.create(params) #=> Quaderno::Contact
71
+ ```
72
+
73
+ will create a contact using the information of the hash passed as parameter and return an instance of Quaderno::Contact with the created contact.
74
+
75
+ ### Updating an existing contact
76
+ ```ruby
77
+ Quaderno::Contact.update(id, params) #=> Quaderno::Contact
78
+ ```
79
+
80
+ will update the specified contact with the data of the hash passed as second parameter.
81
+
82
+ ### Deleting a contact
83
+ ```ruby
84
+ Quaderno::Contact.delete(id) #=> Boolean
85
+ ```
86
+
87
+ will delete the contact with the id passed as parameter.
88
+
89
+
90
+ ## Managing invoices
91
+
92
+ ### Getting invoices
93
+ ```ruby
94
+ Quaderno::Invoice.all(1) #=> Array
95
+ ```
96
+
97
+ will return an array with all your invoices on the first page.
98
+
99
+ ### Finding an invoice
100
+ ```ruby
101
+ Quaderno::Invoice.find(id) #=> Quaderno::Invoice
102
+ ```
103
+
104
+ will return the invoice with the id passed as parameter.
105
+
106
+ ### Creating a new invoice
107
+
108
+ ```ruby
109
+ Quaderno::Invoice.create(params) #=> Quaderno::Invoice
110
+ ```
111
+
112
+ will create an invoice using the information of the hash passed as parameter.
113
+
114
+ ### Updating an existing invoice
115
+ ```ruby
116
+ Quaderno::Invoice.update(id, params) #=> Quaderno::Invoice
117
+ ```
118
+
119
+ will update the specified invoice with the data of the hash passed as second parameter.
120
+
121
+ ### Deleting an invoice
122
+
123
+ ```ruby
124
+ Quaderno::Invoice.delete(id) #=> Boolean
125
+ ```
126
+
127
+ will delete the invoice with the id passed as parameter.
128
+
129
+
130
+ ###Adding or removing a payment
131
+ In order to add a payment you will need the Invoice instance you want to update.
132
+
133
+ ```ruby
134
+ invoice = Quaderno::Invoice.find(invoice_id)
135
+ invoice.add_payment(params) #=> Quaderno::Payment
136
+ ```
137
+
138
+ Where params is a hash with the payment information. The method will return the an instance of Quaderno::Payment wich contains the information of the payment.
139
+
140
+ In order to remove a payment you will need the Invoice instance you want to update.
141
+
142
+ ```ruby
143
+ invoice = Quaderno::Invoice.find(invoice_id)
144
+ invoice.remove_payment(payment_id) #=> Boolean
145
+ ```
146
+
147
+ ###Delivering the invoice
148
+
149
+ In order to deliver the estimate to the default recipient you will need the estimate you want to send.
150
+
151
+ ```ruby
152
+ invoice = Quaderno::Invoice.find(invoice_id)
153
+ invoice.deliver
154
+ ```
155
+
156
+
157
+ ## Managing estimates
158
+
159
+
160
+ ### Getting estimates
161
+ ```ruby
162
+ Quaderno::Estimate.all(1) #=> Array
163
+ ```
164
+
165
+ will return an array with all your estimates on the first page.
166
+
167
+ ### Finding an estimate
168
+ ```ruby
169
+ Quaderno::Estimate.find(id) #=> Quaderno::Estimate
170
+ ```
171
+
172
+ will return the estimate with the id passed as parameter.
173
+
174
+ ### Creating a new estimate
175
+
176
+ ```ruby
177
+ Quaderno::Estimate.create(params) #=> Quaderno::Estimate
178
+ ```
179
+
180
+ will create an estimate using the information of the hash passed as parameter.
181
+
182
+ ### Updating an existing estimate
183
+ ```ruby
184
+ Quaderno::Estimate.update(id, params)
185
+ ```
186
+
187
+ will update the specified estimate with the data of the hash passed as second parameter.
188
+
189
+ ### Deleting an estimate
190
+
191
+ ```ruby
192
+ Quaderno::Estimate.delete(id) #=> Boolean
193
+ ```
194
+
195
+ will delete the estimate with the id passed as parameter.
196
+
197
+
198
+ ###Adding or removing a payment
199
+ In order to add a payment you will need the estimate you want to update.
200
+
201
+ ```ruby
202
+ estimate = Quaderno::Estimate.find(estimate_id)
203
+ estimate.add_payment(params) #=> Quaderno::Payment
204
+ ```
205
+
206
+ Where params is a hash with the payment information. The method will return the an instance of Quaderno::Payment wich contains the information of the payment.
207
+
208
+ In order to remove a payment you will need the estimate you want to update.
209
+
210
+ ```ruby
211
+ estimate = Quaderno::Estimate.find(estimate_id)
212
+ estimate.remove_payment(payment_id) #=> Boolean
213
+ ```
214
+
215
+ ###Delivering the estimate
216
+ In order to deliver the estimate to the default recipient you will need the estimate you want to send.
217
+
218
+ ```ruby
219
+ estimate = Quaderno::Estimate.find(estimate_id)
220
+ estimate.deliver
221
+ ```
222
+
223
+
224
+ ## Managing expenses
225
+
226
+ ### Getting expenses
227
+ ```ruby
228
+ Quaderno::Expense.all(1) #=> Array
229
+ ```
230
+
231
+ will return an array with all your expenses on the first page.
232
+
233
+ ### Finding an expense
234
+ ```ruby
235
+ Quaderno::Expense.find(id) #=> Quaderno::Expense
236
+ ```
237
+
238
+ will return the expense with the id passed as parameter.
239
+
240
+ ### Creating a new expense
241
+ ```ruby
242
+ Quaderno::Expense.create(params) #=> Quaderno::Expense
243
+ ```
244
+
245
+ will create an expense using the information of the hash passed as parameter and return an instance of Quaderno::Expense with the created expense.
246
+
247
+ ### Updating an existing expense
248
+ ```ruby
249
+ Quaderno::Expense.update(id, params) #=> Quaderno::Expense
250
+ ```
251
+
252
+ will update the specified expense with the data of the hash passed as second parameter.
253
+
254
+ ### Deleting an expense
255
+ ```ruby
256
+ Quaderno::Expense.delete(id) #=> Boolean
257
+ ```
258
+
259
+ will delete the expense with the id passed as parameter.
260
+
261
+
262
+ ## Quaderno-api
263
+
264
+ For further information, please visit [quaderno api] (https://github.com/recrea/quaderno-api) wiki
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "quaderno"
18
+ gem.homepage = "http://github.com/recrea/quaderno-ruby"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{one-line summary of your gem}
21
+ gem.description = %Q{longer description of your gem}
22
+ gem.email = "carlos@recrea.es"
23
+ gem.authors = ["Recrea"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |test|
37
+ test.libs << 'test'
38
+ test.pattern = 'test/**/test_*.rb'
39
+ test.verbose = true
40
+ test.rcov_opts << '--exclude "gems/*"'
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rdoc/task'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "quaderno-ruby #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/build_install.sh ADDED
@@ -0,0 +1,2 @@
1
+ gem build quaderno-ruby.gemspec
2
+ gem install quaderno-ruby-0.1.1.gem
@@ -0,0 +1,71 @@
1
+ module Quaderno
2
+ require 'httparty'
3
+ require 'json'
4
+
5
+ class Base < OpenStruct
6
+ include HTTParty
7
+ include Quaderno::Exceptions
8
+ include Quaderno::Behavior::Crud
9
+
10
+ base_uri 'https://quadernoapp.com/'
11
+ @@auth_token = nil
12
+ @@subdomain = nil
13
+ @@rate_limit_info = nil
14
+
15
+ def self.api_model(klass)
16
+ instance_eval <<-END
17
+ def api_model
18
+ #{klass}
19
+ end
20
+ END
21
+ class_eval <<-END
22
+ def api_model
23
+ #{klass}
24
+ end
25
+ END
26
+ end
27
+
28
+ #Default way to configure the authenticata data
29
+ def self.configure
30
+ yield self
31
+ end
32
+
33
+ def self.auth_token=(auth_token)
34
+ @@auth_token = auth_token
35
+ end
36
+
37
+ def self.subdomain=(subdomain)
38
+ @@subdomain = subdomain
39
+ end
40
+
41
+ #Check the connection
42
+ def self.ping
43
+ begin
44
+ party_response = get("/#{ subdomain }/api/v1/ping.json", basic_auth: { username: auth_token })
45
+ rescue Errno::ECONNREFUSED
46
+ return false
47
+ end
48
+ true
49
+ end
50
+
51
+ #Returns the rate limit information: limit and remaining requests
52
+ def self.rate_limit_info
53
+ party_response = get("/#{ subdomain }/api/v1/ping.json", basic_auth: { username: auth_token })
54
+ @@rate_limit_info = { limit: party_response.headers["x-ratelimit-limit"].to_i, remaining: party_response.headers["x-ratelimit-remaining"].to_i }
55
+ end
56
+
57
+
58
+ private
59
+ def self.auth_token
60
+ @@auth_token
61
+ end
62
+
63
+ def self.subdomain
64
+ @_subdomain = @@subdomain
65
+ end
66
+ #Set or returns the model path for the url
67
+ def self.api_path(api_path = nil)
68
+ @_api_path ||= api_path
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,83 @@
1
+ require 'ruby-debug'
2
+ module Quaderno
3
+ module Behavior
4
+ module Crud
5
+ def self.included(receiver)
6
+ receiver.send :extend, ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def to_instance(klass, hash)
11
+ klass.new hash
12
+ end
13
+
14
+ def parse(element)
15
+ payments_collection = []
16
+ element['payments'].each do |payment|
17
+ payments_collection << api_model.to_instance(Quaderno::Payment, payment)
18
+ end unless api_model == Quaderno::Estimate
19
+ element['payments'] = payments_collection
20
+
21
+ items_collection = []
22
+ element['items'].each do |item|
23
+ items_collection << api_model.to_instance(Quaderno::Item, item)
24
+ end
25
+ element['items'] = items_collection
26
+
27
+ contact = api_model.to_instance(Quaderno::Contact, element['contact'])
28
+ element['contact'] = contact
29
+ end
30
+
31
+ def all(page_number)
32
+ party_response = get("/#{ api_model.subdomain }/api/v1/#{ api_model.api_path }.json?page=#{page_number}", basic_auth: { username: api_model.auth_token })
33
+ check_exception_for(party_response, { rate_limit: true, subdomain_or_token: true })
34
+ array = JSON::parse party_response.body
35
+ collection = []
36
+ array.each do |element|
37
+ if (api_model == Quaderno::Invoice) || (api_model == Quaderno::Estimate) || (api_model == Quaderno::Expense)
38
+ api_model.parse(element)
39
+ end
40
+ collection << (new element)
41
+ end
42
+ collection
43
+ end
44
+
45
+ def find(id)
46
+ party_response = get "/#{ api_model.subdomain }/api/v1/#{ api_model.api_path }/#{ id }.json", basic_auth: { username: api_model.auth_token }
47
+ check_exception_for(party_response, { rate_limit: true, subdomain_or_token: true, id: true })
48
+ hash = JSON::parse party_response.body
49
+ if (api_model == Quaderno::Invoice) || (api_model == Quaderno::Estimate) || (api_model == Quaderno::Expense)
50
+ api_model.parse(hash)
51
+ end
52
+ new hash
53
+ end
54
+
55
+ def create(params)
56
+ party_response = post "/#{ api_model.subdomain }/api/v1/#{ api_model.api_path }.json", body: params, basic_auth: { username: api_model.auth_token }
57
+ check_exception_for(party_response, { rate_limit: true, subdomain_or_token: true, required_fields: true })
58
+ hash = JSON::parse party_response.body
59
+ if (api_model == Quaderno::Invoice) || (api_model == Quaderno::Estimate) || (api_model == Quaderno::Expense)
60
+ api_model.parse(hash)
61
+ end
62
+ new hash
63
+ end
64
+
65
+ def update(id, params)
66
+ party_response = put "/#{ api_model.subdomain }/api/v1/#{ api_model.api_path }/#{ id }.json", body: params, basic_auth: { username: api_model.auth_token }
67
+ check_exception_for(party_response, { rate_limit: true, subdomain_or_token: true, id: true })
68
+ hash = JSON::parse party_response.body
69
+ if (api_model == Quaderno::Invoice) || (api_model == Quaderno::Estimate) || (api_model == Quaderno::Expense)
70
+ api_model.parse(hash)
71
+ end
72
+ new hash
73
+ end
74
+
75
+ def delete(id)
76
+ party_response = HTTParty.delete "#{ api_model.base_uri }/#{ api_model.subdomain }/api/v1/#{ api_model.api_path }/#{ id }.json", basic_auth: { username: api_model.auth_token }
77
+ check_exception_for(party_response, { rate_limit: true, subdomain_or_token: true, id: true, has_documents: true })
78
+ true
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,18 @@
1
+ module Quaderno
2
+ module Behavior
3
+ module Deliver
4
+
5
+ def self.included(base)
6
+ base.send :include, InstanceMethods
7
+ end
8
+
9
+ module InstanceMethods
10
+ def deliver
11
+ party_response = api_model.get("/#{ api_model.subdomain }/api/v1/#{ api_model.api_path }/#{ id }/deliver.json", basic_auth: { username: api_model.auth_token })
12
+ api_model.check_exception_for(party_response, { rate_limit: true, subdomain_or_token: true, id: true, required_fields: true })
13
+ { limit: party_response.headers["x-ratelimit-limit"].to_i, remaining: party_response.headers["x-ratelimit-remaining"].to_i }
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ module Quaderno
2
+ module Behavior
3
+ module Payment
4
+ def self.included(base)
5
+ base.send :include, InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def to_instance(klass, parsed)
10
+ klass.new(parsed)
11
+ end
12
+
13
+ def add_payment(params)
14
+ party_response = api_model.post "/#{ api_model.subdomain }/api/v1/#{ api_model.api_path }/#{ id }/payments.json", body: params, basic_auth: { username: api_model.auth_token }
15
+ api_model.check_exception_for(party_response, { rate_limit: true, subdomain_or_token: true, required_fields: true })
16
+ parsed = JSON::parse party_response.body
17
+ instance = to_instance(Quaderno::Payment, parsed)
18
+ payments << instance
19
+ Quaderno::Payment.new parsed
20
+ end
21
+
22
+ def remove_payment(payment_id)
23
+ party_response = HTTParty.delete "#{ api_model.base_uri }/#{ api_model.subdomain }/api/v1/#{ api_model.api_path }/#{ id }/payments/#{ payment_id }.json", basic_auth: { username: api_model.auth_token }
24
+ to_delete = nil
25
+ payments.each do |payment|
26
+ if payment.id == payment_id
27
+ to_delete = payment
28
+ break
29
+ end
30
+ end
31
+ payments.delete(to_delete)
32
+ api_model.check_exception_for(party_response, { rate_limit: true, subdomain_or_token: true, id: true })
33
+ true
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,8 @@
1
+ module Quaderno
2
+ class Contact < Base
3
+
4
+ api_model Quaderno::Contact
5
+ api_path 'contacts'
6
+
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Quaderno
2
+ class Estimate < Base
3
+ include Quaderno::Behavior::Deliver
4
+
5
+ api_model Quaderno::Estimate
6
+ api_path 'estimates'
7
+ end
8
+ end