app_manager 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b537020a68cfa232a0ad374777b2a3a9317d5aa599da985ac07334814567d321
4
- data.tar.gz: e89d2d9140a3196468d77b5bed6e014e3cabde20478c5206c29fc47e3322b9e9
3
+ metadata.gz: 92d071e3e478e20f2fb063d5a821be4d772edb68de15c862c50f0a01c69727d8
4
+ data.tar.gz: 1e171148960d955ca01c76a7bf715630508e2766e4a46790a85e86ffba4ea7a1
5
5
  SHA512:
6
- metadata.gz: 95d3718467208b590e9889a5b774da042a257b7e8f8d05f15b2317637b490b6399bdbe8467fad02226b651d9c7119e805f0e031658202f2f439c9a8dff836111
7
- data.tar.gz: aaeee10fb9e7e7edeb4c743ce2bb3df1b5c332f42386a6d87b866d9e33da2a06ba74e45cb7888da1ea97ca581a48291ae373c49ea1e93cbf7c9e6322337c2ada
6
+ metadata.gz: 205c194f35ab5df4a9fab9fe374a1e83c89ff5ca2ceaa8327ae6ca92589343522ba8c35bdac61d63c92932d9dd7b5769410d4975c8b7fc191e9fcbcf6df4ba61
7
+ data.tar.gz: b8f6a607d5f1a71e5d0b2537909a87a771718b5f31bbe2d39d3ae291521e40eac5b807c2749806f6c20f1bc19453c6e04ebf52533e69c490441f6d9b33ca8b3d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- app_manager (1.1.0)
4
+ app_manager (1.1.1)
5
5
  httparty
6
6
  kaminari (>= 0.16.3)
7
7
  rails (>= 5.2.0)
@@ -10,67 +10,67 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- actioncable (7.0.2.3)
14
- actionpack (= 7.0.2.3)
15
- activesupport (= 7.0.2.3)
13
+ actioncable (7.0.3)
14
+ actionpack (= 7.0.3)
15
+ activesupport (= 7.0.3)
16
16
  nio4r (~> 2.0)
17
17
  websocket-driver (>= 0.6.1)
18
- actionmailbox (7.0.2.3)
19
- actionpack (= 7.0.2.3)
20
- activejob (= 7.0.2.3)
21
- activerecord (= 7.0.2.3)
22
- activestorage (= 7.0.2.3)
23
- activesupport (= 7.0.2.3)
18
+ actionmailbox (7.0.3)
19
+ actionpack (= 7.0.3)
20
+ activejob (= 7.0.3)
21
+ activerecord (= 7.0.3)
22
+ activestorage (= 7.0.3)
23
+ activesupport (= 7.0.3)
24
24
  mail (>= 2.7.1)
25
25
  net-imap
26
26
  net-pop
27
27
  net-smtp
28
- actionmailer (7.0.2.3)
29
- actionpack (= 7.0.2.3)
30
- actionview (= 7.0.2.3)
31
- activejob (= 7.0.2.3)
32
- activesupport (= 7.0.2.3)
28
+ actionmailer (7.0.3)
29
+ actionpack (= 7.0.3)
30
+ actionview (= 7.0.3)
31
+ activejob (= 7.0.3)
32
+ activesupport (= 7.0.3)
33
33
  mail (~> 2.5, >= 2.5.4)
34
34
  net-imap
35
35
  net-pop
36
36
  net-smtp
37
37
  rails-dom-testing (~> 2.0)
38
- actionpack (7.0.2.3)
39
- actionview (= 7.0.2.3)
40
- activesupport (= 7.0.2.3)
38
+ actionpack (7.0.3)
39
+ actionview (= 7.0.3)
40
+ activesupport (= 7.0.3)
41
41
  rack (~> 2.0, >= 2.2.0)
42
42
  rack-test (>= 0.6.3)
43
43
  rails-dom-testing (~> 2.0)
44
44
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
45
- actiontext (7.0.2.3)
46
- actionpack (= 7.0.2.3)
47
- activerecord (= 7.0.2.3)
48
- activestorage (= 7.0.2.3)
49
- activesupport (= 7.0.2.3)
45
+ actiontext (7.0.3)
46
+ actionpack (= 7.0.3)
47
+ activerecord (= 7.0.3)
48
+ activestorage (= 7.0.3)
49
+ activesupport (= 7.0.3)
50
50
  globalid (>= 0.6.0)
51
51
  nokogiri (>= 1.8.5)
52
- actionview (7.0.2.3)
53
- activesupport (= 7.0.2.3)
52
+ actionview (7.0.3)
53
+ activesupport (= 7.0.3)
54
54
  builder (~> 3.1)
55
55
  erubi (~> 1.4)
56
56
  rails-dom-testing (~> 2.0)
57
57
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
58
- activejob (7.0.2.3)
59
- activesupport (= 7.0.2.3)
58
+ activejob (7.0.3)
59
+ activesupport (= 7.0.3)
60
60
  globalid (>= 0.3.6)
61
- activemodel (7.0.2.3)
62
- activesupport (= 7.0.2.3)
63
- activerecord (7.0.2.3)
64
- activemodel (= 7.0.2.3)
65
- activesupport (= 7.0.2.3)
66
- activestorage (7.0.2.3)
67
- actionpack (= 7.0.2.3)
68
- activejob (= 7.0.2.3)
69
- activerecord (= 7.0.2.3)
70
- activesupport (= 7.0.2.3)
61
+ activemodel (7.0.3)
62
+ activesupport (= 7.0.3)
63
+ activerecord (7.0.3)
64
+ activemodel (= 7.0.3)
65
+ activesupport (= 7.0.3)
66
+ activestorage (7.0.3)
67
+ actionpack (= 7.0.3)
68
+ activejob (= 7.0.3)
69
+ activerecord (= 7.0.3)
70
+ activesupport (= 7.0.3)
71
71
  marcel (~> 1.0)
72
72
  mini_mime (>= 1.1.0)
73
- activesupport (7.0.2.3)
73
+ activesupport (7.0.3)
74
74
  concurrent-ruby (~> 1.0, >= 1.0.2)
