app_manager 1.2.6 → 1.3.1
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.
- checksums.yaml +4 -4
- data/.gitignore +7 -1
- data/Gemfile.lock +2 -6
- data/app/controllers/app_manager/charges_controller.rb +157 -157
- data/app/controllers/app_manager/plans_controller.rb +208 -205
- data/app/model/app_manager/app.rb +5 -0
- data/app/model/app_manager/app_manager_record.rb +7 -0
- data/app/model/app_manager/app_structure.rb +5 -0
- data/app/model/app_manager/charge.rb +6 -0
- data/app/model/app_manager/discount_plan.rb +5 -0
- data/app/model/app_manager/extend_trial.rb +5 -0
- data/app/model/app_manager/plan.rb +6 -0
- data/app/model/app_manager/plan_user.rb +5 -0
- data/app_manager.gemspec +1 -1
- data/lib/app_manager/client/connection.rb +5 -7
- data/lib/app_manager/client/plans.rb +34 -34
- data/lib/app_manager/client.rb +21 -23
- data/lib/app_manager/fail_safe.rb +460 -528
- data/lib/app_manager/graphql_helper.rb +1 -1
- data/lib/app_manager/model.rb +188 -200
- data/lib/app_manager/tasks/sync/local_app_manager.rake +2 -3
- data/lib/app_manager/version.rb +1 -1
- data/lib/app_manager.rb +3 -3
- data/lib/generators/app_manager/install/install_generator.rb +40 -31
- data/lib/generators/app_manager/install/templates/failsafe_tables.erb +90 -0
- metadata +11 -16
@@ -1,210 +1,213 @@
|
|
1
1
|
require_dependency "app_manager/application_controller"
|
2
2
|
|
3
3
|
module AppManager
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
rescue Exception => e
|
168
|
-
Rails.logger.info "APP MANAGER >>>> #{e.inspect}"
|
169
|
-
end
|
170
|
-
AppManager.clear_cache
|
171
|
-
end
|
172
|
-
head :ok
|
173
|
-
end
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
private
|
178
|
-
|
179
|
-
def params_permit
|
180
|
-
params.permit!
|
181
|
-
end
|
182
|
-
|
183
|
-
def model
|
184
|
-
@models = ActiveRecord::Base.connection.tables
|
185
|
-
@config_table = AppManager.configuration.shopify_table_name
|
186
|
-
@shopify_domain = AppManager.configuration.shopify_domain_field
|
187
|
-
@plan_field = AppManager.configuration.plan_id_or_name_field
|
188
|
-
@field_names = AppManager.configuration.field_names
|
189
|
-
@api_version = AppManager.configuration.shopify_api_version
|
190
|
-
if @models.include?(@config_table) && !@plan_field.nil?
|
191
|
-
return @config_table.classify.constantize
|
192
|
-
else
|
193
|
-
return nil
|
194
|
-
end
|
4
|
+
class PlansController < ApplicationController
|
5
|
+
cache_response_for :plans
|
6
|
+
cache_response_for :index
|
7
|
+
cache_response_for :users
|
8
|
+
skip_before_action :verify_authenticity_token, :only => [:active_without_plan, :burst_cache, :fail_safe_backup]
|
9
|
+
|
10
|
+
def index
|
11
|
+
render :json => {"features" => AppManager.configuration.plan_features || []}
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def plans
|
16
|
+
active_plan_id_or_name = nil
|
17
|
+
shopify_plan = nil
|
18
|
+
plan = nil
|
19
|
+
active_charge = nil
|
20
|
+
default_plan_id = nil
|
21
|
+
choose_later = false
|
22
|
+
trial_activated_at = nil
|
23
|
+
plan_obj = AppManager::Client.new
|
24
|
+
plans = []
|
25
|
+
if params[:shop_domain].present? && !AppManager.configuration.plan_features.nil?
|
26
|
+
@shop = shop_data
|
27
|
+
if !@shop.nil?
|
28
|
+
active_plan_id_or_name = @shop[@plan_field] rescue nil
|
29
|
+
plans = plan_obj.get_plans(params[:shop_domain], active_plan_id_or_name)
|
30
|
+
# render json: plans and return #use this to test plan failsafe api
|
31
|
+
if !@field_names.nil? && @field_names.has_key?('shopify_plan') && !@field_names.nil?
|
32
|
+
shopify_plan_field = AppManager.configuration.field_names['shopify_plan']
|
33
|
+
shopify_plan = @shop[shopify_plan_field] rescue nil
|
34
|
+
plan = plans && plans.any? && !active_plan_id_or_name.nil? ? (plans.find { |x| x["id"] == active_plan_id_or_name }.present? ? plans.find { |x| x["id"] == active_plan_id_or_name } : nil) : nil
|
35
|
+
|
36
|
+
@trial_activated_field = AppManager.configuration.field_names['trial_activated_at']
|
37
|
+
trial_activated_at = @shop[@trial_activated_field] rescue nil
|
38
|
+
active_charge = plan_obj.get_charge(params[:shop_domain])
|
39
|
+
if active_charge && active_charge.any? && active_charge['active_charge'].nil? && active_charge['cancelled_charge'].nil? && !trial_activated_at && !plan
|
40
|
+
choose_later = true
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
else
|
45
|
+
Rollbar.error("APP MANAGER >>>> Either model is defined wrong or config.plan_id_or_name_field is nil in initializer ===")
|
46
|
+
end
|
47
|
+
else
|
48
|
+
Rollbar.error("APP MANAGER >>>> Either params missing store_domain or config.plan_features is nil in initializer ===")
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
plans = plan_obj.get_plans(params[:shop_domain]) if plans && plans.blank?
|
53
|
+
default_plan_data = plans.select { |x| x['choose_later_plan'] == true }
|
54
|
+
if default_plan_data.any?
|
55
|
+
if default_plan_data.select { |x| x['store_base_plan'] == true }.size > 0
|
56
|
+
shopify_plans = plans.select { |x| x['interval'] == 'EVERY_30_DAYS' }
|
57
|
+
shopify_plans.each do |shp|
|
58
|
+
if shp && shp["shopify_plans"].include?(shopify_plan)
|
59
|
+
default_plan_id = shp["id"]
|
60
|
+
break
|
61
|
+
end
|
62
|
+
end
|
63
|
+
else
|
64
|
+
default_plan_id = default_plan_data.map { |e| e['id'] }.first if default_plan_data.any? rescue nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
response = {
|
69
|
+
'plans' => plans,
|
70
|
+
'shopify_plan' => shopify_plan,
|
71
|
+
'plan' => plan,
|
72
|
+
'default_plan_id' => default_plan_id,
|
73
|
+
'choose_later' => choose_later,
|
74
|
+
'has_active_charge' => (((active_charge && active_charge.any? && !active_charge['active_charge'].nil?) or !trial_activated_at) ? true : false)
|
75
|
+
}
|
76
|
+
render json: response
|
77
|
+
end
|
78
|
+
|
79
|
+
def users
|
80
|
+
if model
|
81
|
+
|
82
|
+
search = params[:search]
|
83
|
+
sort = params[:sort] || AppManager.configuration.field_names['created_at']
|
84
|
+
order = params[:order] || 'asc'
|
85
|
+
plans = params[:plans] || nil
|
86
|
+
plans = plans.values if !plans.nil?
|
87
|
+
shopify_plans = params[:shopify_plans] || nil
|
88
|
+
shopify_plans = shopify_plans.values if !shopify_plans.nil?
|
89
|
+
items_per_page = params[:itemsPerPage] || 25
|
90
|
+
@shopify_email = AppManager.configuration.field_names['shopify_email']
|
91
|
+
@shopify_plan_name_field = AppManager.configuration.field_names['shopify_plan']
|
92
|
+
data = model
|
93
|
+
if params[:search]
|
94
|
+
data = model.where("#{@shopify_domain} LIKE :search OR #{@shopify_email} LIKE :search", search: "%#{search}%")
|
95
|
+
data = data.where(@plan_field => plans) if !plans.nil?
|
96
|
+
data = data.where(@shopify_plan_name_field => shopify_plans) if !shopify_plans.nil?
|
97
|
+
data = data.page(params[:page]).per(items_per_page)
|
98
|
+
else
|
99
|
+
data = model.where(@plan_field => plans) if !plans.nil?
|
100
|
+
data = data.where(@shopify_plan_name_field => shopify_plans) if !shopify_plans.nil?
|
101
|
+
data = data.page(params[:page]).per(items_per_page)
|
102
|
+
end
|
103
|
+
users = {
|
104
|
+
"current_page" => data && data.current_page ? data.current_page : 0,
|
105
|
+
"data" => data ? data.collect { |st| @field_names.map { |key, value| [key, "#{st[value]}"] }.to_h } : [],
|
106
|
+
"first_page_url" => "#{app_url}/api/app-manager/users?page=1",
|
107
|
+
"from" => data && data.total_pages ? 1 : 0,
|
108
|
+
"last_page" => data && data.total_pages ? data.total_pages : 0,
|
109
|
+
"last_page_url" => data && data.total_pages ? "#{app_url}/api/app-manager/users?page=#{data.total_pages}" : nil,
|
110
|
+
"links" => '',
|
111
|
+
"next_page_url" => data && data.next_page ? "#{app_url}/api/app-manager/users?page=#{data.next_page}" : nil,
|
112
|
+
"path" => "#{app_url}/api/app-manager/users",
|
113
|
+
"per_page" => 1,
|
114
|
+
"prev_page_url" => data && data.prev_page ? "#{app_url}/api/app-manager/users?page=#{data.prev_page}" : nil,
|
115
|
+
"to" => data && data.total_pages ? data.total_pages : 0,
|
116
|
+
"total" => data && data.total_pages ? data.total_pages : 0,
|
117
|
+
}
|
118
|
+
render json: users
|
119
|
+
|
120
|
+
else
|
121
|
+
render json: nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def active_without_plan
|
126
|
+
if params[:shop_domain].present? && params[:plan_id].present? && model
|
127
|
+
@shop = shop_data
|
128
|
+
@trial_activated_field = AppManager.configuration.field_names['trial_activated_at']
|
129
|
+
if @shop.update(@plan_field => params[:plan_id], @trial_activated_field => DateTime.now)
|
130
|
+
begin
|
131
|
+
plan_obj = AppManager::Client.new
|
132
|
+
plan_data = plan_obj.get_plan(params[:plan_id], params[:shop_domain]) rescue nil
|
133
|
+
AppManager::EventHandler.new('charge_created', {
|
134
|
+
"plan" => plan_data,
|
135
|
+
"charge" => nil,
|
136
|
+
"previous_charge" => nil,
|
137
|
+
"choose_later" => true,
|
138
|
+
"shopify_domain" => params[:shop_domain]
|
139
|
+
})
|
140
|
+
rescue Exception => e
|
141
|
+
Rollbar.error("APP MANAGER Error in Active without plan method #{e}")
|
142
|
+
end
|
143
|
+
render json: {'status' => true}
|
144
|
+
else
|
145
|
+
render json: {'status' => false, 'error' => "#{@shop.errors.full_messages.to_sentence}"}, status: 422
|
146
|
+
end
|
147
|
+
else
|
148
|
+
render json: {'status' => false, 'error' => 'Shop not found or missing shop'}, status: 422
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
def burst_cache
|
154
|
+
AppManager.clear_cache
|
155
|
+
head :ok
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
def fail_safe_backup
|
160
|
+
params_permit
|
161
|
+
Thread.new do
|
162
|
+
@fs = AppManager::FailSafe.new
|
163
|
+
begin
|
164
|
+
@fs.sync_app_manager
|
165
|
+
rescue Exception => e
|
166
|
+
Rails.logger.info "APP MANAGER >>>> LOCAL DB couldn't sync with POTAL DB #{e.inspect}"
|
195
167
|
end
|
196
168
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
169
|
+
begin
|
170
|
+
@fs.save_api_data(params)
|
171
|
+
rescue Exception => e
|
172
|
+
Rails.logger.info "APP MANAGER >>>> #{e.inspect}"
|
173
|
+
end
|
174
|
+
AppManager.clear_cache
|
175
|
+
end
|
176
|
+
head :ok
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
private
|
181
|
+
|
182
|
+
def params_permit
|
183
|
+
params.permit!
|
184
|
+
end
|
185
|
+
|
186
|
+
def model
|
187
|
+
@models = ActiveRecord::Base.connection.tables
|
188
|
+
@config_table = AppManager.configuration.shopify_table_name
|
189
|
+
@shopify_domain = AppManager.configuration.shopify_domain_field
|
190
|
+
@plan_field = AppManager.configuration.plan_id_or_name_field
|
191
|
+
@field_names = AppManager.configuration.field_names
|
192
|
+
@api_version = AppManager.configuration.shopify_api_version
|
193
|
+
if @models.include?(@config_table) && !@plan_field.nil?
|
194
|
+
return @config_table.classify.constantize
|
195
|
+
else
|
196
|
+
return nil
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def shop_data
|
201
|
+
if model
|
202
|
+
return model.where(@shopify_domain => params[:shop_domain]).first rescue nil
|
203
|
+
else
|
204
|
+
return nil
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def app_url
|
209
|
+
AppManager.configuration.app_url
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
end
|
data/app_manager.gemspec
CHANGED
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_dependency "httparty"
|
34
34
|
spec.add_dependency "rails", '>= 5.2.0'
|
35
35
|
spec.add_dependency "kaminari", '>= 0.16.3'
|
36
|
-
spec.add_dependency "sqlite3", '~> 1.
|
36
|
+
# spec.add_dependency "sqlite3", '~> 1.3.0'
|
37
37
|
# For more information and examples about making a new gem, checkout our
|
38
38
|
# guide at: https://bundler.io/guides/creating_gem.html
|
39
39
|
end
|
@@ -23,7 +23,6 @@ module AppManager
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def request(http_method, path, options)
|
26
|
-
begin
|
27
26
|
if http_method.to_s == 'get'
|
28
27
|
response = response_from_cache_for_api(http_method, path, options)
|
29
28
|
else
|
@@ -38,15 +37,12 @@ module AppManager
|
|
38
37
|
if response.code.to_s.start_with?('2') or response.code.to_s.start_with?('4')
|
39
38
|
data = response.parsed_response
|
40
39
|
data = parse_data(response.parsed_response)
|
41
|
-
# data = response_from_failsafe(path,options)
|
40
|
+
# data = response_from_failsafe(path,options)
|
42
41
|
else
|
43
42
|
data = response_from_failsafe(path,options)
|
44
43
|
end
|
45
44
|
end
|
46
|
-
|
47
|
-
data = response_from_failsafe(path,options)
|
48
|
-
end
|
49
|
-
end
|
45
|
+
end
|
50
46
|
|
51
47
|
def response_from_cache_for_api(http_method, path, options)
|
52
48
|
cache_key = "app-manager-cache/#{path}"
|
@@ -92,7 +88,9 @@ module AppManager
|
|
92
88
|
when 'get-remaining-days'
|
93
89
|
return @fs.get_local_remaining_days(params,options)
|
94
90
|
when 'get-charge'
|
95
|
-
return @fs.get_local_charge(params,options)
|
91
|
+
return @fs.get_local_charge(params,options)
|
92
|
+
when 'has-plan'
|
93
|
+
return @fs.get_local_has_plan(params, options)
|
96
94
|
else
|
97
95
|
return nil
|
98
96
|
end
|
@@ -1,48 +1,48 @@
|
|
1
1
|
module AppManager
|
2
|
-
|
3
|
-
|
2
|
+
class Client
|
3
|
+
module Plans
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
def get_plans(shop_domain, active_plan_id = nil)
|
6
|
+
get("/plans?shop_domain=#{shop_domain}&active_plan_id=#{active_plan_id}")
|
7
|
+
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
def get_plan(plan_id, shop_domain = nil)
|
10
|
+
get("/plan?plan_id=#{plan_id}&shop_domain=#{shop_domain}")
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
def store_charge(options = {})
|
14
|
+
post("/store-charge", options)
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
def cancel_charge(shop_domain, plan_id)
|
18
|
+
post("/cancel-charge", {shop_domain: shop_domain, plan_id: plan_id})
|
19
|
+
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
def update_charge(shop_domain, plan_id)
|
22
|
+
post("/update-charge", {shop_domain: shop_domain, plan_id: plan_id})
|
23
|
+
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def sync_charge(options = {})
|
26
|
+
post("/sync-charge", options)
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
def get_remaining_days(shop_domain, trial_activated_at = nil, plan_id = nil)
|
30
|
+
get("/get-remaining-days?shop_domain=#{shop_domain}&trial_activated_at=#{trial_activated_at}&plan_id=#{plan_id}")
|
31
|
+
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
def get_charge(shop_domain)
|
34
|
+
get("/get-charge?shop_domain=#{shop_domain}")
|
35
|
+
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
def get_status(options = {})
|
38
|
+
get("/get-status", options)
|
39
|
+
end
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
def has_plan(shop_domain, plan_id, trial_activated_at, grandfathered)
|
42
|
+
get("/has-plan?shop_domain=#{shop_domain}&plan_id=#{plan_id}&trial_activated_at=#{trial_activated_at}&grandfathered=#{grandfathered}")
|
43
|
+
end
|
44
44
|
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
end
|
47
|
+
end
|
48
48
|
end
|