app_manager 1.7.0 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 939c279b78c14a7e781d74177e6df92a287a2e463d6c3af39346760e6891115b
4
- data.tar.gz: 9a3abefe3f42d4c40b34d597a0b850d128afbff33094cbe8ddf06b66dd473fb2
3
+ metadata.gz: 1093f4ae3ee06a00f81bf11ad98bb1669f6b9f931bed69a430525733058143a0
4
+ data.tar.gz: 9a3a425bdf82d12982f33ace1e86a1e5b47bbc7b3430ccd96b0469967cbf2f65
5
5
  SHA512:
6
- metadata.gz: 769614783e6d231a4b75303003b8da1143787d10cae09f093647bfeb6b246c28d4e604255a23530ad6332cad3d6796cec7fd99a80a3b5c46c8d74660f8dd17ee
7
- data.tar.gz: da7329819695c265587a36c8c34ef922176e5fd40a5109acd88849695bbbf1143eff43d2d699f08c044d90eaf58bb3f45ea5f5ec09fbbc9c5d34bcb2c980b6b9
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.7.0)
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.5)
92
+ bigdecimal (3.1.6)
93
93
  builder (3.2.4)
94
94
  coderay (1.1.3)
95
- concurrent-ruby (1.2.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.0)
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.1)
111
+ i18n (1.14.4)
113
112
  concurrent-ruby (~> 1.0)
114
- io-console (0.7.1)
115
- irb (1.11.0)
113
+ io-console (0.7.2)
114
+ irb (1.12.0)
116
115
  rdoc
117
- reline (>= 0.3.8)
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.2)
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.20.0)
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.8)
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.2)
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.0)
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.12)
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)
@@ -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
 
@@ -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
- discount_type = plan['discount_type'] || "percentage"
86
- discount_val = discount_type == "percentage" ? (plan['discount'].to_f/ 100) : "#{plan['discount']}"
87
- if !@api_version.nil? && @api_version.to_s.include?('2024')
88
- plan_discount = if plan['discount'] && plan['cycle_count']
89
- {
90
- "discount" => { "durationLimitInIntervals" => (plan['cycle_count'].to_i),
91
- "value" => {"#{discount_type}" => discount_val}
92
- }
93
- }
94
- elsif plan['discount']
95
- {
96
- "discount" => { "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
+ }
97
104
  }
98
- }
99
- else
100
- {}
101
- end
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
- plan_discount = plan['discount'] ? { "discount" => { "durationLimitInIntervals" => (plan['cycle_count'].to_i), "value" => {"#{discount_type}" => discount_val} } } : {}
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppManager
4
- VERSION = "1.7.0"
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.7.0
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-01-09 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