75
75
  i18n (>= 1.6, < 2)
76
76
  minitest (>= 5.1)
@@ -95,7 +95,6 @@ GEM
95
95
  multi_xml (>= 0.5.2)
96
96
  i18n (1.10.0)
97
97
  concurrent-ruby (~> 1.0)
98
- io-wait (0.2.1)
99
98
  kaminari (1.2.2)
100
99
  activesupport (>= 4.1.0)
101
100
  kaminari-actionview (= 1.2.2)
@@ -108,7 +107,7 @@ GEM
108
107
  activerecord
109
108
  kaminari-core (= 1.2.2)
110
109
  kaminari-core (1.2.2)
111
- loofah (2.15.0)
110
+ loofah (2.18.0)
112
111
  crass (~> 1.0.2)
113
112
  nokogiri (>= 1.5.9)
114
113
  mail (2.7.1)
@@ -120,7 +119,7 @@ GEM
120
119
  mime-types-data (3.2022.0105)
121
120
  mini_mime (1.1.2)
122
121
  mini_portile2 (2.8.0)
123
- minitest (5.15.0)
122
+ minitest (5.16.0)
124
123
  multi_xml (0.6.0)
125
124
  net-imap (0.2.3)
126
125
  digest
@@ -130,47 +129,48 @@ GEM
130
129
  digest
131
130
  net-protocol
132
131
  timeout
133
- net-protocol (0.1.2)
134
- io-wait
132
+ net-protocol (0.1.3)
135
133
  timeout
136
134
  net-smtp (0.3.1)
137
135
  digest
138
136
  net-protocol
139
137
  timeout
140
138
  nio4r (2.5.8)
141
- nokogiri (1.13.3)
139
+ nokogiri (1.13.6)
142
140
  mini_portile2 (~> 2.8.0)
143
141
  racc (~> 1.4)
142
+ nokogiri (1.13.6-x86_64-linux)
143
+ racc (~> 1.4)
144
144
  pry (0.14.1)
145
145
  coderay (~> 1.1)
146
146
  method_source (~> 1.0)
147
147
  public_suffix (4.0.6)
148
148
  racc (1.6.0)
149
- rack (2.2.3)
149
+ rack (2.2.3.1)
150
150
  rack-test (1.1.0)
151
151
  rack (>= 1.0, < 3)
152
- rails (7.0.2.3)
153
- actioncable (= 7.0.2.3)
154
- actionmailbox (= 7.0.2.3)
155
- actionmailer (= 7.0.2.3)
156
- actionpack (= 7.0.2.3)
157
- actiontext (= 7.0.2.3)
158
- actionview (= 7.0.2.3)
159
- activejob (= 7.0.2.3)
160
- activemodel (= 7.0.2.3)
161
- activerecord (= 7.0.2.3)
162
- activestorage (= 7.0.2.3)
163
- activesupport (= 7.0.2.3)
152
+ rails (7.0.3)
153
+ actioncable (= 7.0.3)
154
+ actionmailbox (= 7.0.3)
155
+ actionmailer (= 7.0.3)
156
+ actionpack (= 7.0.3)
157
+ actiontext (= 7.0.3)
158
+ actionview (= 7.0.3)
159
+ activejob (= 7.0.3)
160
+ activemodel (= 7.0.3)
161
+ activerecord (= 7.0.3)
162
+ activestorage (= 7.0.3)
163
+ activesupport (= 7.0.3)
164
164
  bundler (>= 1.15.0)
165
- railties (= 7.0.2.3)
165
+ railties (= 7.0.3)
166
166
  rails-dom-testing (2.0.3)
167
167
  activesupport (>= 4.2.0)
168
168
  nokogiri (>= 1.6)
169
- rails-html-sanitizer (1.4.2)
169
+ rails-html-sanitizer (1.4.3)
170
170
  loofah (~> 2.3)
171
- railties (7.0.2.3)
172
- actionpack (= 7.0.2.3)
173
- activesupport (= 7.0.2.3)
171
+ railties (7.0.3)
172
+ actionpack (= 7.0.3)
173
+ activesupport (= 7.0.3)
174
174
  method_source
175
175
  rake (>= 12.2)
176
176
  thor (~> 1.0)
@@ -193,9 +193,9 @@ GEM
193
193
  rspec-support (~> 3.11.0)
194
194
  rspec-support (3.11.0)
195
195
  sqlite3 (1.3.13)
196
- strscan (3.0.1)
196
+ strscan (3.0.3)
197
197
  thor (1.2.1)
198
- timeout (0.2.0)
198
+ timeout (0.3.0)
199
199
  tzinfo (2.0.4)
200
200
  concurrent-ruby (~> 1.0)
201
201
  webmock (3.14.0)
@@ -205,7 +205,7 @@ GEM
205
205
  websocket-driver (0.7.5)
206
206
  websocket-extensions (>= 0.1.0)
207
207
  websocket-extensions (0.1.5)
208
- zeitwerk (2.5.4)
208
+ zeitwerk (2.6.0)
209
209
 
210
210
  PLATFORMS
211
211
  ruby
data/README.md CHANGED
@@ -28,6 +28,10 @@ gem 'app_manager'
28
28
 
29
29
  this install command will mount routes in your rails route and will create a config file at ```config/initializers/app_manager.rb```
30
30
 
31
+ ```
32
+ rails db:migrate
33
+ ```
34
+
31
35
 
32
36
  <a name="step2"></a>
33
37
  ### Configuration
@@ -35,18 +39,7 @@ gem 'app_manager'
35
39
  * Set Shopify API version to 2022-04 as app_manager is best compatible with this version.
36
40
 
37
41
 
38
- * Please check the 'shops' table that must have 'plan_id' as int/bigint and 'trial_activated_at' as datetime otherwise add its migration like following example:
39
-
40
- ```
41
- class AddPlanIdToShops < ActiveRecord::Migration[5.2]
42
- def change
43
- add_column :shops, :plan_id, :bigint
44
- add_column :shops, :trial_activated_at, :datetime
45
- end
46
- end
47
- ```
48
-
49
- and map these new fields in 'config.field_names' in below initializer file which is generated by install command. Please note: this is important step.
42
+ * Please map new fields (which added by app manager migration) in 'config.field_names' in below initializer file which is generated by install command. Please note: this is important step.
50
43
 
