servicemerchant 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/MIT-LICENSE.txt +20 -0
  2. data/README.txt +231 -0
  3. data/Rakefile +122 -0
  4. data/demo.rb +69 -0
  5. data/recurring_billing/lib/am_extensions.rb +1 -0
  6. data/recurring_billing/lib/am_extensions/paypal_extension.rb +170 -0
  7. data/recurring_billing/lib/dependencies.rb +14 -0
  8. data/recurring_billing/lib/gateways.rb +5 -0
  9. data/recurring_billing/lib/gateways/authorize_net.rb +103 -0
  10. data/recurring_billing/lib/gateways/paypal.rb +124 -0
  11. data/recurring_billing/lib/recurring_billing.rb +130 -0
  12. data/recurring_billing/lib/recurring_billing.rdoc +87 -0
  13. data/recurring_billing/lib/utils.rb +81 -0
  14. data/recurring_billing/test/fixtures.yml +33 -0
  15. data/recurring_billing/test/remote/authorize_net_test.rb +36 -0
  16. data/recurring_billing/test/remote/paypal_test.rb +46 -0
  17. data/recurring_billing/test/remote/recurring_billing_test.rb +41 -0
  18. data/recurring_billing/test/test_helper.rb +153 -0
  19. data/recurring_billing/test/unit/authorize_net_gateway_class_test.rb +42 -0
  20. data/recurring_billing/test/unit/paypal_gateway_class_test.rb +23 -0
  21. data/recurring_billing/test/unit/recurring_billing_gateway_class_test.rb +35 -0
  22. data/recurring_billing/test/unit/utils_test.rb +17 -0
  23. data/subscription_management/Rakefile +29 -0
  24. data/subscription_management/lib/models/subscription.rb +9 -0
  25. data/subscription_management/lib/models/subscription_profile.rb +4 -0
  26. data/subscription_management/lib/subscription_management.rb +326 -0
  27. data/subscription_management/samples/backpack.yml +101 -0
  28. data/subscription_management/samples/basecamp.yml +71 -0
  29. data/subscription_management/samples/brainkeeper.yml +90 -0
  30. data/subscription_management/samples/campfire.yml +74 -0
  31. data/subscription_management/samples/clickandpledge.yml +24 -0
  32. data/subscription_management/samples/demo.rb +19 -0
  33. data/subscription_management/samples/elm.yml +174 -0
  34. data/subscription_management/samples/freshbooks.yml +78 -0
  35. data/subscription_management/samples/highrise.yml +100 -0
  36. data/subscription_management/samples/presets.yml +10 -0
  37. data/subscription_management/samples/tariff.outline.yml +0 -0
  38. data/subscription_management/samples/taxes.yml +21 -0
  39. data/subscription_management/subscription_management.rb +7 -0
  40. data/subscription_management/tasks/schema.rb +50 -0
  41. data/subscription_management/test/connection.rb +10 -0
  42. data/subscription_management/test/remote/subscription_management_test.rb +112 -0
  43. data/subscription_management/test/test_helper.rb +84 -0
  44. data/subscription_management/test/unit/subscription_management_test.rb +40 -0
  45. data/tracker/README +12 -0
  46. data/tracker/Rakefile +40 -0
  47. data/tracker/db/migrations/empty-directory +0 -0
  48. data/tracker/demo.rb +12 -0
  49. data/tracker/lib/models/recurring_payment_profile.rb +134 -0
  50. data/tracker/lib/models/transaction.rb +19 -0
  51. data/tracker/lib/recurring_billing_extension.rb +103 -0
  52. data/tracker/lib/recurring_billing_extension.rdoc +34 -0
  53. data/tracker/tasks/schema.rb +66 -0
  54. data/tracker/test/connection.rb +10 -0
  55. data/tracker/test/recurring_payment_profile.rb +35 -0
  56. data/tracker/test/remote/authorize_net_test.rb +68 -0
  57. data/tracker/test/remote/paypal_test.rb +115 -0
  58. data/tracker/test/test_helper.rb +87 -0
  59. data/tracker/test/unit/recurring_payment_profile_test.rb +62 -0
  60. data/tracker/tracker.rb +10 -0
  61. data/vendor/money-1.7.1/MIT-LICENSE +20 -0
  62. data/vendor/money-1.7.1/README +75 -0
  63. data/vendor/money-1.7.1/lib/bank/no_exchange_bank.rb +9 -0
  64. data/vendor/money-1.7.1/lib/bank/variable_exchange_bank.rb +30 -0
  65. data/vendor/money-1.7.1/lib/money.rb +29 -0
  66. data/vendor/money-1.7.1/lib/money/core_extensions.rb +26 -0
  67. data/vendor/money-1.7.1/lib/money/money.rb +209 -0
  68. data/vendor/money-1.7.1/lib/support/cattr_accessor.rb +57 -0
  69. metadata +153 -0
