app_manager 1.6.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c143606bbac6f53820f8522a8a735c33a1d241bc6c2bc919d75bb8319d44aebf
4
- data.tar.gz: 770f14a16a4c912389bfd71106a517af68e724645cc68bd6c9153d61b0d34dee
3
+ metadata.gz: 1093f4ae3ee06a00f81bf11ad98bb1669f6b9f931bed69a430525733058143a0
4
+ data.tar.gz: 9a3a425bdf82d12982f33ace1e86a1e5b47bbc7b3430ccd96b0469967cbf2f65
5
5
  SHA512:
6
- metadata.gz: 40a9cdb0477e5c3b3aa51cc8d5f03be15deab919199f101b237cb0063db42e2d160e72a52aa111b56f5736c1fcadc4a16cd557a45bed0c2fbf914e285eb1763d
7
- data.tar.gz: efdc457510fb1372aa92915d8109f0fd0963dc49d7b18564a725527b932efa3e295d47249b2d75340d00ee517cd47cfbfa30c32b1a7177c5de12130d2396b10e
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 (1.6.3)
4
+ app_manager (2.0.0)
5
5
  activerecord-import (~> 1.4)
6
6
  httparty
7
7
  kaminari (>= 0.16.3)
@@ -10,93 +10,110 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- actioncable (7.0.5)
14
- actionpack (= 7.0.5)
15
- activesupport (= 7.0.5)
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
- actionmailbox (7.0.5)
19
- actionpack (= 7.0.5)
20
- activejob (= 7.0.5)
21
- activerecord (= 7.0.5)
22
- activestorage (= 7.0.5)
23
- activesupport (= 7.0.5)
18
+ zeitwerk (~> 2.6)
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)
24
25
  mail (>= 2.7.1)
25
26
  net-imap
26
27
  net-pop
27
28
  net-smtp
28
- actionmailer (7.0.5)
29
- actionpack (= 7.0.5)
30
- actionview (= 7.0.5)
31
- activejob (= 7.0.5)
32
- activesupport (= 7.0.5)
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)
33
34
  mail (~> 2.5, >= 2.5.4)
34
35
  net-imap
35
36
  net-pop
36
37
  net-smtp
37
- rails-dom-testing (~> 2.0)
38
- actionpack (7.0.5)
39
- actionview (= 7.0.5)
40
- activesupport (= 7.0.5)
41
- rack (~> 2.0, >= 2.2.4)
38
+ rails-dom-testing (~> 2.2)
39
+ actionpack (7.1.3.2)
40
+ actionview (= 7.1.3.2)
41
+ activesupport (= 7.1.3.2)
42
+ nokogiri (>= 1.8.5)
43
+ racc
44
+ rack (>= 2.2.4)
45
+ rack-session (>= 1.0.1)
42
46
  rack-test (>= 0.6.3)
43
- rails-dom-testing (~> 2.0)
44
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
45
- actiontext (7.0.5)
46
- actionpack (= 7.0.5)
47
- activerecord (= 7.0.5)
48
- activestorage (= 7.0.5)
49
- activesupport (= 7.0.5)
47
+ rails-dom-testing (~> 2.2)
48
+ rails-html-sanitizer (~> 1.6)
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)
50
54
  globalid (>= 0.6.0)
51
55
  nokogiri (>= 1.8.5)
52
- actionview (7.0.5)
53
- activesupport (= 7.0.5)
56
+ actionview (7.1.3.2)
57
+ activesupport (= 7.1.3.2)
54
58
  builder (~> 3.1)
55
- erubi (~> 1.4)
56
- rails-dom-testing (~> 2.0)
57
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
58
- activejob (7.0.5)
59
- activesupport (= 7.0.5)
59
+ erubi (~> 1.11)
60
+ rails-dom-testing (~> 2.2)
61
+ rails-html-sanitizer (~> 1.6)
62
+ activejob (7.1.3.2)
63
+ activesupport (= 7.1.3.2)
60
64
  globalid (>= 0.3.6)
61
- activemodel (7.0.5)
62
- activesupport (= 7.0.5)
63
- activerecord (7.0.5)
64
- activemodel (= 7.0.5)
65
- activesupport (= 7.0.5)
66
- activerecord-import (1.4.1)
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
+ timeout (>= 0.4.0)
71
+ activerecord-import (1.5.1)
67
72
  activerecord (>= 4.2)