51
44
 
52
45
  * Please update blank fields in initializer file. Please copy 'uuid' from this [file](https://docs.google.com/spreadsheets/d/1cw2nSKxAHTGn4Cfa98RNdtfHT3zdtwu9bQD7s7hErXc/edit#gid=0) and paste in the following file and make sure that is unique per feature. After copying put your 'app name' next to 'uuid' column in this [file](https://docs.google.com/spreadsheets/d/1cw2nSKxAHTGn4Cfa98RNdtfHT3zdtwu9bQD7s7hErXc/edit#gid=0).
@@ -66,10 +59,11 @@ AppManager.configure do |config|
66
59
  'name' => 'shopify_domain', # demo-rahul-tiwari.myshopify.com
67
60
  'shopify_email' => 'email', # rahul.t@hulkapps.com
68
61
  'shopify_token' => 'shopify_token',
69
- 'shopify_plan' => 'plan_name', # partner_test
62
+ 'shopify_plan' => 'shopify_plan', # partner_test
70
63
  'plan_id' => 'plan_id', # 1. t
71
64
  'created_at' => 'created_at', # 2022-04-15 10:43:05
72
- 'trial_activated_at' => 'trial_activated_at' # field name that stores trial start/activated date
65
+ 'trial_activated_at' => 'trial_activated_at', # field name that stores trial start/activated date
66
+ 'grandfathered' => 'grandfathered'
73
67
  }
74
68
  config.plan_features = [
75
69
  {
@@ -79,7 +73,10 @@ AppManager.configure do |config|
79
73
  "description" => "Feature Description",
80
74
  "value_type" => "integer",
81
75
  "format" => "count",
82
- "display_order" => 1
76
+ "display_order" => 1,
77
+ "hidden_feature" => false,
78
+ "group_order" => "1",
79
+ "group" => "Group Name",
83
80
  },
84
81
  {
85
82
  "uuid" => "9f18f95a-bfaf-11ec-9d64-0242ac120002",
@@ -88,7 +85,10 @@ AppManager.configure do |config|
88
85
  "description" => "Feature Description",
89
86
  "value_type" => "boolean",
90
87
  "format" => "percentage",
91
- "display_order" => 2
88
+ "display_order" => 2,
89
+ "hidden_feature" => false,
90
+ "group_order" => "1",
91
+ "group" => "Group Name",
92
92
  },
93
93
  {
94
94
  "uuid" => "9f190a26-bfaf-11ec-9d64-0242ac120002",
@@ -97,7 +97,10 @@ AppManager.configure do |config|
97
97
  "description" => "Feature Description",
98
98
  "value_type" => "string",
99
99
  "format" => "string",
100
- "display_order" => 3
100
+ "display_order" => 3,
101
+ "hidden_feature" => false,
102
+ "group_order" => "1",
103
+ "group" => "Group Name",
101
104
  },
102
105
  {
103
106
  "uuid" => "9f191340-bfaf-11ec-9d64-0242ac12000",
@@ -110,10 +113,15 @@ AppManager.configure do |config|
110
113
  "val 2"
111
114
  ],
112
115
  "format" => "string",
113
- "display_order" => 4
116
+ "display_order" => 4,
117
+ "hidden_feature" => false,
118
+ "group_order" => "1",
119
+ "group" => "Group Name",
114
120
  }
115
- ] #Required, Values type : integer, boolean, string, array
121
+ ]
116
122
  end
123
+ #Required, Values type : integer, boolean, string, array #
124
+ #Format: percentage, count, string
117
125
  ```
118
126
 
119
127
 
@@ -159,6 +167,10 @@ and then you can use follwing methods with your shop objects.
159
167
  @shop.get_feature('feature-3') # provide slug of feature and this returns value of feature which is set in portal.
160
168
 
161
169
  @shop.get_remaining_days # return integer based on trial activated date.
170
+
171
+ @shop.get_plan # return integer based on trial activated date.
172
+
173
+ @shop.get_charge # return integer based on trial activated date.
162
174
  ```
163
175
 
164
176
 
@@ -1,12 +1,7 @@
1
1
  module AppManager
2
2
  class ApplicationController < ActionController::Base
3
3
  include AppManager::Actions
4
- cache_response_of_app_manager
5
4
  protect_from_forgery with: :exception
6
5
  include AppManager::Authenticate
7
- # rescue_from StandardError do |exception|
8
- # render json: { :error => exception.message }, :status => 500
9
- # end
10
-
11
6
  end
12
7
  end
@@ -2,6 +2,7 @@ require_dependency "app_manager/application_controller"
2
2
 
3
3
  module AppManager
4
4
  class BannersController < ApplicationController
5
+ cache_response_for :marketing_banner
5
6
  def marketing_banner
6
7
  begin
7
8
  banner_obj = AppManager::Client.new
@@ -1,5 +1,4 @@
1
1
  require_dependency "app_manager/application_controller"
2
-
3
2
  module AppManager
4
3
  class ChargesController < ApplicationController
5
4
  include HTTParty
@@ -23,16 +22,16 @@ module AppManager
23
22
  redirect_charge = data["data"]["appSubscriptionCreate"]["confirmationUrl"]
24
23
  render json: {'redirect_url' => redirect_charge}
25
24
  else
26
- render json: {'error' => data["errors"].as_json}
25
+ raise Error, "#{data["errors"].as_json}"
27
26
  end
28
27
  else
29
- render json: {'error' => data["errors"]}
28
+ raise Error, "#{data["errors"]}"
30
29
  end
31
30
  else
32
- render json: {'error' => 'Shop not found'}
31
+ raise ModelNotFound, "Shop not found"
33
32
  end
34
33
  else
35
- render json: {'error' => 'Missing Shop domain or plan id in params'}
34
+ raise Error, "Missing Shop domain or plan id in params"
36
35
  end
37
36
  end
38
37
 
@@ -65,22 +64,29 @@ module AppManager
65
64
 
