app_manager 1.7.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +67 -69
- data/README.md +36 -1
- data/app/controllers/app_manager/charges_controller.rb +21 -1
- data/app/controllers/app_manager/plans_controller.rb +13 -2
- data/app/model/app_manager/discount.rb +5 -0
- data/app/model/app_manager/discount_link_plan.rb +5 -0
- data/app/model/app_manager/discount_shop.rb +5 -0
- data/app/model/app_manager/discount_usage_log.rb +5 -0
- data/lib/app_manager/client/connection.rb +24 -4
- data/lib/app_manager/client/plans.rb +12 -0
- data/lib/app_manager/fail_safe.rb +227 -3
- data/lib/app_manager/graphql_helper.rb +62 -19
- data/lib/app_manager/set_cookie.rb +41 -0
- data/lib/app_manager/version.rb +1 -1
- data/lib/app_manager.rb +27 -0
- data/lib/generators/app_manager/install/install_generator.rb +8 -0
- data/lib/generators/app_manager/install/templates/add_discount_tables.erb +48 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1093f4ae3ee06a00f81bf11ad98bb1669f6b9f931bed69a430525733058143a0
|
4
|
+
data.tar.gz: 9a3a425bdf82d12982f33ace1e86a1e5b47bbc7b3430ccd96b0469967cbf2f65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9306209e778f2593afc88cdaf1f468f8c0ccefddd197e3ecfcb516301581577131975ed73dde14decae361454d32955f25c80220edab9cc755955f986d37a747
|
7
|
+
data.tar.gz: b0f6d9c366e807ebaa5d5fd5de056ecd3f7e93addfbdc944cda14ec915dc86a5e20d4b248426dfe04bc7c5962887d858fd01eed6de2bc4ae7c5976540e9c8c6a
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
app_manager (
|
4
|
+
app_manager (2.0.0)
|
5
5
|
activerecord-import (~> 1.4)
|
6
6
|
httparty
|
7
7
|
kaminari (>= 0.16.3)
|
@@ -10,35 +10,35 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
-
actioncable (7.1.2)
|
14
|
-
actionpack (= 7.1.2)
|
15
|
-
activesupport (= 7.1.2)
|
13
|
+
actioncable (7.1.3.2)
|
14
|
+
actionpack (= 7.1.3.2)
|
15
|
+
activesupport (= 7.1.3.2)
|
16
16
|
nio4r (~> 2.0)
|
17
17
|
websocket-driver (>= 0.6.1)
|
18
18
|
zeitwerk (~> 2.6)
|
19
|
-
actionmailbox (7.1.2)
|
20
|
-
actionpack (= 7.1.2)
|
21
|
-
activejob (= 7.1.2)
|
22
|
-
activerecord (= 7.1.2)
|
23
|
-
activestorage (= 7.1.2)
|
24
|
-
activesupport (= 7.1.2)
|
19
|
+
actionmailbox (7.1.3.2)
|
20
|
+
actionpack (= 7.1.3.2)
|
21
|
+
activejob (= 7.1.3.2)
|
22
|
+
activerecord (= 7.1.3.2)
|
23
|
+
activestorage (= 7.1.3.2)
|
24
|
+
activesupport (= 7.1.3.2)
|
25
25
|
mail (>= 2.7.1)
|
26
26
|
net-imap
|
27
27
|
net-pop
|
28
28
|
net-smtp
|
29
|
-
actionmailer (7.1.2)
|
30
|
-
actionpack (= 7.1.2)
|
31
|
-
actionview (= 7.1.2)
|
32
|
-
activejob (= 7.1.2)
|
33
|
-
activesupport (= 7.1.2)
|
29
|
+
actionmailer (7.1.3.2)
|
30
|
+
actionpack (= 7.1.3.2)
|
31
|
+
actionview (= 7.1.3.2)
|
32
|
+
activejob (= 7.1.3.2)
|
33
|
+
activesupport (= 7.1.3.2)
|
34
34
|
mail (~> 2.5, >= 2.5.4)
|
35
35
|
net-imap
|
36
36
|
net-pop
|
37
37
|
net-smtp
|
38
38
|
rails-dom-testing (~> 2.2)
|
39
|
-
actionpack (7.1.2)
|
40
|
-
actionview (= 7.1.2)
|
41
|
-
activesupport (= 7.1.2)
|
39
|
+
actionpack (7.1.3.2)
|
40
|
+
actionview (= 7.1.3.2)
|
41
|
+
activesupport (= 7.1.3.2)
|
42
42
|
nokogiri (>= 1.8.5)
|
43
43
|
racc
|
44
44
|
rack (>= 2.2.4)
|
@@ -46,37 +46,37 @@ GEM
|
|
46
46
|
rack-test (>= 0.6.3)
|
47
47
|
rails-dom-testing (~> 2.2)
|
48
48
|
rails-html-sanitizer (~> 1.6)
|
49
|
-
actiontext (7.1.2)
|
50
|
-
actionpack (= 7.1.2)
|
51
|
-
activerecord (= 7.1.2)
|
52
|
-
activestorage (= 7.1.2)
|
53
|
-
activesupport (= 7.1.2)
|
49
|
+
actiontext (7.1.3.2)
|
50
|
+
actionpack (= 7.1.3.2)
|
51
|
+
activerecord (= 7.1.3.2)
|
52
|
+
activestorage (= 7.1.3.2)
|
53
|
+
activesupport (= 7.1.3.2)
|
54
54
|
globalid (>= 0.6.0)
|
55
55
|
nokogiri (>= 1.8.5)
|
56
|
-
actionview (7.1.2)
|
57
|
-
activesupport (= 7.1.2)
|
56
|
+
actionview (7.1.3.2)
|
57
|
+
activesupport (= 7.1.3.2)
|
58
58
|
builder (~> 3.1)
|
59
59
|
erubi (~> 1.11)
|
60
60
|
rails-dom-testing (~> 2.2)
|
61
61
|
rails-html-sanitizer (~> 1.6)
|
62
|
-
activejob (7.1.2)
|
63
|
-
activesupport (= 7.1.2)
|
62
|
+
activejob (7.1.3.2)
|
63
|
+
activesupport (= 7.1.3.2)
|
64
64
|
globalid (>= 0.3.6)
|
65
|
-
activemodel (7.1.2)
|
66
|
-
activesupport (= 7.1.2)
|
67
|
-
activerecord (7.1.2)
|
68
|
-
activemodel (= 7.1.2)
|
69
|
-
activesupport (= 7.1.2)
|
65
|
+
activemodel (7.1.3.2)
|
66
|
+
activesupport (= 7.1.3.2)
|
67
|
+
activerecord (7.1.3.2)
|
68
|
+
activemodel (= 7.1.3.2)
|
69
|
+
activesupport (= 7.1.3.2)
|
70
70
|
timeout (>= 0.4.0)
|
71
71
|
activerecord-import (1.5.1)
|
72
72
|
activerecord (>= 4.2)
|
73
|
-
activestorage (7.1.2)
|
74
|
-
actionpack (= 7.1.2)
|
75
|
-
activejob (= 7.1.2)
|
76
|
-
activerecord (= 7.1.2)
|
77
|
-
activesupport (= 7.1.2)
|
73
|
+
activestorage (7.1.3.2)
|
74
|
+
actionpack (= 7.1.3.2)
|
75
|
+
activejob (= 7.1.3.2)
|
76
|
+
activerecord (= 7.1.3.2)
|
77
|
+
activesupport (= 7.1.3.2)
|
78
78
|
marcel (~> 1.0)
|
79
|
-
activesupport (7.1.2)
|
79
|
+
activesupport (7.1.3.2)
|
80
80
|
base64
|
81
81
|
bigdecimal
|
82
82
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
@@ -89,10 +89,10 @@ GEM
|
|
89
89
|
addressable (2.8.0)
|
90
90
|
public_suffix (>= 2.0.2, < 5.0)
|
91
91
|
base64 (0.2.0)
|
92
|
-
bigdecimal (3.1.
|
92
|
+
bigdecimal (3.1.6)
|
93
93
|
builder (3.2.4)
|
94
94
|
coderay (1.1.3)
|
95
|
-
concurrent-ruby (1.2.
|
95
|
+
concurrent-ruby (1.2.3)
|
96
96
|
connection_pool (2.4.1)
|
97
97
|
crack (0.4.5)
|
98
98
|
rexml
|
@@ -100,8 +100,7 @@ GEM
|
|
100
100
|
date (3.3.4)
|
101
101
|
diff-lcs (1.5.0)
|
102
102
|
dotenv (2.1.2)
|
103
|
-
drb (2.2.
|
104
|
-
ruby2_keywords
|
103
|
+
drb (2.2.1)
|
105
104
|
erubi (1.12.0)
|
106
105
|
globalid (1.2.1)
|
107
106
|
activesupport (>= 6.1)
|
@@ -109,12 +108,12 @@ GEM
|
|
109
108
|
httparty (0.21.0)
|
110
109
|
mini_mime (>= 1.0.0)
|
111
110
|
multi_xml (>= 0.5.2)
|
112
|
-
i18n (1.14.
|
111
|
+
i18n (1.14.4)
|
113
112
|
concurrent-ruby (~> 1.0)
|
114
|
-
io-console (0.7.
|
115
|
-
irb (1.
|
113
|
+
io-console (0.7.2)
|
114
|
+
irb (1.12.0)
|
116
115
|
rdoc
|
117
|
-
reline (>= 0.
|
116
|
+
reline (>= 0.4.2)
|
118
117
|
kaminari (1.2.2)
|
119
118
|
activesupport (>= 4.1.0)
|
120
119
|
kaminari-actionview (= 1.2.2)
|
@@ -135,11 +134,11 @@ GEM
|
|
135
134
|
net-imap
|
136
135
|
net-pop
|
137
136
|
net-smtp
|
138
|
-
marcel (1.0.
|
137
|
+
marcel (1.0.4)
|
139
138
|
method_source (1.0.0)
|
140
139
|
mini_mime (1.1.5)
|
141
140
|
mini_portile2 (2.8.5)
|
142
|
-
minitest (5.
|
141
|
+
minitest (5.22.2)
|
143
142
|
multi_xml (0.6.0)
|
144
143
|
mutex_m (0.2.0)
|
145
144
|
net-imap (0.3.7)
|
@@ -162,7 +161,7 @@ GEM
|
|
162
161
|
stringio
|
163
162
|
public_suffix (4.0.6)
|
164
163
|
racc (1.7.3)
|
165
|
-
rack (3.0.
|
164
|
+
rack (3.0.9.1)
|
166
165
|
rack-session (2.0.0)
|
167
166
|
rack (>= 3.0.0)
|
168
167
|
rack-test (2.1.0)
|
@@ -170,20 +169,20 @@ GEM
|
|
170
169
|
rackup (2.1.0)
|
171
170
|
rack (>= 3)
|
172
171
|
webrick (~> 1.8)
|
173
|
-
rails (7.1.2)
|
174
|
-
actioncable (= 7.1.2)
|
175
|
-
actionmailbox (= 7.1.2)
|
176
|
-
actionmailer (= 7.1.2)
|
177
|
-
actionpack (= 7.1.2)
|
178
|
-
actiontext (= 7.1.2)
|
179
|
-
actionview (= 7.1.2)
|
180
|
-
activejob (= 7.1.2)
|
181
|
-
activemodel (= 7.1.2)
|
182
|
-
activerecord (= 7.1.2)
|
183
|
-
activestorage (= 7.1.2)
|
184
|
-
activesupport (= 7.1.2)
|
172
|
+
rails (7.1.3.2)
|
173
|
+
actioncable (= 7.1.3.2)
|
174
|
+
actionmailbox (= 7.1.3.2)
|
175
|
+
actionmailer (= 7.1.3.2)
|
176
|
+
actionpack (= 7.1.3.2)
|
177
|
+
actiontext (= 7.1.3.2)
|
178
|
+
actionview (= 7.1.3.2)
|
179
|
+
activejob (= 7.1.3.2)
|
180
|
+
activemodel (= 7.1.3.2)
|
181
|
+
activerecord (= 7.1.3.2)
|
182
|
+
activestorage (= 7.1.3.2)
|
183
|
+
activesupport (= 7.1.3.2)
|
185
184
|
bundler (>= 1.15.0)
|
186
|
-
railties (= 7.1.2)
|
185
|
+
railties (= 7.1.3.2)
|
187
186
|
rails-dom-testing (2.2.0)
|
188
187
|
activesupport (>= 5.0.0)
|
189
188
|
minitest
|
@@ -191,9 +190,9 @@ GEM
|
|
191
190
|
rails-html-sanitizer (1.6.0)
|
192
191
|
loofah (~> 2.21)
|
193
192
|
nokogiri (~> 1.14)
|
194
|
-
railties (7.1.2)
|
195
|
-
actionpack (= 7.1.2)
|
196
|
-
activesupport (= 7.1.2)
|
193
|
+
railties (7.1.3.2)
|
194
|
+
actionpack (= 7.1.3.2)
|
195
|
+
activesupport (= 7.1.3.2)
|
197
196
|
irb
|
198
197
|
rackup (>= 1.0.0)
|
199
198
|
rake (>= 12.2)
|
@@ -202,7 +201,7 @@ GEM
|
|
202
201
|
rake (13.0.6)
|
203
202
|
rdoc (6.6.2)
|
204
203
|
psych (>= 4.0.0)
|
205
|
-
reline (0.4.
|
204
|
+
reline (0.4.3)
|
206
205
|
io-console (~> 0.5)
|
207
206
|
rexml (3.2.5)
|
208
207
|
rspec (3.11.0)
|
@@ -220,9 +219,8 @@ GEM
|
|
220
219
|
diff-lcs (>= 1.2.0, < 2.0)
|
221
220
|
rspec-support (~> 3.11.0)
|
222
221
|
rspec-support (3.11.0)
|
223
|
-
ruby2_keywords (0.0.5)
|
224
222
|
stringio (3.1.0)
|
225
|
-
thor (1.3.
|
223
|
+
thor (1.3.1)
|
226
224
|
timeout (0.4.1)
|
227
225
|
tzinfo (2.0.6)
|
228
226
|
concurrent-ruby (~> 1.0)
|
@@ -234,7 +232,7 @@ GEM
|
|
234
232
|
websocket-driver (0.7.6)
|
235
233
|
websocket-extensions (>= 0.1.0)
|
236
234
|
websocket-extensions (0.1.5)
|
237
|
-
zeitwerk (2.6.
|
235
|
+
zeitwerk (2.6.13)
|
238
236
|
|
239
237
|
PLATFORMS
|
240
238
|
ruby
|
data/README.md
CHANGED
@@ -209,8 +209,43 @@ and then you can use follwing methods with your shop objects.
|
|
209
209
|
@shop.active_shopfiy_charge_full #It will give shopify recurring charge graphql object with discounted price details
|
210
210
|
```
|
211
211
|
|
212
|
-
|
213
212
|
<a name="step4"></a>
|
213
|
+
### Discount Link Integration
|
214
|
+
|
215
|
+
* Update app manager vue package in Rails+Vue apps & for for non-vue apps, update css or js from npm package, minimum version should be 2.4.4
|
216
|
+
|
217
|
+
* Update app manager gem in your project's Gemfile
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
gem 'app_manager', '2.0.0'
|
221
|
+
```
|
222
|
+
* In Rails project, in application.rb, add following line after require "rails/all" line
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
require 'app_manager/set_cookie'
|
226
|
+
```
|
227
|
+
|
228
|
+
* In route.rb file, add following route with constraints
|
229
|
+
```ruby
|
230
|
+
condition = ->(request) { request.path_info.include?('/discount/') }
|
231
|
+
constraints(condition) do
|
232
|
+
get '/discount/*any', to: AppManager::SetCookie.new(Rails.application, condition)
|
233
|
+
end
|
234
|
+
```
|
235
|
+
* If updating gem from 1.6.1, then run these commands on rails root.
|
236
|
+
|
237
|
+
Note: In this command, Please do not overwrite app_manager.rb file so press n
|
238
|
+
```ruby
|
239
|
+
rails g app_manager:install
|
240
|
+
```
|
241
|
+
This will add a new migration file in your db/app_manager directory
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
rails db:migrate
|
245
|
+
```
|
246
|
+
|
247
|
+
|
248
|
+
<a name="step5"></a>
|
214
249
|
### Extras
|
215
250
|
|
216
251
|
* To view the app_manager ruby gem is working in your rails app you can use rails console and initialize app_manager instance like with App Manager Portal access:
|
@@ -58,9 +58,12 @@ module AppManager
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
request_data = {'shop' => @shop.shopify_domain, 'timestamp' => Time.now.to_i, 'plan' => params[:plan_id]}
|
61
|
+
request_data.merge!('host' => params['host']) if params['host'].present?
|
62
|
+
|
61
63
|
return_url = "#{app_url}#{plan_callback_path}?#{Rack::Utils.build_query(request_data)}"
|
64
|
+
discount_cookie = AppManager.resolve_from_cookies(self.request)
|
62
65
|
gq_obj = AppManager::GraphqlHelper.new(@shop.shopify_domain, @shop.shopify_token)
|
63
|
-
data = gq_obj.recurring_charge_api_call(plan_data, return_url, @shop)
|
66
|
+
data = gq_obj.recurring_charge_api_call(plan_data, return_url, @shop,discount_cookie)
|
64
67
|
if data.present? && !data["errors"].present? && (data["data"].present? && data["data"]["appSubscriptionCreate"].present? && (!data["data"]["appSubscriptionCreate"]["userErrors"].any? && data["data"]["appSubscriptionCreate"]["confirmationUrl"]))
|
65
68
|
redirect_charge = data["data"]["appSubscriptionCreate"]["confirmationUrl"]
|
66
69
|
render json: {'redirect_url' => redirect_charge}
|
@@ -85,6 +88,8 @@ module AppManager
|
|
85
88
|
shopify_token = @field_names['shopify_token']
|
86
89
|
shopify_domain = @field_names['name']
|
87
90
|
grandfathered_field = @field_names['grandfathered']
|
91
|
+
discounted_plans = JSON.parse(params[:discounted_plans]) rescue []
|
92
|
+
discounted_plans = discounted_plans.map!(&:to_s) if discounted_plans.any?
|
88
93
|
if !@shop.nil?
|
89
94
|
old_plan_id = @shop[@plan_field]
|
90
95
|
old_plan_data = nil
|
@@ -131,8 +136,23 @@ module AppManager
|
|
131
136
|
rescue Exception => e
|
132
137
|
Rollbar.error("Error in APP MANAGER Charge Created Callback >>>> #{e.inspect}")
|
133
138
|
end
|
139
|
+
|
140
|
+
begin
|
141
|
+
plan_obj = AppManager::Client.new
|
142
|
+
discounted_plans_present = discounted_plans.present? && discounted_plans.any?
|
143
|
+
if params[:promo_discount].present? && discounted_plans_present && discounted_plans.include?(params[:plan])
|
144
|
+
plan_obj.discount_used(@shop[shopify_domain], params[:promo_discount])
|
145
|
+
elsif params[:promo_discount].present? && discounted_plans.blank?
|
146
|
+
plan_obj.discount_used(@shop[shopify_domain], params[:promo_discount])
|
147
|
+
end
|
148
|
+
rescue
|
149
|
+
Rollbar.error("Error in APP MANAGER Discount used API call >>>> #{e.inspect}")
|
150
|
+
end
|
134
151
|
end
|
135
152
|
end
|
153
|
+
|
154
|
+
|
155
|
+
|
136
156
|
embed_host = Base64.encode64(params[:shop] + "/admin")
|
137
157
|
|
138
158
|
if !old_plan_id.nil?
|
@@ -65,8 +65,19 @@ module AppManager
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
promotional_discount = []
|
69
|
+
discount_cookie = AppManager.resolve_from_cookies(self.request)
|
70
|
+
if discount_cookie && @shop
|
71
|
+
created_at = @shop[AppManager.configuration.field_names['created_at']]
|
72
|
+
reinstall = AppManager.check_if_reinstall(created_at)
|
73
|
+
plan_obj = AppManager::Client.new
|
74
|
+
promotional_discount = plan_obj.get_promotional_discount(params[:shop_domain], discount_cookie['codeType'], discount_cookie['code'], reinstall)
|
75
|
+
promotional_discount = [] if promotional_discount.class.to_s == "Hash" && promotional_discount.has_key?('status') && promotional_discount['status'] == 404
|
76
|
+
end
|
77
|
+
|
68
78
|
response = {
|
69
79
|
'plans' => plans,
|
80
|
+
'promotional_discount' => promotional_discount,
|
70
81
|
'shopify_plan' => shopify_plan,
|
71
82
|
'plan' => plan,
|
72
83
|
'default_plan_id' => default_plan_id,
|
@@ -90,12 +101,12 @@ module AppManager
|
|
90
101
|
@shopify_email = AppManager.configuration.field_names['shopify_email']
|
91
102
|
@shopify_plan_name_field = AppManager.configuration.field_names['shopify_plan']
|
92
103
|
if params[:search]
|
93
|
-
data = model.where("#{@shopify_domain} LIKE :search OR #{@shopify_email} LIKE :search", search: "%#{search}%")
|
104
|
+
data = model.where("#{@shopify_domain} LIKE :search OR #{@shopify_email} LIKE :search", search: "%#{search}%").order(sort + " " + order)
|
94
105
|
data = data.where(@plan_field => plans) if !plans.nil?
|
95
106
|
data = data.where(@shopify_plan_name_field => shopify_plans) if !shopify_plans.nil?
|
96
107
|
data = data.page(params[:page]).per(items_per_page)
|
97
108
|
else
|
98
|
-
data = model
|
109
|
+
data = model.order(sort + " " + order)
|
99
110
|
data = data.where(@plan_field => plans) if !plans.nil?
|
100
111
|
data = data.where(@shopify_plan_name_field => shopify_plans) if !shopify_plans.nil?
|
101
112
|
data = data.page(params[:page]).per(items_per_page)
|
@@ -28,8 +28,19 @@ module AppManager
|
|
28
28
|
response = response_from_cache_for_api(http_method, path, options)
|
29
29
|
failsafe_or_caching_done = true
|
30
30
|
else
|
31
|
-
time_out = Rails.env.development? ? 120 :
|
32
|
-
|
31
|
+
time_out = Rails.env.development? ? 120 : 120
|
32
|
+
begin
|
33
|
+
response = self.class.send(http_method, path, { body: options, timeout: time_out })
|
34
|
+
rescue Net::ReadTimeout => error
|
35
|
+
# Handle timeout error here
|
36
|
+
Rails.logger.info "Net::ReadTimeout: Request timed out. Please try again."
|
37
|
+
response = response_from_failsafe(path, options)
|
38
|
+
rescue StandardError => e
|
39
|
+
# Handle other errors
|
40
|
+
Rails.logger.info "Error: #{e.message}"
|
41
|
+
response = response_from_failsafe(path, options)
|
42
|
+
end
|
43
|
+
|
33
44
|
end
|
34
45
|
if path.include? "/get-status"
|
35
46
|
data = response
|
@@ -42,7 +53,10 @@ module AppManager
|
|
42
53
|
data = parse_data(response.parsed_response)
|
43
54
|
# data = response_from_failsafe(path,options) #uncomment to test failsafe
|
44
55
|
return data
|
45
|
-
|
56
|
+
elsif ((response.class == Hash) && response.has_key?("message"))
|
57
|
+
data = parse_data(response)
|
58
|
+
return data
|
59
|
+
else
|
46
60
|
if failsafe_or_caching_done == true
|
47
61
|
data = response
|
48
62
|
return data
|
@@ -60,7 +74,7 @@ module AppManager
|
|
60
74
|
return fetch_static_cached_response(cache_key)
|
61
75
|
end
|
62
76
|
begin
|
63
|
-
response = self.class.send(http_method, path, { body: options, timeout:
|
77
|
+
response = self.class.send(http_method, path, { body: options, timeout: 1 })
|
64
78
|
if response.class.to_s == "HTTParty::Response" && (response.code.to_s.start_with?('2') or response.code.to_s.start_with?('4')) && (response.code.to_s != '429')
|
65
79
|
Rails.cache.write(cache_key, response, expires_in: AppManager.configuration.expires_in)
|
66
80
|
else
|
@@ -68,6 +82,8 @@ module AppManager
|
|
68
82
|
end
|
69
83
|
rescue Net::ReadTimeout => error
|
70
84
|
response = response_from_failsafe(path,options)
|
85
|
+
rescue StandardError => error
|
86
|
+
response = response_from_failsafe(path, options)
|
71
87
|
rescue Exception => e
|
72
88
|
response = response_from_failsafe(path,options)
|
73
89
|
end
|
@@ -111,6 +127,10 @@ module AppManager
|
|
111
127
|
return @fs.get_local_charge(params,options)
|
112
128
|
when 'has-plan'
|
113
129
|
return @fs.get_local_has_plan(params, options)
|
130
|
+
when 'discount'
|
131
|
+
return @fs.get_local_discount(params, options)
|
132
|
+
when 'use-discount'
|
133
|
+
return @fs.store_discount_used(params,options)
|
114
134
|
else
|
115
135
|
return nil
|
116
136
|
end
|
@@ -26,6 +26,7 @@ module AppManager
|
|
26
26
|
post("/sync-charge", options)
|
27
27
|
end
|
28
28
|
|
29
|
+
|
29
30
|
def get_remaining_days(shop_domain, trial_activated_at = nil, plan_id = nil)
|
30
31
|
get("/get-remaining-days?shop_domain=#{shop_domain}&trial_activated_at=#{trial_activated_at}&plan_id=#{plan_id}")
|
31
32
|
end
|
@@ -42,6 +43,17 @@ module AppManager
|
|
42
43
|
get("/has-plan?shop_domain=#{shop_domain}&plan_id=#{plan_id}&trial_activated_at=#{trial_activated_at}&grandfathered=#{grandfathered}")
|
43
44
|
end
|
44
45
|
|
46
|
+
def get_promotional_discount(shop_domain = nil, code_type, code, reinstall)
|
47
|
+
get("/discount?shop_domain=#{shop_domain}&reinstall=#{reinstall}&code_type=#{code_type}&code=#{code}")
|
48
|
+
end
|
49
|
+
|
50
|
+
def discount_used(shop_domain, discount_id)
|
51
|
+
post('/use-discount', {shop_domain: shop_domain, discount_id: discount_id.to_i})
|
52
|
+
end
|
53
|
+
|
54
|
+
def sync_discount_usage_log(options = {})
|
55
|
+
post("/use-discount-sync", options)
|
56
|
+
end
|
45
57
|
|
46
58
|
end
|
47
59
|
end
|
@@ -52,7 +52,7 @@ module AppManager
|
|
52
52
|
begin
|
53
53
|
save_api_extend_trials(params["extend_trials"])
|
54
54
|
rescue Exception => e
|
55
|
-
Rollbar.error("[
|
55
|
+
Rollbar.error("[Extend Trials] APP MANAGER >>>> #{e.inspect}")
|
56
56
|
end
|
57
57
|
|
58
58
|
begin
|
@@ -60,6 +60,31 @@ module AppManager
|
|
60
60
|
rescue Exception => e
|
61
61
|
Rollbar.error("[Plan User] APP MANAGER >>>> #{e.inspect}")
|
62
62
|
end
|
63
|
+
|
64
|
+
begin
|
65
|
+
save_api_promotional_discounts(params["promotional_discounts"])
|
66
|
+
rescue Exception => e
|
67
|
+
Rollbar.error("[Promotional discounts] APP MANAGER >>>> #{e.inspect}")
|
68
|
+
end
|
69
|
+
|
70
|
+
begin
|
71
|
+
save_api_promotional_discounts_shops(params["promotional_discounts_shops"])
|
72
|
+
rescue Exception => e
|
73
|
+
Rollbar.error("[Promotional discounts shops] APP MANAGER >>>> #{e.inspect}")
|
74
|
+
end
|
75
|
+
|
76
|
+
begin
|
77
|
+
save_api_promotional_discounts_link_plans(params["promotional_discounts_plans"])
|
78
|
+
rescue Exception => e
|
79
|
+
Rollbar.error("[Promotional discounts plans] APP MANAGER >>>> #{e.inspect}")
|
80
|
+
end
|
81
|
+
|
82
|
+
begin
|
83
|
+
save_api_promotional_discounts_usage_log(params["promotional_discounts_usage_log"])
|
84
|
+
rescue Exception => e
|
85
|
+
Rollbar.error("[Promotional discounts usage log] APP MANAGER >>>> #{e.inspect}")
|
86
|
+
end
|
87
|
+
|
63
88
|
end
|
64
89
|
|
65
90
|
def save_api_plans(plans)
|
@@ -185,7 +210,113 @@ module AppManager
|
|
185
210
|
extend_plan_users << AppManager::PlanUser.new(plan_user_id: plan_user['id'],shop_domain: plan_user['shop_domain'], plan_id: plan_user['plan_id'], created_by: plan_user['created_by'], created_at: plan_user['created_at'], updated_at: plan_user['updated_at'])
|
186
211
|
# extend_plan_users << AppManager::PlanUser.new(id: plan_user['id'], shop_domain: plan_user['shop_domain'], plan_id: plan_user['plan_id'], created_by: plan_user['created_by'], created_at: plan_user['created_at'], updated_at: plan_user['updated_at'])
|
187
212
|
end
|
188
|
-
AppManager::
|
213
|
+
AppManager::PlanUser.bulk_import extend_plan_users
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def save_api_promotional_discounts(promotional_discounts)
|
218
|
+
begin
|
219
|
+
AppManager::Discount.connection.truncate(AppManager::Discount.table_name)
|
220
|
+
rescue
|
221
|
+
AppManager::Discount.delete_all
|
222
|
+
end
|
223
|
+
if promotional_discounts.any?
|
224
|
+
promotional_discounts_data = []
|
225
|
+
promotional_discounts.each do |promotional_discount|
|
226
|
+
|
227
|
+
Rails.logger.info " "
|
228
|
+
Rails.logger.info "=== promotional_discount===========#{promotional_discount.inspect}"
|
229
|
+
Rails.logger.info " "
|
230
|
+
|
231
|
+
promotional_discounts_data << AppManager::Discount.new(
|
232
|
+
discount_id: promotional_discount['id'],
|
233
|
+
name: promotional_discount['name'],
|
234
|
+
code: promotional_discount['code'],
|
235
|
+
discount_type: promotional_discount['type'] || 'amount',
|
236
|
+
value: promotional_discount['value'] || 0,
|
237
|
+
duration_intervals: promotional_discount['duration_intervals'],
|
238
|
+
max_usage: promotional_discount['max_usage'],
|
239
|
+
enabled: promotional_discount['enabled'],
|
240
|
+
valid_from: promotional_discount['valid_from'],
|
241
|
+
valid_to: promotional_discount['valid_to'],
|
242
|
+
priority: promotional_discount['priority'] || 0,
|
243
|
+
multiple_uses: promotional_discount['multiple_uses'],
|
244
|
+
multiple_apps: promotional_discount['multiple_apps'],
|
245
|
+
app_id: promotional_discount['app_id'] || 0,
|
246
|
+
created_at: promotional_discount['created_at'],
|
247
|
+
updated_at: promotional_discount['updated_at'],
|
248
|
+
deleted_at: promotional_discount['deleted_at']
|
249
|
+
)
|
250
|
+
end
|
251
|
+
|
252
|
+
Rails.logger.info " "
|
253
|
+
Rails.logger.info "=== promotional_discounts_data===========#{promotional_discounts_data.inspect}"
|
254
|
+
Rails.logger.info " "
|
255
|
+
AppManager::Discount.bulk_import promotional_discounts_data
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def save_api_promotional_discounts_shops(promotional_discounts_shops)
|
260
|
+
|
261
|
+
begin
|
262
|
+
AppManager::DiscountShop.connection.truncate(AppManager::DiscountShop.table_name)
|
263
|
+
rescue
|
264
|
+
AppManager::DiscountShop.delete_all
|
265
|
+
end
|
266
|
+
|
267
|
+
if promotional_discounts_shops.any?
|
268
|
+
promotional_discounts_shop_data = []
|
269
|
+
promotional_discounts_shops.each do |promotional_discounts_shop|
|
270
|
+
promotional_discounts_shop_data << AppManager::DiscountShop.new(
|
271
|
+
discount_id: promotional_discounts_shop['discount_id'],
|
272
|
+
domain: promotional_discounts_shop['domain']
|
273
|
+
)
|
274
|
+
end
|
275
|
+
AppManager::DiscountShop.bulk_import promotional_discounts_shop_data
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def save_api_promotional_discounts_link_plans(promotional_discounts_plans)
|
280
|
+
|
281
|
+
begin
|
282
|
+
AppManager::DiscountLinkPlan.connection.truncate(AppManager::DiscountLinkPlan.table_name)
|
283
|
+
rescue
|
284
|
+
AppManager::DiscountLinkPlan.delete_all
|
285
|
+
end
|
286
|
+
|
287
|
+
if promotional_discounts_plans.any?
|
288
|
+
discount_link_plans_data = []
|
289
|
+
promotional_discounts_plans.each do |link_plan|
|
290
|
+
discount_link_plans_data << AppManager::DiscountLinkPlan.new(
|
291
|
+
discount_id: link_plan['discount_id'],
|
292
|
+
plan_id: link_plan['plan_id']
|
293
|
+
)
|
294
|
+
end
|
295
|
+
AppManager::DiscountLinkPlan.bulk_import discount_link_plans_data
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
def save_api_promotional_discounts_usage_log(promotional_discounts_usage_log)
|
300
|
+
begin
|
301
|
+
AppManager::DiscountUsageLog.connection.truncate(AppManager::DiscountUsageLog.table_name)
|
302
|
+
rescue
|
303
|
+
AppManager::DiscountUsageLog.delete_all
|
304
|
+
end
|
305
|
+
|
306
|
+
if promotional_discounts_usage_log.any?
|
307
|
+
promotional_discounts_usage_log_data = []
|
308
|
+
promotional_discounts_usage_log.each do |log|
|
309
|
+
promotional_discounts_usage_log_data << AppManager::DiscountUsageLog.new(
|
310
|
+
discount_id: log['discount_id'],
|
311
|
+
app_id: log['app_id'],
|
312
|
+
domain: log['domain'],
|
313
|
+
sync: log['sync'],
|
314
|
+
process_type: log['process_type'],
|
315
|
+
created_at: log['created_at'],
|
316
|
+
updated_at: log['updated_at']
|
317
|
+
)
|
318
|
+
end
|
319
|
+
AppManager::DiscountUsageLog.bulk_import promotional_discounts_usage_log_data
|
189
320
|
end
|
190
321
|
end
|
191
322
|
|
@@ -481,6 +612,68 @@ module AppManager
|
|
481
612
|
|
482
613
|
end
|
483
614
|
|
615
|
+
def get_local_discount(params, options)
|
616
|
+
code = [params['code']].pack('H*')
|
617
|
+
code_type = params['code_type']
|
618
|
+
reinstall = params['reinstall']
|
619
|
+
shop_domain = params['shop_domain']
|
620
|
+
now = Time.now
|
621
|
+
|
622
|
+
discount_data = AppManager::Discount.where(enabled: true)
|
623
|
+
.where('valid_from <= ?', now)
|
624
|
+
.where('valid_to >= ?', now)
|
625
|
+
.where(code: code)
|
626
|
+
.first
|
627
|
+
return [] if discount_data.nil?
|
628
|
+
|
629
|
+
discount_shop = AppManager::DiscountShop.where(discount_id: discount_data.discount_id).count
|
630
|
+
|
631
|
+
discount_plan = AppManager::DiscountLinkPlan.where(discount_id: discount_data.discount_id).pluck('plan_id')
|
632
|
+
|
633
|
+
discount_usage = AppManager::DiscountUsageLog.where(discount_id: discount_data.discount_id).count
|
634
|
+
|
635
|
+
discount_usage_by_domain = AppManager::DiscountUsageLog.where(discount_id: discount_data.discount_id)
|
636
|
+
.where(domain: shop_domain)
|
637
|
+
.count
|
638
|
+
if discount_shop > 0
|
639
|
+
discount_shop_specific = AppManager::DiscountShop.where(discount_id: discount_data.discount_id)
|
640
|
+
.where(domain: shop_domain)
|
641
|
+
.first
|
642
|
+
return [] if discount_shop_specific.nil?
|
643
|
+
end
|
644
|
+
|
645
|
+
if discount_data.max_usage.present? && discount_data.max_usage != 0
|
646
|
+
return [] if discount_usage >= discount_data.max_usage
|
647
|
+
end
|
648
|
+
|
649
|
+
if discount_data.multiple_uses == false && discount_usage_by_domain >= 1
|
650
|
+
return []
|
651
|
+
end
|
652
|
+
|
653
|
+
if discount_data.multiple_apps == false
|
654
|
+
discount_usage_by_app = AppManager::DiscountUsageLog
|
655
|
+
.where(discount_id: discount_data.discount_id, domain: shop_domain)
|
656
|
+
.where.not(app_id: discount_data.app_id)
|
657
|
+
.first
|
658
|
+
return [] if discount_usage_by_app.present?
|
659
|
+
end
|
660
|
+
|
661
|
+
|
662
|
+
discount_data = discount_data.attributes.symbolize_keys
|
663
|
+
discount_data[:plan_relation] = discount_plan
|
664
|
+
final_mapped_data = {
|
665
|
+
"id" => discount_data[:discount_id],
|
666
|
+
"name" => discount_data[:name],
|
667
|
+
"type" => discount_data[:discount_type],
|
668
|
+
"value" => discount_data[:value].to_f,
|
669
|
+
"duration_intervals" => discount_data[:duration_intervals],
|
670
|
+
"plan_relation" => discount_data[:plan_relation]
|
671
|
+
} rescue {}
|
672
|
+
|
673
|
+
return JSON.parse(final_mapped_data.to_json)
|
674
|
+
|
675
|
+
end
|
676
|
+
|
484
677
|
def store_local_charge(params, options)
|
485
678
|
message = {"message" => 'fail'}
|
486
679
|
if options
|
@@ -491,7 +684,7 @@ module AppManager
|
|
491
684
|
test_value = charge["test"]
|
492
685
|
plan_id = charge["plan_id"].to_i
|
493
686
|
begin
|
494
|
-
AppManager::Charge.create(charge_id: charge["charge_id"], test: test_value, status: charge["status"], name: charge["name"], type: charge["type"], price: charge["price"], interval: charge["interval"], trial_days: charge["trial_days"], billing_on: charge["billing_on"], activated_on: charge["activated_on"], trial_ends_on: charge["trial_ends_on"], cancelled_on: charge["cancelled_on"], expires_on: charge["expires_on"], plan_id: plan_id, description: charge["description"], shop_domain: charge["shop_domain"], created_at: charge["created_at"], updated_at: charge["updated_at"], sync: 0)
|
687
|
+
AppManager::Charge.create(charge_id: charge["charge_id"], test: test_value, status: charge["status"], name: charge["name"], type: charge["type"], price: charge["price"], interval: charge["interval"], trial_days: charge["trial_days"], billing_on: charge["billing_on"], activated_on: charge["activated_on"], trial_ends_on: charge["trial_ends_on"], cancelled_on: charge["cancelled_on"], expires_on: charge["expires_on"], plan_id: plan_id, description: charge["description"], shop_domain: charge["shop_domain"], created_at: charge["created_at"], updated_at: charge["updated_at"], sync: 0, process_type: 'store-charge')
|
495
688
|
message = {"message" => 'success'}
|
496
689
|
rescue Exception => e
|
497
690
|
Rollbar.error("Charge not saved on local DB due to #{e.inspect}")
|
@@ -511,12 +704,32 @@ module AppManager
|
|
511
704
|
return message
|
512
705
|
end
|
513
706
|
|
707
|
+
def store_discount_used(params,options)
|
708
|
+
if options && options[:shop_domain].present? && options[:discount_id].present?
|
709
|
+
app_id = AppManager::Discount.where(discount_id: options[:discount_id])
|
710
|
+
.pluck(:app_id)
|
711
|
+
.first rescue nil
|
712
|
+
data = {
|
713
|
+
'discount_id' => options[:discount_id],
|
714
|
+
'domain' => options[:shop_domain],
|
715
|
+
'sync' => false,
|
716
|
+
'process_type' => 'use-discount',
|
717
|
+
'app_id' => app_id
|
718
|
+
}
|
719
|
+
discount_usage_log = AppManager::DiscountUsageLog.create(data)
|
720
|
+
return { 'message' => discount_usage_log ? 'success' : 'fail' }
|
721
|
+
else
|
722
|
+
return {"message" => 'fail'}
|
723
|
+
end
|
724
|
+
end
|
725
|
+
|
514
726
|
|
515
727
|
def sync_app_manager
|
516
728
|
plan_obj = AppManager::Client.new
|
517
729
|
response = plan_obj.get_status
|
518
730
|
if response && response.code == 200
|
519
731
|
charges = AppManager::Charge.where(sync: false)
|
732
|
+
discounts_usage_logs = AppManager::DiscountUsageLog.where(sync: false, process_type: 'use-discount')
|
520
733
|
charges.each do |charge|
|
521
734
|
if charge
|
522
735
|
if !charge["cancelled_on"].nil?
|
@@ -529,6 +742,17 @@ module AppManager
|
|
529
742
|
end
|
530
743
|
end
|
531
744
|
end
|
745
|
+
|
746
|
+
if discounts_usage_logs.any?
|
747
|
+
discounts_usage_logs.each do |discount_usage_log|
|
748
|
+
discount_obj = AppManager::Client.new
|
749
|
+
discount_response = discount_obj.sync_discount_usage_log(shop_domain: discount_usage_log['domain'], discount_id: discount_usage_log['discount_id'].to_i)
|
750
|
+
if discount_response && discount_response["data"] == "Saved"
|
751
|
+
AppManager::DiscountUsageLog.find_by(discount_id: discount_usage_log['discount_id'],sync: false).update(sync: true, process_type: nil)
|
752
|
+
end
|
753
|
+
end
|
754
|
+
end
|
755
|
+
|
532
756
|
end
|
533
757
|
end
|
534
758
|
|
@@ -54,7 +54,7 @@ module AppManager
|
|
54
54
|
end
|
55
55
|
|
56
56
|
|
57
|
-
def recurring_charge_api_call(plan,return_url,shop)
|
57
|
+
def recurring_charge_api_call(plan,return_url,shop,discount_cookie)
|
58
58
|
plan_test = nil
|
59
59
|
shop_plan_field = AppManager.configuration.field_names['shopify_plan'] rescue nil
|
60
60
|
if !plan['affiliate'].nil? && plan['affiliate'].any? && !shop_plan_field.nil? && plan['affiliate'].map{|e| e['value']}.include?(shop[shop_plan_field])
|
@@ -67,6 +67,7 @@ module AppManager
|
|
67
67
|
remaining_obj = AppManager::Client.new
|
68
68
|
remaining = remaining_obj.get_remaining_days(shop.shopify_domain,trial_activated_at,plan_id_field)
|
69
69
|
# trial_days = !remaining.nil? ? remaining : trial_days
|
70
|
+
|
70
71
|
if !remaining.nil?
|
71
72
|
if !plan_id_field.nil?
|
72
73
|
plan_obj = AppManager::Client.new
|
@@ -82,31 +83,73 @@ module AppManager
|
|
82
83
|
end
|
83
84
|
end
|
84
85
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
86
|
+
promotional_discount = []
|
87
|
+
if discount_cookie && shop
|
88
|
+
created_at = shop[AppManager.configuration.field_names['created_at']]
|
89
|
+
reinstall = AppManager.check_if_reinstall(created_at)
|
90
|
+
plan_obj = AppManager::Client.new
|
91
|
+
promotional_discount = plan_obj.get_promotional_discount(shop.shopify_domain, discount_cookie['codeType'], discount_cookie['code'], reinstall)
|
92
|
+
promotional_discount = [] if promotional_discount.class.to_s == "Hash" && promotional_discount.has_key?('status') && promotional_discount['status'] == 404
|
93
|
+
end
|
94
|
+
|
95
|
+
if !plan['discount'].nil? && plan['discount'] != 0
|
96
|
+
discount_type = plan['discount_type'] || "percentage"
|
97
|
+
discount_val = discount_type == "percentage" ? (plan['discount'].to_f/ 100) : "#{plan['discount']}"
|
98
|
+
if !@api_version.nil? && @api_version.to_s.include?('2024')
|
99
|
+
plan_discount = if plan['discount'] && plan['cycle_count']
|
100
|
+
{
|
101
|
+
"discount" => { "durationLimitInIntervals" => (plan['cycle_count'].to_i),
|
102
|
+
"value" => {"#{discount_type}" => discount_val}
|
103
|
+
}
|
97
104
|
}
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
105
|
+
elsif plan['discount']
|
106
|
+
{
|
107
|
+
"discount" => { "value" => {"#{discount_type}" => discount_val}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
else
|
111
|
+
{}
|
112
|
+
end
|
113
|
+
else
|
114
|
+
plan_discount = plan['discount'] ? { "discount" => { "durationLimitInIntervals" => (plan['cycle_count'].to_i), "value" => {"#{discount_type}" => discount_val} } } : {}
|
115
|
+
end
|
102
116
|
else
|
103
|
-
|
117
|
+
|
118
|
+
if promotional_discount.any?
|
119
|
+
|
120
|
+
if promotional_discount['plan_relation'].any? && !promotional_discount['plan_relation'].include?(plan['id'])
|
121
|
+
plan_discount = {}
|
122
|
+
else
|
123
|
+
|
124
|
+
discount_type = promotional_discount['type'] || 'percentage'
|
125
|
+
discount_value = {
|
126
|
+
discount_type => discount_type == 'percentage' ? promotional_discount['value'].to_f / 100 : [promotional_discount['value'].to_f, plan['price']].min
|
127
|
+
}
|
128
|
+
|
129
|
+
discount = { 'value' => discount_value }
|
130
|
+
|
131
|
+
discount['durationLimitInIntervals'] = promotional_discount['duration_intervals'].to_i if promotional_discount['duration_intervals'].to_i.positive?
|
132
|
+
plan_discount = { "discount" => discount}
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
104
138
|
end
|
139
|
+
|
140
|
+
discount_exists = !plan['discount'].nil? && plan['discount'] != 0
|
141
|
+
promotional_discount_applies = promotional_discount.present? && promotional_discount.any?
|
142
|
+
promotional_discount_id = discount_exists && promotional_discount_applies ? 0 : promotional_discount_applies ? promotional_discount['id'] : 0
|
143
|
+
|
144
|
+
plans_relation = promotional_discount.present? && promotional_discount['plan_relation'].any? ? promotional_discount['plan_relation'] : []
|
145
|
+
# Append additional data to the existing return_url
|
146
|
+
return_url += "&promo_discount=#{promotional_discount_id}&discounted_plans=#{Rack::Utils.escape(plans_relation.to_json)}"
|
147
|
+
|
105
148
|
price_details = {
|
106
149
|
"price": { "amount": plan['price'], "currencyCode": 'USD' },
|
107
150
|
"interval": plan['interval']['value']
|
108
151
|
}
|
109
|
-
price_details.merge! plan_discount if plan_discount.any?
|
152
|
+
price_details.merge! plan_discount if plan_discount && plan_discount.any?
|
110
153
|
|
111
154
|
plan_var = {
|
112
155
|
"appRecurringPricingDetails": price_details,
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# app/middleware/set_cookie_middleware.rb
|
2
|
+
require 'action_dispatch/middleware/cookies'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
# app/middleware/set_cookie.rb
|
6
|
+
module AppManager
|
7
|
+
class SetCookie
|
8
|
+
def initialize(app, condition)
|
9
|
+
@app = app
|
10
|
+
@condition = condition
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
request = Rack::Request.new(env)
|
15
|
+
|
16
|
+
if @condition.call(request)
|
17
|
+
url = URI.parse(request.url)
|
18
|
+
host = url.host
|
19
|
+
discount_code = request.path.split('/')[2]
|
20
|
+
|
21
|
+
# Set a cookie named 'ShopCircleDiscount' with the extracted values
|
22
|
+
lifetime = Time.now + 60 * 60 * 24 * 365
|
23
|
+
cookie_value = discount_code
|
24
|
+
|
25
|
+
AppManager.clear_cache #clearing cache
|
26
|
+
# Set a 302 response with an external URL and a cookie
|
27
|
+
return [
|
28
|
+
302,
|
29
|
+
{
|
30
|
+
'Location' => 'https://admin.shopify.com/admin/apps/'+ENV['SHOPIFY_APP_SLUG']+'/home/plan' ,
|
31
|
+
'Set-Cookie' => "ShopCircleDiscount=#{cookie_value}; expires=#{lifetime.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')}; path=/; domain=#{host}; secure; HttpOnly; SameSite=None",
|
32
|
+
'Content-Type' => 'text/plain'
|
33
|
+
},
|
34
|
+
['Redirecting to external URL with cookie']
|
35
|
+
]
|
36
|
+
end
|
37
|
+
|
38
|
+
@app.call(env)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/app_manager/version.rb
CHANGED
data/lib/app_manager.rb
CHANGED
@@ -16,8 +16,25 @@ require "app_manager/model"
|
|
16
16
|
require "app_manager/fail_safe"
|
17
17
|
require 'app_manager/railtie' if defined?(Rails)
|
18
18
|
require 'app_manager/exceptions'
|
19
|
+
require 'action_dispatch/middleware/cookies' if defined?(Rails)
|
20
|
+
require "action_controller"
|
19
21
|
|
20
22
|
module AppManager
|
23
|
+
module CookiesHandler
|
24
|
+
include ActionController::Cookies
|
25
|
+
|
26
|
+
def self.resolve_from_cookies(request)
|
27
|
+
if request.cookies['ShopCircleDiscount'].present?
|
28
|
+
{
|
29
|
+
'codeType' => 'normal',
|
30
|
+
'code' => request.cookies['ShopCircleDiscount']
|
31
|
+
}
|
32
|
+
else
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
21
38
|
def self.configure
|
22
39
|
yield configuration
|
23
40
|
end
|
@@ -34,4 +51,14 @@ module AppManager
|
|
34
51
|
end
|
35
52
|
end
|
36
53
|
|
54
|
+
def self.resolve_from_cookies(request)
|
55
|
+
CookiesHandler.resolve_from_cookies(request)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.check_if_reinstall(created_at)
|
59
|
+
created_at < (Time.now - 5.minutes) ? 1 : 0
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
37
64
|
end
|
@@ -39,6 +39,14 @@ module AppManager
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
def create_discount_table_migration
|
43
|
+
if self.class.migration_exists?("db/app_manager", "add_discount_tables")
|
44
|
+
say_status("skipped", "Migration add_discount_tables.rb already exists")
|
45
|
+
else
|
46
|
+
migration_template("add_discount_tables.erb", "db/app_manager/add_discount_tables.rb")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
42
50
|
|
43
51
|
private
|
44
52
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class AddDiscountTables < ActiveRecord::Migration[<%= rails_migration_version %>]
|
2
|
+
def change
|
3
|
+
create_table :discounts do |t|
|
4
|
+
t.bigint :discount_id
|
5
|
+
t.string :name
|
6
|
+
t.string :code
|
7
|
+
t.string :discount_type, default: 'amount'
|
8
|
+
t.decimal :value, default: 0
|
9
|
+
t.integer :duration_intervals
|
10
|
+
t.integer :max_usage
|
11
|
+
t.boolean :enabled, default: true
|
12
|
+
t.datetime :valid_from
|
13
|
+
t.datetime :valid_to
|
14
|
+
t.integer :priority, default: 0
|
15
|
+
t.boolean :multiple_uses, default: true
|
16
|
+
t.boolean :multiple_apps, default: true
|
17
|
+
t.integer :app_id, default: 0
|
18
|
+
t.timestamps
|
19
|
+
t.datetime :deleted_at
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table :discount_shops do |t|
|
23
|
+
t.bigint :discount_id, index: true, foreign_key: true
|
24
|
+
t.string :domain
|
25
|
+
end
|
26
|
+
|
27
|
+
create_table :discounts_usage_log do |t|
|
28
|
+
t.bigint :discount_id, index: true, foreign_key: true
|
29
|
+
t.bigint :app_id, index: true, foreign_key: true
|
30
|
+
t.string :domain
|
31
|
+
t.boolean :sync, default: true
|
32
|
+
t.string :process_type
|
33
|
+
t.timestamps
|
34
|
+
end
|
35
|
+
|
36
|
+
create_table :discount_link_plans do |t|
|
37
|
+
t.bigint :discount_id, index: true, foreign_key: true
|
38
|
+
t.bigint :plan_id, index: true, foreign_key: true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def down
|
43
|
+
drop_table :discounts
|
44
|
+
drop_table :discount_shops
|
45
|
+
drop_table :discounts_usage_log
|
46
|
+
drop_table :discount_link_plans
|
47
|
+
end
|
48
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: app_manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rahul Tiwari @ Hulkapps
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -89,7 +89,11 @@ files:
|
|
89
89
|
- app/model/app_manager/app_manager_record.rb
|
90
90
|
- app/model/app_manager/app_structure.rb
|
91
91
|
- app/model/app_manager/charge.rb
|
92
|
+
- app/model/app_manager/discount.rb
|
93
|
+
- app/model/app_manager/discount_link_plan.rb
|
92
94
|
- app/model/app_manager/discount_plan.rb
|
95
|
+
- app/model/app_manager/discount_shop.rb
|
96
|
+
- app/model/app_manager/discount_usage_log.rb
|
93
97
|
- app/model/app_manager/extend_trial.rb
|
94
98
|
- app/model/app_manager/plan.rb
|
95
99
|
- app/model/app_manager/plan_user.rb
|
@@ -115,9 +119,11 @@ files:
|
|
115
119
|
- lib/app_manager/protection.rb
|
116
120
|
- lib/app_manager/railtie.rb
|
117
121
|
- lib/app_manager/response_cache.rb
|
122
|
+
- lib/app_manager/set_cookie.rb
|
118
123
|
- lib/app_manager/tasks/sync/local_app_manager.rake
|
119
124
|
- lib/app_manager/version.rb
|
120
125
|
- lib/generators/app_manager/install/install_generator.rb
|
126
|
+
- lib/generators/app_manager/install/templates/add_discount_tables.erb
|
121
127
|
- lib/generators/app_manager/install/templates/add_external_charge_field.erb
|
122
128
|
- lib/generators/app_manager/install/templates/add_plan_trial_grandfathered_to_shops.erb
|
123
129
|
- lib/generators/app_manager/install/templates/app_manager.rb.tt
|