68
- activestorage (7.0.5)
69
- actionpack (= 7.0.5)
70
- activejob (= 7.0.5)
71
- activerecord (= 7.0.5)
72
- activesupport (= 7.0.5)
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)
73
78
  marcel (~> 1.0)
74
- mini_mime (>= 1.1.0)
75
- activesupport (7.0.5)
79
+ activesupport (7.1.3.2)
80
+ base64
81
+ bigdecimal
76
82
  concurrent-ruby (~> 1.0, >= 1.0.2)
83
+ connection_pool (>= 2.2.5)
84
+ drb
77
85
  i18n (>= 1.6, < 2)
78
86
  minitest (>= 5.1)
87
+ mutex_m
79
88
  tzinfo (~> 2.0)
80
89
  addressable (2.8.0)
81
90
  public_suffix (>= 2.0.2, < 5.0)
91
+ base64 (0.2.0)
92
+ bigdecimal (3.1.6)
82
93
  builder (3.2.4)
83
94
  coderay (1.1.3)
84
- concurrent-ruby (1.2.2)
95
+ concurrent-ruby (1.2.3)
96
+ connection_pool (2.4.1)
85
97
  crack (0.4.5)
86
98
  rexml
87
99
  crass (1.0.6)
88
- date (3.3.3)
100
+ date (3.3.4)
89
101
  diff-lcs (1.5.0)
90
102
  dotenv (2.1.2)
103
+ drb (2.2.1)
91
104
  erubi (1.12.0)
92
- globalid (1.1.0)
93
- activesupport (>= 5.0)
105
+ globalid (1.2.1)
106
+ activesupport (>= 6.1)
94
107
  hashdiff (1.0.1)
95
108
  httparty (0.21.0)
96
109
  mini_mime (>= 1.0.0)
97
110
  multi_xml (>= 0.5.2)
98
- i18n (1.14.1)
111
+ i18n (1.14.4)
99
112
  concurrent-ruby (~> 1.0)
113
+ io-console (0.7.2)
114
+ irb (1.12.0)
115
+ rdoc
116
+ reline (>= 0.4.2)
100
117
  kaminari (1.2.2)
101
118
  activesupport (>= 4.1.0)
102
119
  kaminari-actionview (= 1.2.2)
@@ -109,7 +126,7 @@ GEM
109
126
  activerecord
110
127
  kaminari-core (= 1.2.2)
111
128
  kaminari-core (1.2.2)
112
- loofah (2.21.3)
129
+ loofah (2.22.0)
113
130
  crass (~> 1.0.2)
114
131
  nokogiri (>= 1.12.0)
115
132
  mail (2.8.1)
@@ -117,61 +134,75 @@ GEM
117
134
  net-imap
118
135
  net-pop
119
136
  net-smtp
120
- marcel (1.0.2)
137
+ marcel (1.0.4)
121
138
  method_source (1.0.0)
122
- mini_mime (1.1.2)
123
- mini_portile2 (2.8.2)
124
- minitest (5.18.0)
139
+ mini_mime (1.1.5)
140
+ mini_portile2 (2.8.5)
141
+ minitest (5.22.2)
125
142
  multi_xml (0.6.0)
126
- net-imap (0.3.4)
143
+ mutex_m (0.2.0)
144
+ net-imap (0.3.7)
127
145
  date
128
146
  net-protocol
129
147
  net-pop (0.1.2)
130
148
  net-protocol
131
- net-protocol (0.2.1)
149
+ net-protocol (0.2.2)
132
150
  timeout
133
- net-smtp (0.3.3)
151
+ net-smtp (0.4.0.1)
134
152
  net-protocol
135
- nio4r (2.5.9)
136
- nokogiri (1.15.2)
153
+ nio4r (2.7.0)
154
+ nokogiri (1.15.5)
137
155
  mini_portile2 (~> 2.8.2)
138
156
  racc (~> 1.4)
139
157
  pry (0.14.1)
140
158
  coderay (~> 1.1)
141
159
  method_source (~> 1.0)
160
+ psych (5.1.2)
161
+ stringio
142
162
  public_suffix (4.0.6)
143
- racc (1.7.0)
144
- rack (2.2.7)
163
+ racc (1.7.3)
164
+ rack (3.0.9.1)
165
+ rack-session (2.0.0)
166
+ rack (>= 3.0.0)
145
167
  rack-test (2.1.0)