66
65
  end
67
66
  end
67
+
68
68
  charge_ob = AppManager::Client.new(nil,json_req=true)
69
69
  response = charge_ob.store_charge(charge.to_json)
70
70
 
71
71
  if response['message'] == "success"
72
- model.update(@plan_field => params[:plan])
72
+ AppManager.clear_cache
73
+ model.update(@plan_field => params[:plan])
74
+ charge_data = plan_obj.get_charge(@shop[shopify_domain])
75
+ AppManager::EventHandler.new('charge_created',{
76
+ "plan" => plan_data,
77
+ "charge" => charge,
78
+ "previous_charge" => charge_data ? (charge_data['cancelled_charge'] || nil) : nil
79
+ })
73
80
  end
74
- redirect_to "/?shop=#{params[:shop]}"
81
+ redirect_to "#{app_url}?shop=#{params[:shop]}", :status => 301 and return
75
82
  else
76
-
77
- render json: {'error' => 'Invalid shopify charge'}
83
+ raise Error, "Invalid shopify charge #{charges.insect}"
78
84
  end
79
85
  else
80
- render json: {'error' => 'Shop not found'}
86
+ raise ModelNotFound, "Shop not found"
81
87
  end
82
88
  else
83
- render json: {'error' => 'Invalid params'}
89
+ raise Error, "Invalid params, must have charge_id,shop && plan"
84
90
  end
85
91
  end
86
92
 
@@ -2,6 +2,9 @@ require_dependency "app_manager/application_controller"
2
2
 
3
3
  module AppManager
4
4
  class PlansController < ApplicationController
5
+ cache_response_for :plans
6
+ cache_response_for :index
7
+ cache_response_for :users
5
8
  skip_before_action :verify_authenticity_token, :only => [:active_without_plan,:burst_cache,:fail_safe_backup]
6
9
  def index
7
10
  render :json => {"features" => AppManager.configuration.plan_features || []}
@@ -12,8 +15,9 @@ module AppManager
12
15
  active_plan_id_or_name = shopify_plan = plan = nil
13
16
  default_plan_id = nil
14
17
  plan_obj = AppManager::Client.new
15
- plans = plan_obj.get_plans
18
+ plans = []
16
19
  if params[:shop_domain].present? && !AppManager.configuration.plan_features.nil?
20
+ plans = plan_obj.get_plans(params[:shop_domain])
17
21
  @shop = shop_data
18
22
  if !@shop.nil?
19
23
  active_plan_id_or_name = @shop[@plan_field]
@@ -53,7 +57,7 @@ module AppManager
53
57
  end
54
58
 
55
59
  response = {
56
- 'plans' => plan_obj.get_plans,
60
+ 'plans' => plans,
57
61
  'shopify_plan' => shopify_plan,
58
62
  'plan' => plan,
59
63
  'default_plan_id' => default_plan_id
@@ -0,0 +1,10 @@
1
+ module AppManager
2
+
3
+ class EventHandler
4
+ def initialize(event,payload)
5
+ ActiveSupport::Notifications.instrument(event, payload)
6
+ end
7
+ end
8
+
9
+ end
10
+
@@ -2,8 +2,10 @@ module AppManager
2
2
  module Actions
3
3
  extend ActiveSupport::Concern
4
4
  module ClassMethods
5
- def cache_response_of_app_manager
6
- around_action ApiCacheHandler.new
5
+ def cache_response_for(*actions)
6
+ options = actions.extract_options!
7
+ filter_options = options.extract!(:if, :unless).merge(only: actions)
8
+ around_action ApiCacheHandler.new(options), filter_options
7
9
  end
8
10
  end
9
11
  end
@@ -1,8 +1,9 @@
1
1
  module AppManager
2
2
  module Actions
3
3
  class ApiCacheHandler
4
- def initialize
5
-
4
+ def initialize(options)
5
+ @options = options
6
+ @expires_in = @options[:expires_in]
6
7
  end
7
8
 
8
9
 
@@ -20,7 +21,7 @@ module AppManager
20
21
  protected
21
22
 
22
23
  def should_response_cache?
23
- return @request.get? && @response_cache.cached_response.present?
24
+ return @request.get? && AppManager.configuration.enable_caching && @response_cache.cached_response.present?
24
25
  end
25
26
 
26
27
  def log_info
@@ -37,29 +38,33 @@ module AppManager
37
38
 
38
39
  def cache_path
39
40
  @cache_path = "app-manager-cache"
40
-
41
- path_only = @request.fullpath.split('?').first
42
- @cache_path = "#{@cache_path}#{path_only}"
41
+ if @options[:cache_path].present?
42
+ @cache_path = "#{@cache_path}#{@options[:cache_path]}"
43
+ elsif AppManager.configuration.refresh_by_request_params?
44
+ @cache_path = "#{@cache_path}#{@request.fullpath}"
45
+ else
46
+ path_only = @request.fullpath.split('?').first
47
+ @cache_path = "#{@cache_path}#{path_only}"
48
+ end
43
49
 
44
50
  if AppManager.configuration.cache_by_headers.present?
45
51
  headers = AppManager.configuration.cache_by_headers.map do |header|
46
52
  @request.headers[header].to_s
47
53
  end
48
54
  headers_cache_path = headers.join('-')
49
- @cache_path = "#{@cache_path}/#{headers_cache_path}"
55
+ @cache_path = "#{@cache_path}#{headers_cache_path}"
50
56
  end
51
-
52
- @cache_path
57
+ return @cache_path
53
58
  end
54
59
 
55
60
  def render_cached_response
56
61
  body = @response_cache.body
57
62
  status = @response_cache.status
58
63
  headers = @response_cache.headers
59
- # headers.try(:each) do |key, value|
60
- # @controller.response.headers[key] = value
61
- # end
62
- @controller.render json: body, status: status
64
+ headers.try(:each) do |key, value|
65
+ @controller.response.headers[key] = value
66
+ end
67
+ @controller.render plain: body, status: status
63
68
  end
64
69
  end
65
70
  end
@@ -23,19 +23,24 @@ module AppManager
23
23
  private
24
24
 
25
25
  def request(http_method, path, options)
26
- response = self.class.send(http_method, path, { body: options })
27
- if path.include? "/get-status"
28
- data = response
29
- elsif path.include? "/sync-charge"
30
- data = response.parsed_response
31
- data = parse_data(response.parsed_response)
32
- else
33
- if response.code.to_s.start_with?('2') or response.code.to_s.start_with?('4')
34
- data = response.parsed_response
35
- data = parse_data(response.parsed_response)
26
+ begin
27
+ response = self.class.send(http_method, path, { body: options, timeout: 10 })
28
+ if path.include? "/get-status"
29
+ data = response
30
+ elsif path.include? "/sync-charge"
31
+ data = response.parsed_response
32
+ data = parse_data(response.parsed_response)
36
33
  else
37
- data = response_from_failsafe(path,options)
34
+ if response.code.to_s.start_with?('2') or response.code.to_s.start_with?('4')
35
+ data = response.parsed_response
36
+ data = parse_data(response.parsed_response)
37
+ # data = response_from_failsafe(path,options)
38
+ else
39
+ data = response_from_failsafe(path,options)
40
+ end
38
41
  end
42
+ rescue Exception => e
43
+ data = response_from_failsafe(path,options)
39
44
  end
40
45
  end
41
46
 
@@ -57,7 +62,7 @@ module AppManager
57
62
  when "static-contents"
58
63
  return @fs.get_local_app_structures
59
64
  when 'plans'
60
- return @fs.get_local_plans
65
+ return @fs.get_local_plans(params)
61
66
  when 'plan'
62
67
  return @fs.get_local_plan(params)
63
68
  when 'store-charge'
@@ -2,8 +2,8 @@ module AppManager
2
2
  class Client
3
3
  module Plans
4
4
 
5
- def get_plans(options = {})
6
- get("/plans", options)
5
+ def get_plans(shop_domain)
6
+ get("/plans?shop_domain=#{shop_domain}")
7
7
  end
8
8
 
9
9
  def get_plan(plan_id,shop_domain=nil)
@@ -12,10 +12,10 @@ module AppManager
12
12
  attr_accessor :shopify_domain_field
13
13
  attr_accessor :plan_id_or_name_field
14
14
  attr_accessor :field_names
15
-
16
-
15
+ attr_accessor :refresh_by_request_params
17
16
 
18
17
  def initialize
18
+ @refresh_by_request_params = true
19
19
  @expires_in = 1.day
20
20
  @enable_caching = true
21
21
  @app_url = nil
@@ -35,6 +35,7 @@ module AppManager
35
35
  'email' => 'email'
36
36
  }
