cheddargetter_client_ruby 0.1.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.
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,11 @@
1
+ source "http://rubygems.org"
2
+ gem "httparty", ">= 0.4.3"
3
+
4
+
5
+ group :development do
6
+ gem "shoulda", ">= 0"
7
+ gem "bundler", "~> 1.0.0"
8
+ gem "jeweler", "~> 1.5.1"
9
+ gem "rcov", ">= 0"
10
+ gem "ruby-debug"
11
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ columnize (0.3.2)
5
+ crack (0.1.8)
6
+ git (1.2.5)
7
+ httparty (0.6.1)
8
+ crack (= 0.1.8)
9
+ jeweler (1.5.1)
10
+ bundler (~> 1.0.0)
11
+ git (>= 1.2.5)
12
+ rake
13
+ linecache (0.43)
14
+ rake (0.8.7)
15
+ rcov (0.9.9)
16
+ ruby-debug (0.10.4)
17
+ columnize (>= 0.1)
18
+ ruby-debug-base (~> 0.10.4.0)
19
+ ruby-debug-base (0.10.4)
20
+ linecache (>= 0.3)
21
+ shoulda (2.11.3)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ bundler (~> 1.0.0)
28
+ httparty (>= 0.4.3)
29
+ jeweler (~> 1.5.1)
30
+ rcov
31
+ ruby-debug
32
+ shoulda
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010 Expected Behavior, LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,68 @@
1
+ = Cheddar Getter API Client for Ruby
2
+
3
+ This is a Ruby wrapper for the CheddarGetter[http://cheddargetter.com] API.
4
+ It allows you to interface with the Cheddar Getter API using simple calls, i.e.:
5
+
6
+ client = CheddarGetter::Client.new(:product_code => "YOUR_PRODUCT_CODE",
7
+ :username => "your.username@example.com",
8
+ :password => "your.password")
9
+
10
+ client.new_customer(
11
+ :code => 'EXAMPLE_CUSTOMER',
12
+ :firstName => 'Example',
13
+ :lastName => 'Customer',
14
+ :email => 'example_customer@example.com',
15
+ :subscription => {
16
+ :planCode => 'THE_PLAN_CODE',
17
+ :ccFirstName => 'Example',
18
+ :ccLastName' => 'Customer',
19
+ :ccNumber' => '4111111111111111',
20
+ :ccExpiration => '04/2011',
21
+ :ccZip' => '90210'
22
+ }
23
+ )
24
+
25
+ See the `example` directory for more usage examples.
26
+ It is modeled directly after cheddargetter-client-php[https://github.com/marcguyer/cheddargetter-client-php], the official PHP library, with a number of ruby-isms to make life easier.
27
+
28
+
29
+ == Installation
30
+
31
+ This library should be installed as a gem. It is hosted on Gemcutter[http://gemcutter.org].
32
+
33
+ If you don't have your system set up to use gemcutter, follow the instructions on their site, i.e.:
34
+
35
+ $ gem install gemcutter
36
+ $ gem tumble
37
+
38
+ This will install Gemcutter and set your gem sources to search the gemcutter repos.
39
+
40
+ Then you can install this library as a gem:
41
+
42
+ $ gem install cheddargetter_client_ruby
43
+
44
+
45
+ === Requirements
46
+
47
+ This library requires HTTParty version 0.4.3 or greater.
48
+
49
+ $ gem install httparty
50
+
51
+
52
+ === Usage
53
+
54
+ Simply require this library before you use it:
55
+
56
+ require 'cheddargetter_client_ruby'
57
+
58
+
59
+ If you're using Rails, you could include this gem in your configuration, i.e. in `environment.rb`
60
+
61
+ config.gem 'cheddargetter_client_ruby'
62
+
63
+ Check out the example[https://github.com/expectedbehavior/cheddargetter_client_ruby/tree/master/example] to see usage details. You can also check out the Cheddar Getter API documention[http://cheddargetter.com/developers].
64
+
65
+ == Copyright
66
+
67
+ Copyright (c) 2010 Expected Behavior. See LICENSE.txt for further details.
68
+
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ gem.name = "cheddargetter_client_ruby"
15
+ gem.homepage = "http://github.com/expectedbehavior/cheddargetter_client_ruby"
16
+ gem.license = "MIT"
17
+ gem.summary = "A CheddarGetter API wrapper for Ruby"
18
+ gem.description = "A CheddarGetter API wrapper for Ruby"
19
+ gem.email = "support@expectedbehavior.com"
20
+ gem.authors = ["Expected Behavior"]
21
+ gem.add_runtime_dependency 'httparty', '>= 0.4.3'
22
+ end
23
+ Jeweler::RubygemsDotOrgTasks.new
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/test_*.rb'
29
+ test.verbose = true
30
+ end
31
+
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/test_*.rb'
36
+ test.verbose = true
37
+ end
38
+
39
+ task :default => :test
40
+
41
+ require 'rake/rdoctask'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "cheddargetter_client_ruby #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,79 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{cheddargetter_client_ruby}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Expected Behavior"]
12
+ s.date = %q{2010-12-09}
13
+ s.description = %q{A CheddarGetter API wrapper for Ruby}
14
+ s.email = %q{support@expectedbehavior.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE.txt",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "cheddargetter_client_ruby.gemspec",
28
+ "example/README",
29
+ "example/example.rb",
30
+ "lib/cheddar_getter/client.rb",
31
+ "lib/cheddar_getter/client_exception.rb",
32
+ "lib/cheddar_getter/response.rb",
33
+ "lib/cheddar_getter/response_exception.rb",
34
+ "lib/cheddargetter_client_ruby.rb",
35
+ "test/helper.rb",
36
+ "test/test_cheddargetter_client_ruby.rb"
37
+ ]
38
+ s.homepage = %q{http://github.com/expectedbehavior/cheddargetter_client_ruby}
39
+ s.licenses = ["MIT"]
40
+ s.require_paths = ["lib"]
41
+ s.rubygems_version = %q{1.3.7}
42
+ s.summary = %q{A CheddarGetter API wrapper for Ruby}
43
+ s.test_files = [
44
+ "test/helper.rb",
45
+ "test/test_cheddargetter_client_ruby.rb"
46
+ ]
47
+
48
+ if s.respond_to? :specification_version then
49
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
50
+ s.specification_version = 3
51
+
52
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
53
+ s.add_runtime_dependency(%q<httparty>, [">= 0.4.3"])
54
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
55
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
56
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
57
+ s.add_development_dependency(%q<rcov>, [">= 0"])
58
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
59
+ s.add_runtime_dependency(%q<httparty>, [">= 0.4.3"])
60
+ else
61
+ s.add_dependency(%q<httparty>, [">= 0.4.3"])
62
+ s.add_dependency(%q<shoulda>, [">= 0"])
63
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
64
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
65
+ s.add_dependency(%q<rcov>, [">= 0"])
66
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
67
+ s.add_dependency(%q<httparty>, [">= 0.4.3"])
68
+ end
69
+ else
70
+ s.add_dependency(%q<httparty>, [">= 0.4.3"])
71
+ s.add_dependency(%q<shoulda>, [">= 0"])
72
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
73
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
74
+ s.add_dependency(%q<rcov>, [">= 0"])
75
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
76
+ s.add_dependency(%q<httparty>, [">= 0.4.3"])
77
+ end
78
+ end
79
+
data/example/README ADDED
@@ -0,0 +1,9 @@
1
+ The example script requires modification to work for your purposes.
2
+
3
+ The username, password and productCode must be customized.
4
+
5
+ The script makes use of two different pricing plans:
6
+ * A free plan with code=FREE
7
+ * A paid plan with code=PREMIUM
8
+
9
+ You must either create these pricing plans in the CG admin GUI or substitute your own plan codes
@@ -0,0 +1,122 @@
1
+ require 'rubygems'
2
+ require 'cheddargetter_client_ruby'
3
+
4
+ FREE_PLAN = "FREE"
5
+ PAID_PLAN = "PREMIUM"
6
+
7
+ client = CheddarGetter::Client.new(:product_code => "YOUR_PRODUCT_CODE",
8
+ :username => "your.username@example.com",
9
+ :password => "your.password")
10
+
11
+ puts ""
12
+ puts "********************************************************************"
13
+ puts "** DELETING PREVIOUSLY CREATED EXAMPLE CUSTOMERS **"
14
+ puts "********************************************************************"
15
+
16
+ # delete customers if they're already there
17
+ response = client.delete_all_customers
18
+ if response.valid?
19
+ puts "\tDeleted old customers"
20
+ else
21
+ puts "\tERROR: #{response.error_message}"
22
+ end
23
+
24
+ puts ""
25
+ puts "********************************************************************"
26
+ puts "** CREATE CUSTOMER ON THE FREE PLAN **"
27
+ puts "********************************************************************"
28
+
29
+ # create a customer on a free plan
30
+ data = {
31
+ :code => 'MILTON_WADDAMS',
32
+ :firstName => 'Milton',
33
+ :lastName => 'Waddams',
34
+ :email => 'milt@initech.com',
35
+ :subscription => {
36
+ :planCode => FREE_PLAN
37
+ }
38
+ }
39
+
40
+ response = client.new_customer(data)
41
+ if response.valid?
42
+ puts "\tCreated Milton Waddams with code=MILTON_WADDAMS"
43
+ else
44
+ puts "\tERROR: #{response.error_message}"
45
+ end
46
+
47
+ puts ""
48
+ puts "********************************************************************"
49
+ puts "** SIMULATE ERROR CREATING CUSTOMER ON PAID PLAN **"
50
+ puts "********************************************************************"
51
+
52
+ # try to create a customer on a paid plan (simulated error)
53
+ data = {
54
+ :code => 'BILL_LUMBERG',
55
+ :firstName => 'Bill',
56
+ :lastName => 'Lumberg',
57
+ :email => 'bill@initech.com',
58
+ :subscription => {
59
+ :planCode => PAID_PLAN,
60
+ :ccNumber => '4111111111111111',
61
+ :ccExpiration => '10/2014',
62
+ :ccCardCode => '123',
63
+ :ccFirstName => 'Bill',
64
+ :ccLastName => 'Lumberg',
65
+ :ccZip => '05003' # simulates an error of "Credit card type is not accepted"
66
+ }
67
+ }
68
+
69
+ response = client.new_customer(data)
70
+ if response.valid?
71
+ puts "\tCreated Bill Lumberg with code=BILL_LUMBERG. (This should not have happened)"
72
+ else
73
+ puts "\tExpect Error: #{response.error_message}"
74
+ end
75
+
76
+ puts ""
77
+ puts "********************************************************************"
78
+ puts "** CREATE CUSTOMER ON PAID PLAN AND GET CURRENT **"
79
+ puts "** INVOICE INFORMATION **"
80
+ puts "********************************************************************"
81
+
82
+ data = {
83
+ :code => 'BILL_LUMBERG',
84
+ :firstName => 'Bill',
85
+ :lastName => 'Lumberg',
86
+ :email => 'bill@initech.com',
87
+ :subscription => {
88
+ :planCode => PAID_PLAN,
89
+ :ccNumber => '4111111111111111',
90
+ :ccExpiration => '10/2014',
91
+ :ccCardCode => '123',
92
+ :ccFirstName => 'Bill',
93
+ :ccLastName => 'Lumberg',
94
+ :ccZip => '90210'
95
+ }
96
+ }
97
+
98
+
99
+ response = client.new_customer(data)
100
+ if response.valid?
101
+ puts "\tCreated Bill Lumberg with code=BILL_LUMBERG"
102
+ else
103
+ puts "\tERROR: #{response.error_message}"
104
+ end
105
+
106
+ #get lumberg and display current details
107
+ response = client.get_customer(:code => 'BILL_LUMBERG')
108
+ if response.valid?
109
+ customer = response.customer
110
+ subscription = response.customer_subscription
111
+ plan = response.customer_plan
112
+ invoice = response.customer_invoice
113
+
114
+ puts "\t#{customer[:firstName]} #{customer[:lastName]}"
115
+ puts "\tPricing Plan: #{plan[:name]}"
116
+ puts "\tPending Invoice Scheduled: #{invoice[:billingDatetime].strftime('%m/%d/%Y')}"
117
+ invoice[:charges].each do |charge|
118
+ puts "\t\t(#{charge[:quantity]}) #{charge[:code]} $#{charge[:eachAmount]*charge[:quantity]}"
119
+ end
120
+ else
121
+ puts "\tERROR: #{response.error_message}"
122
+ end
@@ -0,0 +1,385 @@
1
+ module CheddarGetter
2
+ class Client
3
+ include HTTParty
4
+
5
+ base_uri "https://cheddargetter.com/"
6
+ attr_accessor :product_code, :product_id, :username, :password
7
+
8
+ #options:
9
+ #
10
+ #{
11
+ # :username => required, your CheddarGetter username
12
+ # :password => required, your CheddarGetter password
13
+ # :product_id => this or product_code is required
14
+ # :product_code => this or product_id is required
15
+ #}
16
+ def initialize(options = { })
17
+ self.product_code = options[:product_code]
18
+ self.product_id = options[:product_id]
19
+ self.username = options[:username]
20
+ self.password = options[:password]
21
+
22
+ raise CheddarGetter::ClientException.new(":username is required") unless self.username
23
+ raise CheddarGetter::ClientException.new(":password is required") unless self.password
24
+ unless self.product_code || self.product_id
25
+ raise CheddarGetter::ClientException.new(":product_code or :product_id are required")
26
+ end
27
+ end
28
+
29
+ #https://cheddargetter.com/developers#all-plans
30
+ def get_plans
31
+ do_request(:item => :plans, :action => :get)
32
+ end
33
+
34
+ #https://cheddargetter.com/developers#single-plan
35
+ #
36
+ #id_hash: {:code => plan_code} OR {:id => plan_id}
37
+ def get_plan(id_hash = { })
38
+ do_request(:item => :plans, :action => :get, :id_hash => id_hash)
39
+ end
40
+
41
+ #https://cheddargetter.com/developers#all-customers
42
+ #
43
+ #Any, all, or none of this data hash can be given.
44
+ #It just filters the returned customers
45
+ #
46
+ #data:
47
+ #
48
+ #{
49
+ # :subscriptionStatus => "activeOnly" or "canceledOnly",
50
+ # :planCode => plan_code, #can take an array of plan codes
51
+ # :createdAfterDate => date,
52
+ # :createdBeforeDate => date,
53
+ # :canceledAfterDate => date,
54
+ # :canceledBeforeDate => date,
55
+ # :orderBy => "name" (default), "company", "plan", "billingDatetime" or "createdDatetime"
56
+ # :orderByDirection => "asc" (default) or "desc"
57
+ # :search => Tcustomer name, company, email address and last four digits of credit card.
58
+ #}
59
+ def get_customers(data = nil)
60
+ do_request(:item => :customers, :action => :get, :data => data)
61
+ end
62
+
63
+ #https://cheddargetter.com/developers#single-customer
64
+ #
65
+ #id_hash: {:code => customer_code} OR {:id => customer_id}
66
+ def get_customer(id_hash = { })
67
+ do_request(:item => :customers, :action => :get, :id_hash => id_hash)
68
+ end
69
+
70
+ #https://cheddargetter.com/developers#add-customer
71
+ #
72
+ #data:
73
+ #
74
+ #{
75
+ # :code => required,
76
+ # :firstName => required,
77
+ # :lastName => required,
78
+ # :email => required,
79
+ # :company => not_required,
80
+ # :isVatExempt => not_required,
81
+ # :vatNumber => not_required,
82
+ # :notes => not_required,
83
+ # :firstContactDatetime => not_required,
84
+ # :referer => not_required,
85
+ # :campaignTerm => not_required,
86
+ # :campaignName => not_required,
87
+ # :campaignSource => not_required,
88
+ # :campaignMedium => not_required,
89
+ # :campaignContent => not_required,
90
+ # :metaData => { #not_required
91
+ # :any_user_defined_value => not_required
92
+ # },
93
+ # :subscription => { #required
94
+ # :planCode => required,
95
+ # :initialBillDate => not_required,
96
+ # :ccNumber => required_if_not_free,
97
+ # :ccExpiration => required_if_not_free,
98
+ # :ccCardCode => required_if_not_free,
99
+ # :ccFirstName => required_if_not_free,
100
+ # :ccLastName => required_if_not_free,
101
+ # :ccCompany => not_required,
102
+ # :ccCountry => not_required,
103
+ # :ccAddress => not_required,
104
+ # :ccCity => not_required,
105
+ # :ccState => not_required,
106
+ # :ccZip => required_if_not_free
107
+ # },
108
+ # :charges => { #not required
109
+ # :user_defined => {
110
+ # :chargeCode => required_if_adding_a_charge,
111
+ # :quantity => required_if_adding_a_charge,
112
+ # :eachAmount => required_if_adding_a_charge,
113
+ # :description => not_required
114
+ # }
115
+ # },
116
+ # :items => { #not required
117
+ # :user_defined => {
118
+ # :itemCode => required_if_setting_an_item,
119
+ # :quantity => required_if_setting_an_item
120
+ # }
121
+ # }
122
+ #}
123
+ def new_customer(data = { })
124
+ do_request(:item => :customers, :action => :new, :data => data)
125
+ end
126
+
127
+ #https://cheddargetter.com/developers#update-customer-subscription
128
+ #
129
+ #id_hash: {:code => customer_code} OR {:id => customer_id}
130
+ #
131
+ #data:
132
+ #
133
+ #{
134
+ # :firstName => not_required,
135
+ # :lastName => not_required,
136
+ # :email => not_required,
137
+ # :company => not_required,
138
+ # :isVatExempt => not_required,
139
+ # :vatNumber => not_required,
140
+ # :notes => not_required,
141
+ # :firstContactDatetime => not_required,
142
+ # :referer => not_required,
143
+ # :campaignTerm => not_required,
144
+ # :campaignName => not_required,
145
+ # :campaignSource => not_required,
146
+ # :campaignMedium => not_required,
147
+ # :campaignContent => not_required,
148
+ # :metaData => { #not_required
149
+ # :any_user_defined_value => not_required
150
+ # },
151
+ # :subscription => { #not_required
152
+ # :planCode => not_required,
153
+ # :changeBillDate => not_required,
154
+ # :ccNumber => not_required_unless_plan_change_from_free_to_paid,
155
+ # :ccExpiration => not_required_unless_plan_change_from_free_to_paid,
156
+ # :ccCardCode => not_required_unless_plan_change_from_free_to_paid,
157
+ # :ccFirstName => not_required_unless_plan_change_from_free_to_paid,
158
+ # :ccLastName => not_required_unless_plan_change_from_free_to_paid,
159
+ # :ccCompany => not_required,
160
+ # :ccCountry => not_required,
161
+ # :ccAddress => not_required,
162
+ # :ccCity => not_required,
163
+ # :ccState => not_required,
164
+ # :ccZip => not_required_unless_plan_change_from_free_to_paid
165
+ # },
166
+ #}
167
+ def edit_customer(id_hash = { }, data = { })
168
+ do_request(:item => :customers, :action => :edit, :id_hash => id_hash, :data => data)
169
+ end
170
+
171
+ #https://cheddargetter.com/developers#update-customer
172
+ #
173
+ #id_hash: {:code => customer_code} OR {:id => customer_id}
174
+ #
175
+ #data:
176
+ #
177
+ #{
178
+ # :firstName => not_required,
179
+ # :lastName => not_required,
180
+ # :email => not_required,
181
+ # :company => not_required,
182
+ # :notes => not_required,
183
+ # :metaData => { #not_required
184
+ # :any_user_defined_value => not_required
185
+ # },
186
+ #}
187
+ def edit_customer_only(id_hash = { }, data = { })
188
+ do_request(:item => :customers, :action => "edit-customer", :id_hash => id_hash, :data => data)
189
+ end
190
+
191
+ #https://cheddargetter.com/developers#delete-customer
192
+ #
193
+ #id_hash: {:code => customer_code} OR {:id => customer_id}
194
+ def delete_customer(id_hash = { })
195
+ do_request(:item => :customers, :action => :delete, :id_hash => id_hash)
196
+ end
197
+
198
+ #https://cheddargetter.com/developers#delete-all-customers
199
+ def delete_all_customers
200
+ do_request(:item => :customers, :action => "delete-all/confirm/1")
201
+ end
202
+
203
+ #https://cheddargetter.com/developers#update-subscription
204
+ #
205
+ #id_hash: {:code => customer_code} OR {:id => customer_id}
206
+ #
207
+ #data:
208
+ #
209
+ #{
210
+ # :planCode => not_required,
211
+ # :changeBillDate => not_required,
212
+ # :ccNumber => not_required_unless_plan_change_from_free_to_paid,
213
+ # :ccExpiration => not_required_unless_plan_change_from_free_to_paid,
214
+ # :ccCardCode => not_required_unless_plan_change_from_free_to_paid,
215
+ # :ccFirstName => not_required_unless_plan_change_from_free_to_paid,
216
+ # :ccLastName => not_required_unless_plan_change_from_free_to_paid,
217
+ # :ccCompany => not_required,
218
+ # :ccCountry => not_required,
219
+ # :ccAddress => not_required,
220
+ # :ccCity => not_required,
221
+ # :ccState => not_required,
222
+ # :ccZip => not_required_unless_plan_change_from_free_to_paid
223
+ #}
224
+ def edit_subscription(id_hash = { }, data = { })
225
+ do_request(:item => :customers, :action => "edit-subscription", :id_hash => id_hash, :data => data)
226
+ end
227
+
228
+ #https://cheddargetter.com/developers#cancel-subscription
229
+ #
230
+ #id_hash: {:code => customer_code} OR {:id => customer_id}
231
+ def cancel_subscription(id_hash = { })
232
+ do_request(:item => :customers, :action => :cancel, :id_hash => id_hash)
233
+ end
234
+
235
+ #https://cheddargetter.com/developers#add-item-quantity
236
+ #
237
+ #id_hash:
238
+ #
239
+ #{
240
+ # :code => Either code or id are required (this is the customer code)
241
+ # :id => Either code or id are required (this is the customer id)
242
+ # :item_code => Either item code or item id are required
243
+ # :item_id => Either item code or item id are required
244
+ #}
245
+ #
246
+ #data: (not required)
247
+ #
248
+ #{ :quantity => treated_as_1_if_not_set }
249
+ def add_item_quantity(id_hash = { }, data = { })
250
+ do_request(:item => :customers, :action => "add-item-quantity", :id_hash => id_hash,
251
+ :data => data, :add_item_id => true)
252
+ end
253
+
254
+ #https://cheddargetter.com/developers#remove-item-quantity
255
+ #
256
+ #id_hash:
257
+ #
258
+ #{
259
+ # :code => Either code or id are required (this is the customer code)
260
+ # :id => Either code or id are required (this is the customer id)
261
+ # :item_code => Either item code or item id are required
262
+ # :item_id => Either item code or item id are required
263
+ #}
264
+ #
265
+ #data: (not required)
266
+ #
267
+ #{ :quantity => treated_as_1_if_not_set }
268
+ def remove_item_quantity(id_hash = { }, data = { })
269
+ do_request(:item => :customers, :action => "remove-item-quantity", :id_hash => id_hash,
270
+ :data => data, :add_item_id => true)
271
+ end
272
+
273
+ #https://cheddargetter.com/developers#set-item-quantity
274
+ #
275
+ #id_hash:
276
+ #
277
+ #{
278
+ # :code => Either code or id are required (this is the customer code)
279
+ # :id => Either code or id are required (this is the customer id)
280
+ # :item_code => Either item code or item id are required
281
+ # :item_id => Either item code or item id are required
282
+ #}
283
+ #
284
+ #data: { :quantity => required }
285
+ def set_item_quantity(id_hash = { }, data = { })
286
+ do_request(:item => :customers, :action => "set-item-quantity", :id_hash => id_hash,
287
+ :data => data, :add_item_id => true)
288
+ end
289
+
290
+ #https://cheddargetter.com/developers#add-charge
291
+ #
292
+ #id_hash: {:code => customer_code} OR {:id => customer_id}
293
+ #
294
+ #data:
295
+ #
296
+ #{
297
+ # :chargeCode => required,
298
+ # :quantity => required,
299
+ # :eachAmount => required,
300
+ # :description => not_required
301
+ #}
302
+ def add_charge(id_hash = { }, data = { })
303
+ do_request(:item => :customers, :action => "add-charge", :id_hash => id_hash, :data => data)
304
+ end
305
+
306
+ private
307
+ def get_identifier_string(type, id_hash)
308
+ code = type ? "#{type}_code".to_sym : :code
309
+ id = type ? "#{type}_id".to_sym : :id
310
+
311
+ if id_hash[code]
312
+ str = type ? "#{type}Code" : "code"
313
+ "/#{str}/#{CGI.escape(id_hash[code].to_s)}"
314
+ elsif id_hash[id]
315
+ str = type ? "#{type}Id" : "id"
316
+ "/#{str}/#{CGI.escape(id_hash[id].to_s)}"
317
+ else
318
+ raise CheddarGetter::ClientException.new("Either a :#{code} or :#{id} is required")
319
+ end
320
+ end
321
+
322
+ def do_request(options)
323
+ data = options[:data]
324
+ deep_fix_request_data!(data)
325
+
326
+ path = "/xml/#{options[:item]}/#{options[:action]}"
327
+ path += get_identifier_string(nil, options[:id_hash]) if options[:id_hash]
328
+ path += get_identifier_string("item", options[:id_hash]) if options[:add_item_id]
329
+ path += if product_code
330
+ "/productCode/#{CGI.escape(product_code.to_s)}"
331
+ elsif product_id
332
+ "/productId/#{CGI.escape(product_id.to_s)}"
333
+ else
334
+ raise CheddarGetter::ClientException.new("A product code or id is required to make requests.")
335
+ end
336
+
337
+ response = if data
338
+ CheddarGetter::Client.post(path, :body => data, :basic_auth => {
339
+ :username => self.username,
340
+ :password => self.password
341
+ })
342
+ else
343
+ CheddarGetter::Client.get(path, :basic_auth => {
344
+ :username => self.username,
345
+ :password => self.password
346
+ })
347
+ end
348
+
349
+ CheddarGetter::Response.new(response)
350
+ end
351
+
352
+ FIX_UP_KEYS = {
353
+ :ccExpiration => :month_year,
354
+ :isVatExempt => :boolean,
355
+ :initialBillDate => :year_month_day,
356
+ :createdAfterDate => :year_month_day,
357
+ :createdBeforeDate => :year_month_day,
358
+ :canceledAfterDate => :year_month_day,
359
+ :canceledBeforeDate => :year_month_day
360
+ }
361
+
362
+ def deep_fix_request_data!(data)
363
+ if data.is_a?(Array)
364
+ data.each do |v|
365
+ deep_fix_request_data!(v)
366
+ end
367
+ elsif data.is_a?(Hash)
368
+ data.each do |k, v|
369
+ deep_fix_request_data!(v)
370
+ type = FIX_UP_KEYS[k]
371
+ if type
372
+ data[k] = case type
373
+ when :month_year then v.respond_to?(:strftime) ? v.strftime("%m/%Y") : v
374
+ when :boolean then v ? "1" : "0"
375
+ when :year_month_day then v.respond_to?(:strftime) ? v.strftime("%Y/%m/%d") : v
376
+ else v
377
+ end
378
+ end
379
+ end
380
+ end
381
+ end
382
+
383
+ end
384
+ end
385
+