146
168
  rack (>= 1.3)
147
- rails (7.0.5)
148
- actioncable (= 7.0.5)
149
- actionmailbox (= 7.0.5)
150
- actionmailer (= 7.0.5)
151
- actionpack (= 7.0.5)
152
- actiontext (= 7.0.5)
153
- actionview (= 7.0.5)
154
- activejob (= 7.0.5)
155
- activemodel (= 7.0.5)
156
- activerecord (= 7.0.5)
157
- activestorage (= 7.0.5)
158
- activesupport (= 7.0.5)
169
+ rackup (2.1.0)
170
+ rack (>= 3)
171
+ webrick (~> 1.8)
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)
159
184
  bundler (>= 1.15.0)
160
- railties (= 7.0.5)
161
- rails-dom-testing (2.0.3)
162
- activesupport (>= 4.2.0)
185
+ railties (= 7.1.3.2)
186
+ rails-dom-testing (2.2.0)
187
+ activesupport (>= 5.0.0)
188
+ minitest
163
189
  nokogiri (>= 1.6)
164
190
  rails-html-sanitizer (1.6.0)
165
191
  loofah (~> 2.21)
166
192
  nokogiri (~> 1.14)
167
- railties (7.0.5)
168
- actionpack (= 7.0.5)
169
- activesupport (= 7.0.5)
170
- method_source
193
+ railties (7.1.3.2)
194
+ actionpack (= 7.1.3.2)
195
+ activesupport (= 7.1.3.2)
196
+ irb
197
+ rackup (>= 1.0.0)
171
198
  rake (>= 12.2)
172
- thor (~> 1.0)
173
- zeitwerk (~> 2.5)
199
+ thor (~> 1.0, >= 1.2.2)
200
+ zeitwerk (~> 2.6)
174
201
  rake (13.0.6)
202
+ rdoc (6.6.2)
203
+ psych (>= 4.0.0)
204
+ reline (0.4.3)
205
+ io-console (~> 0.5)
175
206
  rexml (3.2.5)
176
207
  rspec (3.11.0)
177
208
  rspec-core (~> 3.11.0)
@@ -188,18 +219,20 @@ GEM
188
219
  diff-lcs (>= 1.2.0, < 2.0)
189
220
  rspec-support (~> 3.11.0)
190
221
  rspec-support (3.11.0)
191
- thor (1.2.2)
192
- timeout (0.3.2)
222
+ stringio (3.1.0)
223
+ thor (1.3.1)
224
+ timeout (0.4.1)
193
225
  tzinfo (2.0.6)
194
226
  concurrent-ruby (~> 1.0)
195
227
  webmock (3.14.0)
196
228
  addressable (>= 2.8.0)
197
229
  crack (>= 0.3.2)
198
230
  hashdiff (>= 0.4.0, < 2.0.0)
199
- websocket-driver (0.7.5)
231
+ webrick (1.8.1)
232
+ websocket-driver (0.7.6)
200
233
  websocket-extensions (>= 0.1.0)
201
234
  websocket-extensions (0.1.5)
202
- zeitwerk (2.6.8)
235
+ zeitwerk (2.6.13)
203
236
 
204
237
  PLATFORMS
205
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,17 +58,20 @@ 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)
64
- if !data["errors"].present? && (data["data"].present? && data["data"]["appSubscriptionCreate"].present? && (!data["data"]["appSubscriptionCreate"]["userErrors"].any? && data["data"]["appSubscriptionCreate"]["confirmationUrl"]))
66
+ data = gq_obj.recurring_charge_api_call(plan_data, return_url, @shop,discount_cookie)
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}
67
70
  else
68
71
  raise Error, "#{data.inspect}"
69
72
  end
70
73
  else
71
- raise Error, "#{data.inspect}"
74
+ raise Error, "Plan not found"
72
75
  end
73
76
  else
74
77
  raise ModelNotFound, "Shop not found"
@@ -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)
@@ -0,0 +1,5 @@
1
+ module AppManager
2
+ class Discount < AppManagerRecord
3
+ self.table_name = "discounts"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module AppManager
2
+ class DiscountLinkPlan < AppManagerRecord
3
+ self.table_name = "discount_link_plans"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module AppManager
2
+ class DiscountShop < AppManagerRecord
3
+ self.table_name = "discount_shops"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module AppManager
2
+ class DiscountUsageLog < AppManagerRecord
3
+ self.table_name = "discounts_usage_log"
4
+ end
5
+ end
@@ -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 : 30
32
- response = self.class.send(http_method, path, { body: options, timeout: time_out })
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
- else
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: 15 })
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("[Extens Trials] APP MANAGER >>>> #{e.inspect}")
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::ExtendTrial.bulk_import extend_plan_users
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
 