37
37
  @fs = AppManager::FailSafe.new
38
+ AppManager.clear_cache
38
39
  end
39
40
 
40
41
  def expires_in
@@ -77,6 +78,9 @@ module AppManager
77
78
  @field_names
78
79
  end
79
80
 
81
+ def refresh_by_request_params?
82
+ @refresh_by_request_params
83
+ end
80
84
 
81
85
  end
82
86
  end
@@ -0,0 +1,4 @@
1
+ module AppManager
2
+ class Error < StandardError; end
3
+ class ModelNotFound < Error; end
4
+ end
@@ -11,53 +11,46 @@ module AppManager
11
11
  end
12
12
 
13
13
  def save_api_data(params)
14
- Thread.new do
15
14
  begin
16
15
  save_api_plans(params["plans"])
17
16
  rescue Exception => e
18
17
  Rails.logger.info "APP MANGAGER >>>> #{e.inspect}"
19
18
  end
20
- end
21
- Thread.new do
22
19
  begin
23
20
  save_api_charges(params["charges"])
24
21
  rescue Exception => e
25
22
  Rails.logger.info "APP MANGAGER >>>> #{e.inspect}"
26
23
  end
27
- end
28
- Thread.new do
29
24
  begin
30
25
  save_api_apps(params["apps"])
31
26
  rescue Exception => e
32
27
  Rails.logger.info "APP MANGAGER >>>> #{e.inspect}"
33
28
  end
34
- end
35
- Thread.new do
36
29
  begin
37
30
  save_api_app_structures(params["app_structures"])
38
31
  rescue Exception => e
39
32
  Rails.logger.info "APP MANGAGER >>>> #{e.inspect}"
40
33
  end
41
- end
42
- Thread.new do
43
34
  begin
44
35
  save_api_discount_plans(params["discount_plans"])
45
36
  rescue Exception => e
46
37
  Rails.logger.info "APP MANGAGER >>>> #{e.inspect}"
47
38
  end
48
- end
49
- Thread.new do
50
39
  begin
51
40
  save_api_extend_trials(params["extend_trials"])
52
41
  rescue Exception => e
53
42
  Rails.logger.info "APP MANGAGER >>>> #{e.inspect}"
54
43
  end
55
- end
44
+ begin
45
+ save_api_plan_users(params["plan_users"])
46
+ rescue Exception => e
47
+ Rails.logger.info "APP MANGAGER >>>> #{e.inspect}"
48
+ end
56
49
  end
57
50
 
58
51
  def save_api_plans(plans)
59
52
  @apm_db.execute("DROP TABLE IF EXISTS plans;")
60
- @apm_db.execute "CREATE TABLE IF NOT EXISTS plans(id integer,type varchar(255), name varchar(255), price float, offer_text varchar(255), interval text, shopify_plans text, trial_days integer, test boolean, on_install integer, is_custom boolean, app_id integer, base_plan integer, created_at datetime, updated_at datetime, public boolean, discount integer, cycle_count integer, store_base_plan boolean, discount_type varchar(255), affiliate text, features text)"
53
+ @apm_db.execute "CREATE TABLE IF NOT EXISTS plans(id integer,type varchar(255), name varchar(255), price float, offer_text varchar(255), interval text, shopify_plans text, trial_days integer, test boolean, on_install integer, is_custom boolean, app_id integer, base_plan integer, created_at datetime, updated_at datetime, public boolean, discount integer, cycle_count integer, store_base_plan boolean, discount_type varchar(255), affiliate text, features text, deleted_at datetime)"
61
54
 