@@ -0,0 +1,9 @@
1
+ class NoExchangeBank# :nodoc:
2
+
3
+ def reduce(money, currency)
4
+ return money if money.currency == currency
5
+ raise Money::MoneyError.new("Current Money::bank does not support money exchange. Please implement a bank object that does and assign it to the Money class.")
6
+ end
7
+
8
+
9
+ end
@@ -0,0 +1,30 @@
1
+ # Example useage:
2
+ #
3
+ # Money.bank = VariableExchangeBank.new
4
+ # Money.bank.add_rate("USD", "CAD", 1.24515)
5
+ # Money.bank.add_rate("CAD", "USD", 0.803115)
6
+ # Money.us_dollar(100).exchange_to("CAD") => Money.ca_dollar(124)
7
+ # Money.ca_dollar(100).exchange_to("USD") => Money.us_dollar(80)
8
+ class VariableExchangeBank
9
+
10
+ def add_rate(from, to, rate)
11
+ rates["#{from}_TO_#{to}".upcase] = rate
12
+ end
13
+
14
+ def get_rate(from, to)
15
+ rates["#{from}_TO_#{to}".upcase]
16
+ end
17
+
18
+ def reduce(money, currency)
19
+ rate = get_rate(money.currency, currency) or raise Money::MoneyError.new("Can't find required exchange rate")
20
+
21
+ Money.new((money.cents * rate).floor, currency)
22
+ end
23
+
24
+ private
25
+
26
+ def rates
27
+ @rates ||= {}
28
+ end
29
+
30
+ end
@@ -0,0 +1,29 @@
1
+ #--
2
+ # Copyright (c) 2005 Tobias Luetke
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+
25
+ require File.dirname(__FILE__) + '/support/cattr_accessor'
26
+ require File.dirname(__FILE__) + '/bank/no_exchange_bank'
27
+ require File.dirname(__FILE__) + '/bank/variable_exchange_bank'
28
+ require File.dirname(__FILE__) + '/money/money'
29
+ require File.dirname(__FILE__) + '/money/core_extensions'
@@ -0,0 +1,26 @@
1
+ # Allows Writing of 100.to_money for +Numeric+ types
2
+ # 100.to_money => #<Money @cents=10000>
3
+ # 100.37.to_money => #<Money @cents=10037>
4
+ class Numeric
5
+ def to_money
6
+ Money.new(self * 100)
7
+ end
8
+ end
9
+
10
+ # Allows Writing of '100'.to_money for +String+ types
11
+ # Excess characters will be discarded
12
+ # '100'.to_money => #<Money @cents=10000>
13
+ # '100.37'.to_money => #<Money @cents=10037>
14
+ class String
15
+ def to_money
16
+ # Get the currency
17
+ matches = scan /([A-Z]{2,3})/
18
+ currency = matches[0] ? matches[0][0] : Money.default_currency
19
+
20
+ # Get the cents amount
21
+ matches = scan /(\-?\d+(\.(\d+))?)/
22
+ cents = matches[0] ? (matches[0][0].to_f * 100) : 0
23
+
24
+ Money.new(cents, currency)
25
+ end
26
+ end
@@ -0,0 +1,209 @@
1
+ # === Usage with ActiveRecord
2
+ #
3
+ # Use the compose_of helper to let active record deal with embedding the money
4
+ # object in your models. The following example requires a cents and a currency field.
5
+ #
6
+ # class ProductUnit < ActiveRecord::Base
7
+ # belongs_to :product
8
+ # composed_of :price, :class_name => "Money", :mapping => [ %w(cents cents), %w(currency currency) ]
9
+ #
10
+ # private
11
+ # validate :cents_not_zero
12
+ #
13
+ # def cents_not_zero
14
+ # errors.add("cents", "cannot be zero or less") unless cents > 0
15
+ # end
16
+ #
17
+ # validates_presence_of :sku, :currency
18
+ # validates_uniqueness_of :sku
19
+ # end
20
+ #
21
+ class Money
22
+ include Comparable
23
+
24
+ attr_reader :cents, :currency
25
+
26
+ class MoneyError < StandardError# :nodoc:
27
+ end
28
+
29
+ # Bank lets you exchange the object which is responsible for currency
30
+ # exchange.
31
+ # The default implementation just throws an exception. However money
32
+ # ships with a variable exchange bank implementation which supports
33
+ # custom excahnge rates:
34
+ #
35
+ # Money.bank = VariableExchangeBank.new
36
+ # Money.bank.add_rate("USD", "CAD", 1.24515)
37
+ # Money.bank.add_rate("CAD", "USD", 0.803115)
38
+ # Money.us_dollar(100).exchange_to("CAD") => Money.ca_dollar(124)
39
+ # Money.ca_dollar(100).exchange_to("USD") => Money.us_dollar(80)
40
+ @@bank = NoExchangeBank.new
41
+ cattr_accessor :bank
42
+
43
+ @@default_currency = "USD"
44
+ cattr_accessor :default_currency
45
+
46
+ # Creates a new money object.
47
+ # Money.new(100)
48
+ #
49
+ # Alternativly you can use the convinience methods like
50
+ # Money.ca_dollar and Money.us_dollar
51
+ def initialize(cents, currency = default_currency)
52
+ @cents, @currency = cents.round, currency
53
+ end
54
+
55
+ # Do two money objects equal? Only works if both objects are of the same currency
56
+ def eql?(other_money)
57
+ cents == other_money.cents && currency == other_money.currency
58
+ end
59
+
60
+ def <=>(other_money)
61
+ if currency == other_money.currency
62
+ cents <=> other_money.cents
63
+ else
64
+ cents <=> other_money.exchange_to(currency).cents
65
+ end
66
+ end
67
+
68
+ def +(other_money)
69
+ return other_money.dup if cents.zero?
70
+ return dup if other_money.cents.zero?
71
+
72
+ if currency == other_money.currency
73
+ Money.new(cents + other_money.cents, other_money.currency)
74
+ else
75
+ Money.new(cents + other_money.exchange_to(currency).cents,currency)
76
+ end
77
+ end
78
+
79
+ def -(other_money)
80
+
81
+ if currency == other_money.currency
82
+ Money.new(cents - other_money.cents, other_money.currency)
83
+ else
84
+
85
+ return other_money.dup if self.cents.zero?
86
+
87
+ return self.dup if other_money.cents.zero?
88
+
89
+
90
+ Money.new(cents - other_money.exchange_to(currency).cents, currency)
91
+
92
+ end
93
+ end
94
+
95
+ # get the cents value of the object
96
+ def cents
97
+ @cents.to_i
98
+ end
99
+
100
+ # multiply money by fixnum
101
+ def *(fixnum)
102
+ Money.new(cents * fixnum, currency)
103
+ end
104
+
105
+ # divide money by fixnum
106
+ def /(fixnum)
107
+ Money.new(cents / fixnum, currency)
108
+ end
109
+
110
+ # Test if the money amount is zero
111
+ def zero?
112
+ cents == 0
113
+ end
114
+
115
+
116
+ # Format the price according to several rules
117
+ # Currently supported are :with_currency, :no_cents and :html
118
+ #
119
+ # with_currency:
120
+ #
121
+ # Money.ca_dollar(0).format => "free"
122
+ # Money.ca_dollar(100).format => "$1.00"
123
+ # Money.ca_dollar(100).format(:with_currency) => "$1.00 CAD"
124
+ # Money.us_dollar(85).format(:with_currency) => "$0.85 USD"
125
+ #
126
+ # no_cents:
127
+ #
128
+ # Money.ca_dollar(100).format(:no_cents) => "$1"
129
+ # Money.ca_dollar(599).format(:no_cents) => "$5"
130
+ #
131
+ # Money.ca_dollar(570).format(:no_cents, :with_currency) => "$5 CAD"
132
+ # Money.ca_dollar(39000).format(:no_cents) => "$390"
133
+ #
134
+ # html:
135
+ #
136
+ # Money.ca_dollar(570).format(:html, :with_currency) => "$5.70 <span class=\"currency\">CAD</span>"
137
+ def format(*rules)
138
+ return "free" if cents == 0
139
+
140
+ rules = rules.flatten
141
+
142
+ if rules.include?(:no_cents)
143
+ formatted = sprintf("$%d", cents.to_f / 100 )
144
+ else
145
+ formatted = sprintf("$%.2f", cents.to_f / 100 )
146
+ end
147
+
148
+ if rules.include?(:with_currency)
149
+ formatted << " "
150
+ formatted << '<span class="currency">' if rules.include?(:html)
151
+ formatted << currency
152
+ formatted << '</span>' if rules.include?(:html)
153
+ end
154
+ formatted
155
+ end
156
+
157
+ # Money.ca_dollar(100).to_s => "1.00"
158
+ def to_s
159
+ sprintf("%.2f", cents.to_f / 100 )
160
+ end
161
+
162
+ # Recieve the amount of this money object in another currency
163
+ def exchange_to(other_currency)
164
+ self.class.bank.reduce(self, other_currency)
165
+ end
166
+
167
+ # Create a new money object with value 0
168
+ def self.empty(currency = default_currency)
169
+ Money.new(0, currency)
170
+ end
171
+
172
+ # Create a new money object using the Canadian dollar currency
173
+ def self.ca_dollar(num)
174
+ Money.new(num, "CAD")
175
+ end
176
+
177
+ # Create a new money object using the American dollar currency
178
+ def self.us_dollar(num)
179
+ Money.new(num, "USD")
180
+ end
181
+
182
+ # Create a new money object using the Euro currency
183
+ def self.euro(num)
184
+ Money.new(num, "EUR")
185
+ end
186
+
187
+ # Recieve a money object with the same amount as the current Money object
188
+ # in american dollar
189
+ def as_us_dollar
190
+ exchange_to("USD")
191
+ end
192
+
193
+ # Recieve a money object with the same amount as the current Money object
194
+ # in canadian dollar
195
+ def as_ca_dollar
196
+ exchange_to("CAD")
197
+ end
198
+
199
+ # Recieve a money object with the same amount as the current Money object
200
+ # in euro
201
+ def as_ca_euro
202
+ exchange_to("EUR")
203
+ end
204
+
205
+ # Conversation to self
206
+ def to_money
207
+ self
208
+ end
209
+ end
@@ -0,0 +1,57 @@
1
+ # Extends the class object with class and instance accessors for class attributes,
2
+ # just like the native attr* accessors for instance attributes.
3
+ class Class # :nodoc:
4
+ def cattr_reader(*syms)
5
+ syms.each do |sym|
6
+ class_eval <<-EOS
7
+ if ! defined? @@#{sym.to_s}
8
+ @@#{sym.to_s} = nil
9
+ end
10
+
11
+ def self.#{sym.to_s}
12
+ @@#{sym}
13
+ end
14
+
15
+ def #{sym.to_s}
16
+ @@#{sym}
17
+ end
18
+
19
+ def call_#{sym.to_s}
20
+ case @@#{sym.to_s}
21
+ when Symbol then send(@@#{sym})
22
+ when Proc then @@#{sym}.call(self)
23
+ when String then @@#{sym}
24
+ else nil
25
+ end
26
+ end
27
+ EOS
28
+ end
29
+ end
30
+
31
+ def cattr_writer(*syms)
32
+ syms.each do |sym|
33
+ class_eval <<-EOS
34
+ if ! defined? @@#{sym.to_s}
35
+ @@#{sym.to_s} = nil
36
+ end
37
+
38
+ def self.#{sym.to_s}=(obj)
39
+ @@#{sym.to_s} = obj
40
+ end
41
+
42
+ def self.set_#{sym.to_s}(obj)
43
+ @@#{sym.to_s} = obj
44
+ end
45
+
46
+ def #{sym.to_s}=(obj)
47
+ @@#{sym} = obj
48
+ end
49
+ EOS
50
+ end
51
+ end
52
+
53
+ def cattr_accessor(*syms)
54
+ cattr_reader(*syms)
55
+ cattr_writer(*syms)
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: servicemerchant
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2008-10-26 00:00:00 +04:00
8
+ summary: Provides UI and tools to add billing feature to web application
9
+ require_paths:
10
+ - lib
11
+ email:
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors: []
30
+
31
+ files:
32
+ - recurring_billing/lib
33
+ - recurring_billing/lib/am_extensions
34
+ - recurring_billing/lib/am_extensions/paypal_extension.rb
35
+ - recurring_billing/lib/am_extensions.rb
36
+ - recurring_billing/lib/dependencies.rb
37
+ - recurring_billing/lib/gateways
38
+ - recurring_billing/lib/gateways/authorize_net.rb
39
+ - recurring_billing/lib/gateways/paypal.rb
40
+ - recurring_billing/lib/gateways.rb
41
+ - recurring_billing/lib/recurring_billing.rb
42
+ - recurring_billing/lib/recurring_billing.rdoc
43
+ - recurring_billing/lib/utils.rb
44
+ - recurring_billing/test
45
+ - recurring_billing/test/fixtures.yml
46
+ - recurring_billing/test/remote
47
+ - recurring_billing/test/remote/authorize_net_test.rb
48
+ - recurring_billing/test/remote/paypal_test.rb
49
+ - recurring_billing/test/remote/recurring_billing_test.rb
50
+ - recurring_billing/test/test_helper.rb
51
+ - recurring_billing/test/unit
52
+ - recurring_billing/test/unit/authorize_net_gateway_class_test.rb
53
+ - recurring_billing/test/unit/paypal_gateway_class_test.rb
54
+ - recurring_billing/test/unit/recurring_billing_gateway_class_test.rb
55
+ - recurring_billing/test/unit/utils_test.rb
56
+ - subscription_management/lib
57
+ - subscription_management/lib/models
58
+ - subscription_management/lib/models/subscription.rb
59
+ - subscription_management/lib/models/subscription_profile.rb
60
+ - subscription_management/lib/subscription_management.rb
61
+ - subscription_management/Rakefile
62
+ - subscription_management/samples
63
+ - subscription_management/samples/backpack.yml
64
+ - subscription_management/samples/basecamp.yml
65
+ - subscription_management/samples/brainkeeper.yml
66
+ - subscription_management/samples/campfire.yml
67
+ - subscription_management/samples/clickandpledge.yml
68
+ - subscription_management/samples/demo.rb
69
+ - subscription_management/samples/elm.yml
70
+ - subscription_management/samples/freshbooks.yml
71
+ - subscription_management/samples/highrise.yml
72
+ - subscription_management/samples/presets.yml
73
+ - subscription_management/samples/tariff.outline.yml
74
+ - subscription_management/samples/taxes.yml
75
+ - subscription_management/subscription_management.rb
76
+ - subscription_management/tasks
77
+ - subscription_management/tasks/schema.rb
78
+ - subscription_management/test
79
+ - subscription_management/test/connection.rb
80
+ - subscription_management/test/remote
81
+ - subscription_management/test/remote/subscription_management_test.rb
82
+ - subscription_management/test/test_helper.rb
83
+ - subscription_management/test/unit
84
+ - subscription_management/test/unit/subscription_management_test.rb
85
+ - tracker/db
86
+ - tracker/db/migrations
87
+ - tracker/db/migrations/empty-directory
88
+ - tracker/demo.rb
89
+ - tracker/lib
90
+ - tracker/lib/models
91
+ - tracker/lib/models/recurring_payment_profile.rb
92
+ - tracker/lib/models/transaction.rb
93
+ - tracker/lib/recurring_billing_extension.rb
94
+ - tracker/lib/recurring_billing_extension.rdoc
95
+ - tracker/Rakefile
96
+ - tracker/README
97
+ - tracker/tasks
98
+ - tracker/tasks/schema.rb
99
+ - tracker/test
100
+ - tracker/test/connection.rb
101
+ - tracker/test/recurring_payment_profile.rb
102
+ - tracker/test/remote
103
+ - tracker/test/remote/authorize_net_test.rb
104
+ - tracker/test/remote/paypal_test.rb
105
+ - tracker/test/test_helper.rb
106
+ - tracker/test/unit
107
+ - tracker/test/unit/recurring_payment_profile_test.rb
108
+ - tracker/tracker.rb
109
+ - vendor/money-1.7.1
110
+ - vendor/money-1.7.1/lib
111
+ - vendor/money-1.7.1/lib/bank
112
+ - vendor/money-1.7.1/lib/bank/no_exchange_bank.rb
113
+ - vendor/money-1.7.1/lib/bank/variable_exchange_bank.rb
114
+ - vendor/money-1.7.1/lib/money
115
+ - vendor/money-1.7.1/lib/money/core_extensions.rb
116
+ - vendor/money-1.7.1/lib/money/money.rb
117
+ - vendor/money-1.7.1/lib/money.rb
118
+ - vendor/money-1.7.1/lib/support
119
+ - vendor/money-1.7.1/lib/support/cattr_accessor.rb
120
+ - vendor/money-1.7.1/MIT-LICENSE
121
+ - vendor/money-1.7.1/README
122
+ - demo.rb
123
+ - MIT-LICENSE.txt
124
+ - pkg
125
+ - Rakefile
126
+ - README.txt
127
+ - recurring_billing
128
+ - sample_app
129
+ - subscription_management
130
+ - tracker
131
+ - vendor
132
+ test_files: []
133
+
134
+ rdoc_options: []
135
+
136
+ extra_rdoc_files: []
137
+
138
+ executables: []
139
+
140
+ extensions: []
141
+
142
+ requirements: []
143
+
144
+ dependencies:
145
+ - !ruby/object:Gem::Dependency
146
+ name: activemerchant
147
+ version_requirement:
148
+ version_requirements: !ruby/object:Gem::Version::Requirement
149
+ requirements:
150
+ - - "="
151
+ - !ruby/object:Gem::Version
152
+ version: 1.3.2
153
+ version: