billingly 0.1.6 → 0.1.7
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.
@@ -130,6 +130,17 @@ module Billingly
|
|
130
130
|
on_subscription_success
|
131
131
|
end
|
132
132
|
end
|
133
|
+
|
134
|
+
# Customers can subscribe to a plan using a special subscription code which would
|
135
|
+
# allow them to access an otherwise hidden plan.
|
136
|
+
# @param code [String] The 13 digit EAN-13 code being redeemed
|
137
|
+
def redeem_special_plan_code(code_string)
|
138
|
+
code = Billingly::SpecialPlanCode.find_by_code(code_string)
|
139
|
+
return if code.nil?
|
140
|
+
return if code.redeemed?
|
141
|
+
subscribe_to_plan(code.plan)
|
142
|
+
code.update_attributes(customer: self, redeemed_on: Time.now)
|
143
|
+
end
|
133
144
|
|
134
145
|
# Callback called whenever this customer is successfully subscribed to a plan.
|
135
146
|
# This callback does not differentiate if the customer is subscribing for the first time,
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'ean13'
|
3
|
+
|
4
|
+
# A SpecialPlanCode lets the {Customer} subscribe to a plan which is hidden from regular
|
5
|
+
# customers.
|
6
|
+
# Customers would visit your site and redeem the code instead of subscribing to
|
7
|
+
# a plan directly. The code will then subscribe them to a plan with the given special pricing.
|
8
|
+
class Billingly::SpecialPlanCode < ActiveRecord::Base
|
9
|
+
belongs_to :plan
|
10
|
+
belongs_to :customer
|
11
|
+
validates :plan, presence: true
|
12
|
+
validates :code, presence: true
|
13
|
+
|
14
|
+
attr_accessible :plan, :code, :customer, :redeemed_on
|
15
|
+
|
16
|
+
# !@attribute [r] redeemed?
|
17
|
+
# @return [Boolean] Whether this code has been redeemed or not
|
18
|
+
def redeemed?
|
19
|
+
!redeemed_on.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
# Creates a list of valid random ean-13 codes.
|
23
|
+
# @param how_many [Integer] How many codes to create.
|
24
|
+
# @return [Array<String>] The list of generated ean-13 codes.
|
25
|
+
def self.generate_ean_13_codes(how_many)
|
26
|
+
randoms = Set.new
|
27
|
+
loop do
|
28
|
+
ean = EAN13.complete( (100000000000 + rand(100000000000)).to_s )
|
29
|
+
randoms << ean if ean
|
30
|
+
return randoms.to_a if randoms.size == how_many
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Generates rows in the database with codes for a specific plan.
|
35
|
+
# It creates new rows with new codes, and it makes sure that the new codes don't clash
|
36
|
+
# with pre-existing codes.
|
37
|
+
# @param plan [Plan] The plan to generate the codes for.
|
38
|
+
# @param how_many [Integer] How many new codes to issue.
|
39
|
+
def self.generate_for_plan(plan, how_many)
|
40
|
+
generate_ean_13_codes(how_many).collect do |code|
|
41
|
+
self.create!(code: code, plan: plan)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Exports all the codes for each plan. You may export only the unused ones.
|
46
|
+
# The codes are exported into CSV files inside the current user's home directory.
|
47
|
+
# There is one file per plan. Each file contains all the available codes for a given plan.
|
48
|
+
def self.export_codes
|
49
|
+
where('redeemed_on IS NULL').group_by(&:plan).each do |plan, special_codes|
|
50
|
+
filename = "ean_13_codes_for_#{plan.description.gsub(/[^a-zA-Z0-9]/,'_')}.csv"
|
51
|
+
File.open(File.expand_path("~/#{filename}"),'w') do |file|
|
52
|
+
file.write(special_codes.collect(&:code).join("\n"))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.cleanup_exported_files
|
58
|
+
`rm #{File.expand_path('~/ean_13_codes_for_*.csv')}`
|
59
|
+
end
|
60
|
+
end
|
data/lib/billingly/version.rb
CHANGED
@@ -64,6 +64,15 @@ class CreateBillinglyTables < ActiveRecord::Migration
|
|
64
64
|
t.boolean 'hidden_on'
|
65
65
|
t.timestamps
|
66
66
|
end
|
67
|
+
|
68
|
+
create_table :billingly_special_plan_codes do |t|
|
69
|
+
t.references :plan, null: false
|
70
|
+
t.string :code
|
71
|
+
t.references :customer
|
72
|
+
t.datetime :redeemed_on
|
73
|
+
t.timestamps
|
74
|
+
end
|
75
|
+
add_index :billingly_special_plan_codes, :code, :unique => true
|
67
76
|
end
|
68
77
|
end
|
69
78
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: billingly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &70221659484260 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.2.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70221659484260
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: validates_email_format_of
|
27
|
-
requirement: &
|
27
|
+
requirement: &70221659483740 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70221659483740
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: has_duration
|
38
|
-
requirement: &
|
38
|
+
requirement: &70221659499360 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,21 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70221659499360
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: ean13
|
49
|
+
requirement: &70221659498700 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70221659498700
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
59
|
name: timecop
|
49
|
-
requirement: &
|
60
|
+
requirement: &70221659497480 !ruby/object:Gem::Requirement
|
50
61
|
none: false
|
51
62
|
requirements:
|
52
63
|
- - ! '>='
|
@@ -54,10 +65,10 @@ dependencies:
|
|
54
65
|
version: '0'
|
55
66
|
type: :development
|
56
67
|
prerelease: false
|
57
|
-
version_requirements: *
|
68
|
+
version_requirements: *70221659497480
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
70
|
name: sqlite3
|
60
|
-
requirement: &
|
71
|
+
requirement: &70221659496980 !ruby/object:Gem::Requirement
|
61
72
|
none: false
|
62
73
|
requirements:
|
63
74
|
- - ! '>='
|
@@ -65,10 +76,10 @@ dependencies:
|
|
65
76
|
version: '0'
|
66
77
|
type: :development
|
67
78
|
prerelease: false
|
68
|
-
version_requirements: *
|
79
|
+
version_requirements: *70221659496980
|
69
80
|
- !ruby/object:Gem::Dependency
|
70
81
|
name: rspec-rails
|
71
|
-
requirement: &
|
82
|
+
requirement: &70221659496400 !ruby/object:Gem::Requirement
|
72
83
|
none: false
|
73
84
|
requirements:
|
74
85
|
- - ! '>='
|
@@ -76,10 +87,10 @@ dependencies:
|
|
76
87
|
version: '0'
|
77
88
|
type: :development
|
78
89
|
prerelease: false
|
79
|
-
version_requirements: *
|
90
|
+
version_requirements: *70221659496400
|
80
91
|
- !ruby/object:Gem::Dependency
|
81
92
|
name: factory_girl_rails
|
82
|
-
requirement: &
|
93
|
+
requirement: &70221659495600 !ruby/object:Gem::Requirement
|
83
94
|
none: false
|
84
95
|
requirements:
|
85
96
|
- - ! '>='
|
@@ -87,7 +98,7 @@ dependencies:
|
|
87
98
|
version: '0'
|
88
99
|
type: :development
|
89
100
|
prerelease: false
|
90
|
-
version_requirements: *
|
101
|
+
version_requirements: *70221659495600
|
91
102
|
description: Rails Engine for SaaS subscription management. Manage subscriptions,
|
92
103
|
plan changes, free trials and more!!!
|
93
104
|
email:
|
@@ -107,6 +118,7 @@ files:
|
|
107
118
|
- app/models/billingly/journal_entry.rb
|
108
119
|
- app/models/billingly/payment.rb
|
109
120
|
- app/models/billingly/plan.rb
|
121
|
+
- app/models/billingly/special_plan_code.rb
|
110
122
|
- app/models/billingly/subscription.rb
|
111
123
|
- app/models/billingly/tasks.rb
|
112
124
|
- app/views/billingly/mailer/overdue_notification.html.erb
|