62
55
  if plans.any?
63
56
  plans.each do |plan|
@@ -73,7 +66,7 @@ module AppManager
73
66
  is_custom = plan['is_custom'] ? 1 : 0
74
67
  public_val = plan['public'] ? 1 : 0
75
68
  store_base_plan = plan['store_base_plan'] ? 1 : 0
76
- @apm_db.execute("INSERT INTO plans ( id , type , name , price , offer_text , interval , shopify_plans , trial_days , test , on_install , is_custom , app_id , base_plan , created_at, updated_at , public , discount , cycle_count , store_base_plan , discount_type, affiliate, features ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",plan["id"], plan["type"], plan["name"], plan["price"], plan["offer_text"], "#{interval}", "#{shopify_plans}", plan["trial_days"], plan_test, plan["on_install"], is_custom, plan["app_id"], plan["base_plan"], plan["created_at"], plan["updated_at"],public_val, plan["discount"], plan["cycle_count"], store_base_plan, plan["discount_type"], "#{affiliate}", "#{features}")
69
+ @apm_db.execute("INSERT INTO plans ( id , type , name , price , offer_text , interval , shopify_plans , trial_days , test , on_install , is_custom , app_id , base_plan , created_at, updated_at , public , discount , cycle_count , store_base_plan , discount_type, affiliate, features, deleted_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",plan["id"], plan["type"], plan["name"], plan["price"], plan["offer_text"], "#{interval}", "#{shopify_plans}", plan["trial_days"], plan_test, plan["on_install"], is_custom, plan["app_id"], plan["base_plan"], plan["created_at"], plan["updated_at"],public_val, plan["discount"], plan["cycle_count"], store_base_plan, plan["discount_type"], "#{affiliate}", "#{features}",plan["deleted_at"])
77
70
  end
78
71
  end
79
72
  end
@@ -129,6 +122,16 @@ module AppManager
129
122
  end
130
123
  end
131
124
 
125
+ def save_api_plan_users(plan_users)
126
+ @apm_db.execute("DROP TABLE IF EXISTS plan_users;")
127
+ @apm_db.execute "CREATE TABLE IF NOT EXISTS plan_users(id integer,shop_domain varchar(255),plan_id integer,created_by integer,created_at datetime,updated_at datetime)"
128
+ if plan_users.any?
129
+ plan_users.each do |plan_user|
130
+ @apm_db.execute("INSERT INTO plan_users (id ,shop_domain, plan_id, created_by, created_at, updated_at ) VALUES (?,?,?,?,?,?)", plan_user['id'], plan_user['shop_domain'], plan_user['plan_id'], plan_user['created_by'], plan_user['created_at'], plan_user['updated_at'])
131
+ end
132
+ end
133
+ end
134
+
132
135
 
133
136
  def get_local_app_structures
134
137
  app_structures = {}
@@ -146,38 +149,89 @@ module AppManager
146
149
  end
147
150
 
148
151
 
149
- def get_local_plans
150
- plans = []
151
- @apm_db.execute( "SELECT * FROM plans;") do |plan|
152
- new_plan = {}
153
- plan.each_with_index do |(key, value), index|
154
- if ['interval'].include?(key)
155
- val = eval(value)
156
- new_plan[key] = val
157
- new_plan[key] = val['value'] if val rescue {}
158
- elsif ['shopify_plans'].include?(key)
159
- val = eval(value)
160
- new_plan[key] = val.collect{|e|e['value']}
161
- elsif ['affiliate'].include?(key)
162
- new_plan[key] = eval(value)
163
- elsif ['is_custom','public','store_base_plan'].include?(key)
164
- new_plan[key] = (value == 0 ? false : true)
165
- elsif ['test'].include?(key)
166
- new_plan[key] = (value == 0 ? nil : true)
167
- elsif ['features'].include?(key)
168
- value = eval(value)
169
- value = value.each {|e| e.delete("id")}.each {|e| e.delete("created_at")}.each {|e| e.delete("updated_at")}.group_by{|h| h['feature_id']}
170
- new_feature = {}
171
- value.each_with_index do |(k, v), index|
172
- new_feature[k] = v.first if v.class == Array
152
+ def get_local_plans(params)
153
+ plans_data = []
154
+
155
+ active_plan_id = nil
156
+ charges = @apm_db.execute( "SELECT * FROM charges WHERE shop_domain = ? ",params['shop_domain'])
157
+ active_plan_id = charges.first['plan_id'] if charges.any?
158
+
159
+ custom_plan_ids = []
160
+ plan_users = @apm_db.execute( "SELECT * FROM plan_users WHERE shop_domain = ? ",params['shop_domain'])
161
+ custom_plan_ids = plan_users.collect{|e|e['plan_id']} if plan_users.any?
162
+
163
+ custom_plan_base_ids = []
164
+ plan_data = @apm_db.execute( "SELECT * FROM plans WHERE id IN (?) AND base_plan IS NOT NULL;",custom_plan_ids)
165
+ custom_plan_base_ids = plan_data.collect{|e|e['base_plan']} if plan_data.any?
166
+
167
+ if active_plan_id && custom_plan_base_ids.include?(active_plan_id)
168
+ custom_plan_base_ids.delete(active_plan_id)
169
+ end
170
+
171
+ if custom_plan_base_ids.any?
172
+ plans = @apm_db.execute( "SELECT * FROM plans WHERE (public = ? OR id IN (?)) AND id NOT IN (?)", 1,custom_plan_ids,custom_plan_base_ids)
173
+ else
174
+ plans = @apm_db.execute( "SELECT * FROM plans WHERE (public = ? OR id IN (?))", 1,custom_plan_ids)
175
+ end
176
+
177
+ if plans.any?
178
+
179
+ plans.each do |plan|
180
+ new_plan = {}
181
+ plan.each_with_index do |(key, value), index|
182
+ if ['interval'].include?(key)
183
+ val = eval(value)
184
+ new_plan[key] = val
185
+ new_plan[key] = val['value'] if val rescue {}
186
+ elsif ['shopify_plans'].include?(key)
187
+ val = eval(value)
188
+ new_plan[key] = val.collect{|e|e['value']}
189
+ elsif ['affiliate'].include?(key)
190
+ new_plan[key] = eval(value)
191
+ elsif ['is_custom','public','store_base_plan'].include?(key)
192
+ new_plan[key] = (value == 0 ? false : true)
193
+ elsif ['test'].include?(key)
194
+ new_plan[key] = (value == 0 ? nil : true)
195
+ elsif ['features'].include?(key)
196
+ value = eval(value)
197
+ value = value.each {|e| e.delete("id")}.each {|e| e.delete("created_at")}.each {|e| e.delete("updated_at")}
198
+ new_plan[key] = value
199
+ else
200
+ new_plan[key] = value unless key.class == Integer
173
201
  end
