quaderno 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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