app_manager 1.7.0 → 2.2.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +73 -75
- data/README.md +36 -1
- data/app/controllers/app_manager/charges_controller.rb +22 -1
- data/app/controllers/app_manager/plans_controller.rb +10 -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 +26 -4
- data/lib/app_manager/client/plans.rb +16 -0
- data/lib/app_manager/fail_safe.rb +223 -3
- data/lib/app_manager/graphql_helper.rb +59 -19
- data/lib/app_manager/set_local_storage.rb +34 -0
- data/lib/app_manager/version.rb +1 -1
- 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: f97b31c44449e934975e233f07a745d883e58abd3a29ccd30537ec0e1ba6bca2
|
|
4
|
+
data.tar.gz: 863e6b243cd1c16839c4d5c9d7f3a3a0b1b47909ce613c9ff075e21d996ce314
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 31f071cf42a3cfec28b0fae59cedfc72c2b24b80a85c237932acf0d118807977a961aa199ebd5435f5ddcb4f9310a27ac47589b35db953f39e61fbdd7e6d25d6
|
|
7
|
+
data.tar.gz: 67769978a3d30041d329e02a22432dad4d936a5254ac711e118a03be50101e11260aa22929a2c210ddbec027c44b60fa807f0c51dc494e6aac92a16033b8b83d
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
app_manager (
|
|
4
|
+
app_manager (2.2.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
|
-
activerecord-import (1.
|
|
71
|
+
activerecord-import (1.6.0)
|
|
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.7)
|
|
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
|
-
mini_portile2 (2.8.
|
|
142
|
-
minitest (5.
|
|
140
|
+
mini_portile2 (2.8.6)
|
|
141
|
+
minitest (5.22.3)
|
|
143
142
|
multi_xml (0.6.0)
|
|
144
143
|
mutex_m (0.2.0)
|
|
145
144
|
net-imap (0.3.7)
|
|
@@ -149,10 +148,10 @@ GEM
|
|
|
149
148
|
net-protocol
|
|
150
149
|
net-protocol (0.2.2)
|
|
151
150
|
timeout
|
|
152
|
-
net-smtp (0.
|
|
151
|
+
net-smtp (0.5.0)
|
|
153
152
|
net-protocol
|
|
154
|
-
nio4r (2.7.
|
|
155
|
-
nokogiri (1.15.
|
|
153
|
+
nio4r (2.7.1)
|
|
154
|
+
nokogiri (1.15.6)
|
|
156
155
|
mini_portile2 (~> 2.8.2)
|
|
157
156
|
racc (~> 1.4)
|
|
158
157
|
pry (0.14.1)
|
|
@@ -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.10)
|
|
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,18 +190,18 @@ 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)
|
|
200
199
|
thor (~> 1.0, >= 1.2.2)
|
|
201
200
|
zeitwerk (~> 2.6)
|
|
202
201
|
rake (13.0.6)
|
|
203
|
-
rdoc (6.6.
|
|
202
|
+
rdoc (6.6.3.1)
|
|
204
203
|
psych (>= 4.0.0)
|
|
205
|
-
reline (0.
|
|
204
|
+
reline (0.5.1)
|
|
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:
|
|
@@ -41,6 +41,7 @@ module AppManager
|
|
|
41
41
|
end
|
|
42
42
|
if @shop.update(update_info)
|
|
43
43
|
begin
|
|
44
|
+
plan_data['old_plan'] = params[:old_plan] || nil;
|
|
44
45
|
AppManager::EventHandler.new('charge_created', {
|
|
45
46
|
"plan" => plan_data,
|
|
46
47
|
"charge" => nil,
|
|
@@ -58,9 +59,13 @@ module AppManager
|
|
|
58
59
|
end
|
|
59
60
|
end
|
|
60
61
|
request_data = {'shop' => @shop.shopify_domain, 'timestamp' => Time.now.to_i, 'plan' => params[:plan_id]}
|
|
62
|
+
request_data.merge!('host' => params['host']) if params['host'].present?
|
|
63
|
+
request_data.merge!('old_plan' => params['old_plan']) if params['old_plan'].present?
|
|
64
|
+
|
|
61
65
|
return_url = "#{app_url}#{plan_callback_path}?#{Rack::Utils.build_query(request_data)}"
|
|
62
66
|
gq_obj = AppManager::GraphqlHelper.new(@shop.shopify_domain, @shop.shopify_token)
|
|
63
|
-
|
|
67
|
+
discount_local_storage = params[:discount_code].present? && !params[:discount_code].nil? ? params[:discount_code] : nil
|
|
68
|
+
data = gq_obj.recurring_charge_api_call(plan_data, return_url, @shop,discount_local_storage)
|
|
64
69
|
if data.present? && !data["errors"].present? && (data["data"].present? && data["data"]["appSubscriptionCreate"].present? && (!data["data"]["appSubscriptionCreate"]["userErrors"].any? && data["data"]["appSubscriptionCreate"]["confirmationUrl"]))
|
|
65
70
|
redirect_charge = data["data"]["appSubscriptionCreate"]["confirmationUrl"]
|
|
66
71
|
render json: {'redirect_url' => redirect_charge}
|
|
@@ -85,6 +90,7 @@ module AppManager
|
|
|
85
90
|
shopify_token = @field_names['shopify_token']
|
|
86
91
|
shopify_domain = @field_names['name']
|
|
87
92
|
grandfathered_field = @field_names['grandfathered']
|
|
93
|
+
discounted_plans = []
|
|
88
94
|
if !@shop.nil?
|
|
89
95
|
old_plan_id = @shop[@plan_field]
|
|
90
96
|
old_plan_data = nil
|
|
@@ -131,8 +137,23 @@ module AppManager
|
|
|
131
137
|
rescue Exception => e
|
|
132
138
|
Rollbar.error("Error in APP MANAGER Charge Created Callback >>>> #{e.inspect}")
|
|
133
139
|
end
|
|
140
|
+
|
|
141
|
+
begin
|
|
142
|
+
plan_obj = AppManager::Client.new
|
|
143
|
+
if params[:discount].present? && !params[:discount].nil?
|
|
144
|
+
discounted_plans = plan_obj.get_related_discounted_plans(params[:discount])
|
|
145
|
+
if discounted_plans.empty? || discounted_plans.include?(params[:plan].to_i)
|
|
146
|
+
plan_obj.discount_used(@shop[shopify_domain], params[:discount])
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
rescue
|
|
150
|
+
Rollbar.error("Error in APP MANAGER Discount used API call >>>> #{e.inspect}")
|
|
151
|
+
end
|
|
134
152
|
end
|
|
135
153
|
end
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
136
157
|
embed_host = Base64.encode64(params[:shop] + "/admin")
|
|
137
158
|
|
|
138
159
|
if !old_plan_id.nil?
|
|
@@ -65,8 +65,16 @@ module AppManager
|
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
promotional_discount = []
|
|
69
|
+
if params[:discount_code].present? && !params[:discount_code].nil? && @shop
|
|
70
|
+
discount_local_storage = params[:discount_code]
|
|
71
|
+
plan_obj = AppManager::Client.new
|
|
72
|
+
promotional_discount = plan_obj.get_promotional_discount(params[:shop_domain],discount_local_storage)
|
|
73
|
+
promotional_discount = [] if promotional_discount.class.to_s == "Hash" && promotional_discount.has_key?('status') && promotional_discount['status'] == 404
|
|
74
|
+
end
|
|
68
75
|
response = {
|
|
69
76
|
'plans' => plans,
|
|
77
|
+
'promotional_discount' => promotional_discount,
|
|
70
78
|
'shopify_plan' => shopify_plan,
|
|
71
79
|
'plan' => plan,
|
|
72
80
|
'default_plan_id' => default_plan_id,
|
|
@@ -90,12 +98,12 @@ module AppManager
|
|
|
90
98
|
@shopify_email = AppManager.configuration.field_names['shopify_email']
|
|
91
99
|
@shopify_plan_name_field = AppManager.configuration.field_names['shopify_plan']
|
|
92
100
|
if params[:search]
|
|
93
|
-
data = model.where("#{@shopify_domain} LIKE :search OR #{@shopify_email} LIKE :search", search: "%#{search}%")
|
|
101
|
+
data = model.where("#{@shopify_domain} LIKE :search OR #{@shopify_email} LIKE :search", search: "%#{search}%").order(sort + " " + order)
|
|
94
102
|
data = data.where(@plan_field => plans) if !plans.nil?
|
|
95
103
|
data = data.where(@shopify_plan_name_field => shopify_plans) if !shopify_plans.nil?
|
|
96
104
|
data = data.page(params[:page]).per(items_per_page)
|
|
97
105
|
else
|
|
98
|
-
data = model
|
|
106
|
+
data = model.order(sort + " " + order)
|
|
99
107
|
data = data.where(@plan_field => plans) if !plans.nil?
|
|
100
108
|
data = data.where(@shopify_plan_name_field => shopify_plans) if !shopify_plans.nil?
|
|
101
109
|
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: 120 })
|
|
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,12 @@ 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)
|
|
134
|
+
when 'get-related-discounted-plans'
|
|
135
|
+
return @fs.get_local_related_discounted_plans(params,options)
|
|
114
136
|
else
|
|
115
137
|
return nil
|
|
116
138
|
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,21 @@ 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)
|
|
47
|
+
get("/discount?shop_domain=#{shop_domain}&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
|
|
57
|
+
|
|
58
|
+
def get_related_discounted_plans(discount_id)
|
|
59
|
+
get("/get-related-discounted-plans?discount_id=#{discount_id}")
|
|
60
|
+
end
|
|
45
61
|
|
|
46
62
|
end
|
|
47
63
|
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,106 @@ 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
|
+
promotional_discounts_data << AppManager::Discount.new(
|
|
228
|
+
discount_id: promotional_discount['id'],
|
|
229
|
+
name: promotional_discount['name'],
|
|
230
|
+
code: promotional_discount['code'],
|
|
231
|
+
discount_type: promotional_discount['type'] || 'amount',
|
|
232
|
+
value: promotional_discount['value'] || 0,
|
|
233
|
+
duration_intervals: promotional_discount['duration_intervals'],
|
|
234
|
+
max_usage: promotional_discount['max_usage'],
|
|
235
|
+
enabled: promotional_discount['enabled'],
|
|
236
|
+
valid_from: promotional_discount['valid_from'],
|
|
237
|
+
valid_to: promotional_discount['valid_to'],
|
|
238
|
+
priority: promotional_discount['priority'] || 0,
|
|
239
|
+
multiple_uses: promotional_discount['multiple_uses'],
|
|
240
|
+
multiple_apps: promotional_discount['multiple_apps'],
|
|
241
|
+
app_id: promotional_discount['app_id'] || 0,
|
|
242
|
+
created_at: promotional_discount['created_at'],
|
|
243
|
+
updated_at: promotional_discount['updated_at'],
|
|
244
|
+
deleted_at: promotional_discount['deleted_at']
|
|
245
|
+
)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
AppManager::Discount.bulk_import promotional_discounts_data
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def save_api_promotional_discounts_shops(promotional_discounts_shops)
|
|
253
|
+
|
|
254
|
+
begin
|
|
255
|
+
AppManager::DiscountShop.connection.truncate(AppManager::DiscountShop.table_name)
|
|
256
|
+
rescue
|
|
257
|
+
AppManager::DiscountShop.delete_all
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
if promotional_discounts_shops.any?
|
|
261
|
+
promotional_discounts_shop_data = []
|
|
262
|
+
promotional_discounts_shops.each do |promotional_discounts_shop|
|
|
263
|
+
promotional_discounts_shop_data << AppManager::DiscountShop.new(
|
|
264
|
+
discount_id: promotional_discounts_shop['discount_id'],
|
|
265
|
+
domain: promotional_discounts_shop['domain']
|
|
266
|
+
)
|
|
267
|
+
end
|
|
268
|
+
AppManager::DiscountShop.bulk_import promotional_discounts_shop_data
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def save_api_promotional_discounts_link_plans(promotional_discounts_plans)
|
|
273
|
+
|
|
274
|
+
begin
|
|
275
|
+
AppManager::DiscountLinkPlan.connection.truncate(AppManager::DiscountLinkPlan.table_name)
|
|
276
|
+
rescue
|
|
277
|
+
AppManager::DiscountLinkPlan.delete_all
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
if promotional_discounts_plans.any?
|
|
281
|
+
discount_link_plans_data = []
|
|
282
|
+
promotional_discounts_plans.each do |link_plan|
|
|
283
|
+
discount_link_plans_data << AppManager::DiscountLinkPlan.new(
|
|
284
|
+
discount_id: link_plan['discount_id'],
|
|
285
|
+
plan_id: link_plan['plan_id']
|
|
286
|
+
)
|
|
287
|
+
end
|
|
288
|
+
AppManager::DiscountLinkPlan.bulk_import discount_link_plans_data
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def save_api_promotional_discounts_usage_log(promotional_discounts_usage_log)
|
|
293
|
+
begin
|
|
294
|
+
AppManager::DiscountUsageLog.connection.truncate(AppManager::DiscountUsageLog.table_name)
|
|
295
|
+
rescue
|
|
296
|
+
AppManager::DiscountUsageLog.delete_all
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
if promotional_discounts_usage_log.any?
|
|
300
|
+
promotional_discounts_usage_log_data = []
|
|
301
|
+
promotional_discounts_usage_log.each do |log|
|
|
302
|
+
promotional_discounts_usage_log_data << AppManager::DiscountUsageLog.new(
|
|
303
|
+
discount_id: log['discount_id'],
|
|
304
|
+
app_id: log['app_id'],
|
|
305
|
+
domain: log['domain'],
|
|
306
|
+
sync: log['sync'],
|
|
307
|
+
process_type: log['process_type'],
|
|
308
|
+
created_at: log['created_at'],
|
|
309
|
+
updated_at: log['updated_at']
|
|
310
|
+
)
|
|
311
|
+
end
|
|
312
|
+
AppManager::DiscountUsageLog.bulk_import promotional_discounts_usage_log_data
|
|
189
313
|
end
|
|
190
314
|
end
|
|
191
315
|
|
|
@@ -481,6 +605,71 @@ module AppManager
|
|
|
481
605
|
|
|
482
606
|
end
|
|
483
607
|
|
|
608
|
+
def get_local_discount(params, options)
|
|
609
|
+
code = [params['code']].pack('H*')
|
|
610
|
+
shop_domain = params['shop_domain']
|
|
611
|
+
now = Time.now
|
|
612
|
+
|
|
613
|
+
discount_data = AppManager::Discount.where(enabled: true)
|
|
614
|
+
.where('valid_from <= ?', now)
|
|
615
|
+
.where('valid_to IS NULL OR valid_to >= ?', now)
|
|
616
|
+
.where(code: code)
|
|
617
|
+
.first
|
|
618
|
+
return [] if discount_data.nil?
|
|
619
|
+
|
|
620
|
+
discount_shop = AppManager::DiscountShop.where(discount_id: discount_data.discount_id).count
|
|
621
|
+
|
|
622
|
+
discount_plan = AppManager::DiscountLinkPlan.where(discount_id: discount_data.discount_id).pluck('plan_id')
|
|
623
|
+
|
|
624
|
+
discount_usage = AppManager::DiscountUsageLog.where(discount_id: discount_data.discount_id).count
|
|
625
|
+
|
|
626
|
+
discount_usage_by_domain = AppManager::DiscountUsageLog.where(discount_id: discount_data.discount_id)
|
|
627
|
+
.where(domain: shop_domain)
|
|
628
|
+
.count
|
|
629
|
+
if discount_shop > 0
|
|
630
|
+
discount_shop_specific = AppManager::DiscountShop.where(discount_id: discount_data.discount_id)
|
|
631
|
+
.where(domain: shop_domain)
|
|
632
|
+
.first
|
|
633
|
+
return [] if discount_shop_specific.nil?
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
if discount_data.max_usage.present? && discount_data.max_usage != 0
|
|
637
|
+
return [] if discount_usage >= discount_data.max_usage
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
if discount_data.multiple_uses == false && discount_usage_by_domain >= 1
|
|
641
|
+
return []
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
if discount_data.multiple_apps == false
|
|
645
|
+
discount_usage_by_app = AppManager::DiscountUsageLog
|
|
646
|
+
.where(discount_id: discount_data.discount_id, domain: shop_domain)
|
|
647
|
+
.where.not(app_id: discount_data.app_id)
|
|
648
|
+
.first
|
|
649
|
+
return [] if discount_usage_by_app.present?
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
discount_data = discount_data.attributes.symbolize_keys
|
|
654
|
+
discount_data[:plan_relation] = discount_plan
|
|
655
|
+
final_mapped_data = {
|
|
656
|
+
"id" => discount_data[:discount_id],
|
|
657
|
+
"name" => discount_data[:name],
|
|
658
|
+
"type" => discount_data[:discount_type],
|
|
659
|
+
"value" => discount_data[:value].to_f,
|
|
660
|
+
"duration_intervals" => discount_data[:duration_intervals],
|
|
661
|
+
"plan_relation" => discount_data[:plan_relation]
|
|
662
|
+
} rescue {}
|
|
663
|
+
|
|
664
|
+
return JSON.parse(final_mapped_data.to_json)
|
|
665
|
+
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
def get_local_related_discounted_plans(params, options)
|
|
669
|
+
discounted_plans = DiscountLinkPlan.where(discount_id: params['discount_id']).pluck(:plan_id) rescue []
|
|
670
|
+
return discounted_plans
|
|
671
|
+
end
|
|
672
|
+
|
|
484
673
|
def store_local_charge(params, options)
|
|
485
674
|
message = {"message" => 'fail'}
|
|
486
675
|
if options
|
|
@@ -491,7 +680,7 @@ module AppManager
|
|
|
491
680
|
test_value = charge["test"]
|
|
492
681
|
plan_id = charge["plan_id"].to_i
|
|
493
682
|
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)
|
|
683
|
+
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
684
|
message = {"message" => 'success'}
|
|
496
685
|
rescue Exception => e
|
|
497
686
|
Rollbar.error("Charge not saved on local DB due to #{e.inspect}")
|
|
@@ -511,12 +700,32 @@ module AppManager
|
|
|
511
700
|
return message
|
|
512
701
|
end
|
|
513
702
|
|
|
703
|
+
def store_discount_used(params,options)
|
|
704
|
+
if options && options[:shop_domain].present? && options[:discount_id].present?
|
|
705
|
+
app_id = AppManager::Discount.where(discount_id: options[:discount_id])
|
|
706
|
+
.pluck(:app_id)
|
|
707
|
+
.first rescue nil
|
|
708
|
+
data = {
|
|
709
|
+
'discount_id' => options[:discount_id],
|
|
710
|
+
'domain' => options[:shop_domain],
|
|
711
|
+
'sync' => false,
|
|
712
|
+
'process_type' => 'use-discount',
|
|
713
|
+
'app_id' => app_id
|
|
714
|
+
}
|
|
715
|
+
discount_usage_log = AppManager::DiscountUsageLog.create(data)
|
|
716
|
+
return { 'message' => discount_usage_log ? 'success' : 'fail' }
|
|
717
|
+
else
|
|
718
|
+
return {"message" => 'fail'}
|
|
719
|
+
end
|
|
720
|
+
end
|
|
721
|
+
|
|
514
722
|
|
|
515
723
|
def sync_app_manager
|
|
516
724
|
plan_obj = AppManager::Client.new
|
|
517
725
|
response = plan_obj.get_status
|
|
518
726
|
if response && response.code == 200
|
|
519
727
|
charges = AppManager::Charge.where(sync: false)
|
|
728
|
+
discounts_usage_logs = AppManager::DiscountUsageLog.where(sync: false, process_type: 'use-discount')
|
|
520
729
|
charges.each do |charge|
|
|
521
730
|
if charge
|
|
522
731
|
if !charge["cancelled_on"].nil?
|
|
@@ -529,6 +738,17 @@ module AppManager
|
|
|
529
738
|
end
|
|
530
739
|
end
|
|
531
740
|
end
|
|
741
|
+
|
|
742
|
+
if discounts_usage_logs.any?
|
|
743
|
+
discounts_usage_logs.each do |discount_usage_log|
|
|
744
|
+
discount_obj = AppManager::Client.new
|
|
745
|
+
discount_response = discount_obj.sync_discount_usage_log(shop_domain: discount_usage_log['domain'], discount_id: discount_usage_log['discount_id'].to_i)
|
|
746
|
+
if discount_response && discount_response["data"] == "Saved"
|
|
747
|
+
AppManager::DiscountUsageLog.find_by(discount_id: discount_usage_log['discount_id'],sync: false).update(sync: true, process_type: nil)
|
|
748
|
+
end
|
|
749
|
+
end
|
|
750
|
+
end
|
|
751
|
+
|
|
532
752
|
end
|
|
533
753
|
end
|
|
534
754
|
|
|
@@ -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_local_storage)
|
|
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,70 @@ 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_local_storage.nil? && shop
|
|
88
|
+
plan_obj = AppManager::Client.new
|
|
89
|
+
promotional_discount = plan_obj.get_promotional_discount(shop.shopify_domain, discount_local_storage)
|
|
90
|
+
promotional_discount = [] if promotional_discount.class.to_s == "Hash" && promotional_discount.has_key?('status') && promotional_discount['status'] == 404
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
if !plan['discount'].nil? && plan['discount'] != 0
|
|
94
|
+
discount_type = plan['discount_type'] || "percentage"
|
|
95
|
+
discount_val = discount_type == "percentage" ? (plan['discount'].to_f/ 100) : "#{plan['discount']}"
|
|
96
|
+
if !@api_version.nil? && @api_version.to_s.include?('2024')
|
|
97
|
+
plan_discount = if plan['discount'] && plan['cycle_count']
|
|
98
|
+
{
|
|
99
|
+
"discount" => { "durationLimitInIntervals" => (plan['cycle_count'].to_i),
|
|
100
|
+
"value" => {"#{discount_type}" => discount_val}
|
|
101
|
+
}
|
|
97
102
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
103
|
+
elsif plan['discount']
|
|
104
|
+
{
|
|
105
|
+
"discount" => { "value" => {"#{discount_type}" => discount_val}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else
|
|
109
|
+
{}
|
|
110
|
+
end
|
|
111
|
+
else
|
|
112
|
+
plan_discount = plan['discount'] ? { "discount" => { "durationLimitInIntervals" => (plan['cycle_count'].to_i), "value" => {"#{discount_type}" => discount_val} } } : {}
|
|
113
|
+
end
|
|
102
114
|
else
|
|
103
|
-
|
|
115
|
+
|
|
116
|
+
if promotional_discount.any?
|
|
117
|
+
|
|
118
|
+
if promotional_discount['plan_relation'].any? && !promotional_discount['plan_relation'].include?(plan['id'])
|
|
119
|
+
plan_discount = {}
|
|
120
|
+
else
|
|
121
|
+
|
|
122
|
+
discount_type = promotional_discount['type'] || 'percentage'
|
|
123
|
+
discount_value = {
|
|
124
|
+
discount_type => discount_type == 'percentage' ? promotional_discount['value'].to_f / 100 : [promotional_discount['value'].to_f, plan['price']].min
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
discount = { 'value' => discount_value }
|
|
128
|
+
|
|
129
|
+
discount['durationLimitInIntervals'] = promotional_discount['duration_intervals'].to_i if promotional_discount['duration_intervals'].to_i.positive?
|
|
130
|
+
plan_discount = { "discount" => discount}
|
|
131
|
+
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
|
|
104
136
|
end
|
|
137
|
+
|
|
138
|
+
discount_exists = !plan['discount'].nil? && plan['discount'] != 0
|
|
139
|
+
promotional_discount_applies = promotional_discount.present? && promotional_discount.any?
|
|
140
|
+
promotional_discount_id = discount_exists && promotional_discount_applies ? 0 : promotional_discount_applies ? promotional_discount['id'] : 0
|
|
141
|
+
|
|
142
|
+
return_url += "&discount=#{promotional_discount_id}"
|
|
143
|
+
|
|
144
|
+
|
|
105
145
|
price_details = {
|
|
106
146
|
"price": { "amount": plan['price'], "currencyCode": 'USD' },
|
|
107
147
|
"interval": plan['interval']['value']
|
|
108
148
|
}
|
|
109
|
-
price_details.merge! plan_discount if plan_discount.any?
|
|
149
|
+
price_details.merge! plan_discount if plan_discount && plan_discount.any?
|
|
110
150
|
|
|
111
151
|
plan_var = {
|
|
112
152
|
"appRecurringPricingDetails": price_details,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
|
|
3
|
+
# app/middleware/set_cookie.rb
|
|
4
|
+
module AppManager
|
|
5
|
+
class SetLocalStorage
|
|
6
|
+
def initialize(app, condition,destination_url)
|
|
7
|
+
@app = app
|
|
8
|
+
@condition = condition
|
|
9
|
+
@destination_url = destination_url
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(env)
|
|
13
|
+
request = Rack::Request.new(env)
|
|
14
|
+
|
|
15
|
+
if @condition.call(request)
|
|
16
|
+
url = URI.parse(request.url)
|
|
17
|
+
host = url.host
|
|
18
|
+
discount_code = request.path.split('/')[2] rescue ''
|
|
19
|
+
AppManager.clear_cache #clearing cache
|
|
20
|
+
# Set a 302 response with an external URL and a cookie
|
|
21
|
+
return [
|
|
22
|
+
302,
|
|
23
|
+
{
|
|
24
|
+
'Location' => "#{@destination_url}?discount_code=#{discount_code}" ,
|
|
25
|
+
'Content-Type' => 'text/plain'
|
|
26
|
+
},
|
|
27
|
+
['Redirecting to external URL with cookie']
|
|
28
|
+
]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
@app.call(env)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/app_manager/version.rb
CHANGED
|
@@ -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.2.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-04-19 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_local_storage.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
|