174
- new_plan[key] = new_feature
202
+ end
203
+ plans_data.push(new_plan)
204
+ end
205
+
206
+ features_by_plans = plans_data.collect{|e|e['features']}
207
+ if features_by_plans.any? && AppManager.configuration.plan_features.any?
208
+ features_by_plans_data = []
209
+ features = AppManager.configuration.plan_features
210
+ features_by_plans.each do |features_by_plan|
211
+ features_by_plan.each do |fp|
212
+ fp['name'] = features.find{|e| e['uuid'] == fp['feature_id']}['name'] rescue nil
213
+ fp['format'] = features.find{|e| e['uuid'] == fp['feature_id']}['format'] rescue nil
214
+ features_by_plans_data.push(fp)
215
+ end
216
+ end
217
+ end
218
+
219
+ plans_data.each do |plan|
220
+ if features_by_plans_data.select{|e| e['plan_id'] == plan['id']}.size > 0
221
+ feature_hash = {}
222
+ features_by_plans_data.select{|e| e['plan_id'] == plan['id']}.each do |fp|
223
+ feature_hash[fp["feature_id"]] = fp
224
+ end
225
+ features = feature_hash
175
226
  else
176
- new_plan[key] = value unless key.class == Integer
227
+ features = nil
177
228
  end
229
+ plan['features'] = features
178
230
  end
179
- plans.push(new_plan)
180
- end
231
+
232
+ plans = plans_data
233
+ end
234
+
181
235
  return plans
182
236
  end
183
237
 
@@ -72,7 +72,7 @@ module AppManager
72
72
 
73
73
  discount_type = plan['discount_type'] || "percentage"
74
74
  discount_val = discount_type == "percentage" ? (plan['discount'].to_f/ 100) : "#{plan['discount']}"
75
- plan_discount = plan['discount'] ? { "discount" => { "durationLimitInIntervals" => (plan['cycle_count'] || nil), "value" => {"#{discount_type}" => discount_val} } } : {}
75
+ plan_discount = plan['discount'] ? { "discount" => { "durationLimitInIntervals" => (plan['cycle_count'].to_i || 0), "value" => {"#{discount_type}" => discount_val} } } : {}
76
76
 
77
77
  price_details = {
78
78
  "price": { "amount": plan['price'], "currencyCode": 'USD' },
@@ -7,8 +7,11 @@ module AppManager
7
7
  def has_plan
8
8
  if !self[AppManager.configuration.plan_id_or_name_field]
9
9
  return false;
10
+ end
11
+ if self[AppManager.configuration.field_names['grandfathered']]
12
+ return true;
10
13
  end
11
- plan_id = self.plan_id
14
+ plan_id = self[AppManager.configuration.plan_id_or_name_field]
12
15
  if !plan_id
13
16
  Rails.logger.info "Plan id found nil or not set"
14
17
  return false;
@@ -26,9 +29,9 @@ module AppManager
26
29
 
27
30
 
28
31
  def plan_features
29
- plan_id = self.plan_id
32
+ plan_id = self[AppManager.configuration.plan_id_or_name_field]
30
33
  if !plan_id
31
- raise "Plan id not found"
34
+ raise Error, "Plan id not found"
32
35
  end
33
36
  plan_obj = AppManager::Client.new
34
37
  plans = plan_obj.get_plan(plan_id)
@@ -70,6 +73,27 @@ module AppManager
70
73
  shop_domain ? plan_obj.get_remaining_days(shop_domain,trial_activated_at_val,plan_id) : 0
71
74
  end
72
75
 
76
+
77
+ def get_plan
78
+ if !self[AppManager.configuration.plan_id_or_name_field]
79
+ raise Error, "Invalid params, must have charge_id,shop && plan"
80
+ end
81
+ plan_obj = AppManager::Client.new
82
+ return plan_obj.get_plan(self[AppManager.configuration.plan_id_or_name_field])
83
+ end
84
+
85
+ def get_charge
86
+ begin
87
+ shop_domain = self[AppManager.configuration.shopify_domain_field]
88
+ plan_obj = AppManager::Client.new
89
+ return plan_obj.get_charge(self[AppManager.configuration.shopify_domain_field])
90
+ rescue Exception => e
91
+ return "#{e.inspect}"
92
+ end
93
+ end
94
+
95
+
96
+
73
97
  private
74
98
 
75
99
  def casted_value(value,value_type)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppManager
4
- VERSION = "1.1.0"
4
+ VERSION = "1.1.1"
5
5
  end
data/lib/app_manager.rb CHANGED
@@ -15,6 +15,7 @@ require "app_manager/protection"
15
15
  require "app_manager/model"
16
16
  require "app_manager/fail_safe"
17
17
  require 'app_manager/railtie' if defined?(Rails)
18
+ require 'app_manager/exceptions'
18
19
 
19
20
  module AppManager
20
21
  def self.configure
@@ -1,7 +1,10 @@
1
1
  require "rails/generators/base"
2
+ require "rails/generators/active_record"
3
+
2
4
  module AppManager
3
5
  module Generators
4
6
  class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
5
8
  source_root File.expand_path('../templates', __FILE__)
6
9
 
7
10
  def mount_engine
@@ -16,6 +19,25 @@ module AppManager
16
19
  template("app_manager.rb", "config/initializers/app_manager.rb")
17
20
  end
18
21
 
22
+ def create_plan_trial_grandfathered_to_shops_migration
23
+ migration_template("add_plan_trial_grandfathered_to_shops.erb", "db/migrate/add_plan_trial_grandfathered_to_shops.rb")
24
+ end
25
+
26
+ private
27
+
28
+ def rails_migration_version
29
+ Rails.version.match(/\d\.\d/)[0]
30
+ end
31
+
32
+ class << self
33
+ private :next_migration_number
34
+
35
+ # for generating a timestamp when using `create_migration`
36
+ def next_migration_number(dir)
37
+ ActiveRecord::Generators::Base.next_migration_number(dir)
38
+ end
39
+ end
40
+
19
41
  end
20
42
  end
21
43
  end
@@ -0,0 +1,7 @@
1
+ class AddPlanTrialGrandfatheredToShops < ActiveRecord::Migration[<%= rails_migration_version %>]
2
+ def change
3
+ add_column :shops, :plan_id, :bigint unless column_exists? :shops, :plan_id
4
+ add_column :shops, :trial_activated_at, :datetime unless column_exists? :shops, :trial_activated_at
5
+ add_column :shops, :grandfathered, :boolean unless column_exists? :shops, :grandfathered
6
+ end
7
+ end
@@ -11,10 +11,11 @@ AppManager.configure do |config|
11
11
  'name' => 'shopify_domain', # demo-rahul-tiwari.myshopify.com
12
12
  'shopify_email' => 'email', # rahul.t@hulkapps.com
13
13
  'shopify_token' => 'shopify_token',
14
- 'shopify_plan' => 'plan_name', # partner_test
14
+ 'shopify_plan' => 'shopify_plan', # partner_test
15
15
  'plan_id' => 'plan_id', # 1. t
16
16
  'created_at' => 'created_at', # 2022-04-15 10:43:05
17
- 'trial_activated_at' => 'trial_activated_at' # field name that stores trial start/activated date
17
+ 'trial_activated_at' => 'trial_activated_at', # field name that stores trial start/activated date
18
+ 'grandfathered' => 'grandfathered'
18
19
  }