@@ -262,6 +393,9 @@ module AppManager
262
393
  value = eval(value)
263
394
  value = value.each { |e| e.delete("id") }.each { |e| e.delete("created_at") }.each { |e| e.delete("updated_at") }
264
395
  new_plan[key] = value
396
+ elsif ['plan_id'].include?(key)
397
+ # puts value.inspect
398
+ new_plan["id"] = value if value rescue {}
265
399
  else
266
400
  new_plan[key] = value unless key.class == Integer
267
401
  end
@@ -350,6 +484,8 @@ module AppManager
350
484
  new_plan[key] = (value == 0 || value == false ? false : true)
351
485
  elsif ['test'].include?(key)
352
486
  new_plan[key] = (value == 0 || value == false ? nil : true)
487
+ elsif ['plan_id'].include?(key)
488
+ new_plan["id"] = value if value rescue nil
353
489
  else
354
490
  new_plan[key] = value unless key.class == Integer
355
491
  end
@@ -476,6 +612,68 @@ module AppManager
476
612
 
477
613
  end
478
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
+
479
677
  def store_local_charge(params, options)
480
678
  message = {"message" => 'fail'}
481
679
  if options
@@ -486,7 +684,7 @@ module AppManager
486
684
  test_value = charge["test"]
487
685
  plan_id = charge["plan_id"].to_i
488
686
  begin
489
- 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')
490
688
  message = {"message" => 'success'}
491
689
  rescue Exception => e
492
690
  Rollbar.error("Charge not saved on local DB due to #{e.inspect}")
@@ -506,12 +704,32 @@ module AppManager
506
704
  return message
507
705
  end
508
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
+
509
726
 
510
727
  def sync_app_manager
511
728
  plan_obj = AppManager::Client.new
512
729
  response = plan_obj.get_status
513
730
  if response && response.code == 200
514
731
  charges = AppManager::Charge.where(sync: false)
732
+ discounts_usage_logs = AppManager::DiscountUsageLog.where(sync: false, process_type: 'use-discount')
515
733
  charges.each do |charge|
516
734
  if charge
517
735
  if !charge["cancelled_on"].nil?
@@ -524,6 +742,17 @@ module AppManager
524
742
  end
525
743
  end
526
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
+
527
756
  end
528
757
  end
529
758
 
@@ -33,7 +33,7 @@ module AppManager
33
33
  response = ActiveSupport::JSON.decode(response.read_body) rescue nil
34
34
  return response
35
35
  else
36
- Rollbar.error("=== params missing from any of these api_key, api_version, shopify_domain, shopify_token ===")
36
+ Rollbar.error("=== params missing from any of these api_key=#{@api_key}, api_version=#{@api_version}, shopify_domain=#{@shopify_domain}, shopify_token ===#{@shopify_token}")
37
37
  return []
38
38
  end
39
39
  end
@@ -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,15 +83,73 @@ module AppManager
82
83
  end
83
84
  end
84
85
 
85
- discount_type = plan['discount_type'] || "percentage"
86
- discount_val = discount_type == "percentage" ? (plan['discount'].to_f/ 100) : "#{plan['discount']}"
87
- plan_discount = plan['discount'] ? { "discount" => { "durationLimitInIntervals" => (plan['cycle_count'].to_i || 0), "value" => {"#{discount_type}" => discount_val} } } : {}
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
+ }
104
+ }
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
116
+ else
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
+
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)}"
88
147
 
89
148
  price_details = {
90
149
  "price": { "amount": plan['price'], "currencyCode": 'USD' },
91
150
  "interval": plan['interval']['value']
92
151
  }
93
- price_details.merge! plan_discount if plan_discount.any?
152
+ price_details.merge! plan_discount if plan_discount && plan_discount.any?
94
153
 
95
154
  plan_var = {
96
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppManager
4
- VERSION = "1.6.3"
4
+ VERSION = "2.0.0"
5
5
  end
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: 1.6.3
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: 2023-06-08 00:00:00.000000000 Z
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