19
20
  config.plan_features = [
20
21
  {
@@ -24,7 +25,10 @@ AppManager.configure do |config|
24
25
  "description" => "Feature Description",
25
26
  "value_type" => "integer",
26
27
  "format" => "count",
27
- "display_order" => 1
28
+ "display_order" => 1,
29
+ "hidden_feature" => false,
30
+ "group_order" => "1",
31
+ "group" => "Group Name",
28
32
  },
29
33
  {
30
34
  "uuid" => "9f18f95a-bfaf-11ec-9d64-0242ac120002",
@@ -33,7 +37,10 @@ AppManager.configure do |config|
33
37
  "description" => "Feature Description",
34
38
  "value_type" => "boolean",
35
39
  "format" => "percentage",
36
- "display_order" => 2
40
+ "display_order" => 2,
41
+ "hidden_feature" => false,
42
+ "group_order" => "1",
43
+ "group" => "Group Name",
37
44
  },
38
45
  {
39
46
  "uuid" => "9f190a26-bfaf-11ec-9d64-0242ac120002",
@@ -42,7 +49,10 @@ AppManager.configure do |config|
42
49
  "description" => "Feature Description",
43
50
  "value_type" => "string",
44
51
  "format" => "string",
45
- "display_order" => 3
52
+ "display_order" => 3,
53
+ "hidden_feature" => false,
54
+ "group_order" => "1",
55
+ "group" => "Group Name",
46
56
  },
47
57
  {
48
58
  "uuid" => "9f191340-bfaf-11ec-9d64-0242ac12000",
@@ -55,7 +65,23 @@ AppManager.configure do |config|
55
65
  "val 2"
56
66
  ],
57
67
  "format" => "string",
58
- "display_order" => 4
68
+ "display_order" => 4,
69
+ "hidden_feature" => false,
70
+ "group_order" => "1",
71
+ "group" => "Group Name",
59
72
  }
60
- ] #Required, Values type : integer, boolean, string, array
61
- end
73
+ ]
74
+ end
75
+ #Required, Values type : integer, boolean, string, array #
76
+ #Format: percentage, count, string
77
+
78
+
79
+ #################################################
80
+ # Following method receives payload after charge created functionality. Use this for 'MauticCall'
81
+ # payload contains plan, charge and previous_charge
82
+
83
+ ActiveSupport::Notifications.subscribe "charge_created" do |name, start, finish, id, payload|
84
+ Rails.logger.debug "========APP MANAGER========="
85
+ Rails.logger.debug "DATA : #{payload}"
86
+ Rails.logger.debug "========APP MANAGER========="
87
+ 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.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hulkapps
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-01 00:00:00.000000000 Z
11
+ date: 2022-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -85,6 +85,7 @@ files:
85
85
  - app/controllers/app_manager/charges_controller.rb
86
86
  - app/controllers/app_manager/plans_controller.rb
87
87
  - app/controllers/concerns/app_manager/authenticate.rb
88
+ - app/services/app_manager/event_handler.rb
88
89
  - app_manager-0.1.0.gem
89
90
  - app_manager.gemspec
90
91
  - bin/console
@@ -99,6 +100,7 @@ files:
99
100
  - lib/app_manager/client/plans.rb
100
101
  - lib/app_manager/config.rb
101
102
  - lib/app_manager/engine.rb
103
+ - lib/app_manager/exceptions.rb
102
104
  - lib/app_manager/fail_safe.rb
103
105
  - lib/app_manager/graphql_helper.rb
104
106
  - lib/app_manager/model.rb
@@ -108,6 +110,7 @@ files:
108
110
  - lib/app_manager/tasks/sync/local_app_manager.rake
109
111
  - lib/app_manager/version.rb
110
112
  - lib/generators/app_manager/install/install_generator.rb
113
+ - lib/generators/app_manager/install/templates/add_plan_trial_grandfathered_to_shops.erb
111
114
  - lib/generators/app_manager/install/templates/app_manager.rb.tt
112
115
  homepage: https://www.hulkapps.com
113
116
  licenses: []