app_manager 0.1.0 → 1.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 +4 -4
- data/.github/workflows/ruby.yml +5 -6
- data/Gemfile +2 -2
- data/Gemfile.lock +16 -24
- data/README.md +119 -13
- data/app/controllers/app_manager/application_controller.rb +7 -0
- data/app/controllers/app_manager/banners_controller.rb +7 -2
- data/app/controllers/app_manager/charges_controller.rb +122 -0
- data/app/controllers/app_manager/plans_controller.rb +157 -0
- data/app/controllers/concerns/app_manager/authenticate.rb +10 -0
- data/app_manager-0.1.0.gem +0 -0
- data/app_manager.gemspec +3 -3
- data/config/routes.rb +14 -1
- data/lib/app_manager/actions.rb +10 -0
- data/lib/app_manager/api_cache_handler.rb +67 -0
- data/lib/app_manager/client/banners.rb +1 -1
- data/lib/app_manager/client/connection.rb +37 -3
- data/lib/app_manager/client/plans.rb +40 -0
- data/lib/app_manager/client.rb +15 -7
- data/lib/app_manager/config.rb +82 -0
- data/lib/app_manager/fail_safe.rb +324 -0
- data/lib/app_manager/graphql_helper.rb +125 -0
- data/lib/app_manager/model.rb +98 -0
- data/lib/app_manager/protection.rb +21 -0
- data/lib/app_manager/railtie.rb +10 -0
- data/lib/app_manager/response_cache.rb +40 -0
- data/lib/app_manager/tasks/sync/local_app_manager.rake +12 -0
- data/lib/app_manager/version.rb +1 -1
- data/lib/app_manager.rb +22 -2
- data/lib/generators/app_manager/install/install_generator.rb +8 -0
- data/lib/generators/app_manager/install/templates/app_manager.rb.tt +61 -0
- metadata +46 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d1ca5e305b62425f916bcb20e5677a2bc0be1e4b16f2d68879dcce443da5ffe
|
4
|
+
data.tar.gz: 1d174e5fbd19029a498c539ae908089dfcab7dea8b4d2f43d8e3bf48b9b354ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b846e8b38a8fcb8301715c137f23e875828195c9b73bca8e1bbb814cf66fee9565690a296465757955d267fc290f574ba3434a63449657444c52144e0ad7c31
|
7
|
+
data.tar.gz: 00cdb184943ace69f37c5e166950791e193c67e071a88692a7b81d45de79a5d648ee2c70887c5f3cc1eea1d2ec5df82a7632aa9ae241c7f518c7f8ef52f31abe
|
data/.github/workflows/ruby.yml
CHANGED
@@ -23,20 +23,19 @@ jobs:
|
|
23
23
|
runs-on: ubuntu-latest
|
24
24
|
strategy:
|
25
25
|
matrix:
|
26
|
-
ruby-version: ['2.7'
|
26
|
+
ruby-version: ['2.7']
|
27
27
|
|
28
28
|
steps:
|
29
|
-
- uses: actions/checkout@
|
29
|
+
- uses: actions/checkout@v2
|
30
30
|
- name: Set up Ruby
|
31
31
|
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
32
32
|
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
33
|
-
|
34
|
-
uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
|
33
|
+
uses: ruby/setup-ruby@v1
|
34
|
+
# uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
|
35
35
|
with:
|
36
36
|
ruby-version: ${{ matrix.ruby-version }}
|
37
37
|
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
38
38
|
- name: Run tests
|
39
39
|
run: |
|
40
40
|
bundle install
|
41
|
-
bundle exec rspec spec
|
42
|
-
|
41
|
+
bundle exec rspec spec
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
app_manager (
|
4
|
+
app_manager (1.0.0)
|
5
5
|
httparty
|
6
|
+
kaminari (>= 0.16.3)
|
6
7
|
rails (>= 5.2.0)
|
8
|
+
sqlite3 (~> 1.3.0)
|
7
9
|
|
8
10
|
GEM
|
9
11
|
remote: https://rubygems.org/
|
@@ -75,7 +77,6 @@ GEM
|
|
75
77
|
tzinfo (~> 2.0)
|
76
78
|
addressable (2.8.0)
|
77
79
|
public_suffix (>= 2.0.2, < 5.0)
|
78
|
-
ast (2.4.2)
|
79
80
|
builder (3.2.4)
|
80
81
|
coderay (1.1.3)
|
81
82
|
concurrent-ruby (1.1.10)
|
@@ -95,6 +96,18 @@ GEM
|
|
95
96
|
i18n (1.10.0)
|
96
97
|
concurrent-ruby (~> 1.0)
|
97
98
|
io-wait (0.2.1)
|
99
|
+
kaminari (1.2.2)
|
100
|
+
activesupport (>= 4.1.0)
|
101
|
+
kaminari-actionview (= 1.2.2)
|
102
|
+
kaminari-activerecord (= 1.2.2)
|
103
|
+
kaminari-core (= 1.2.2)
|
104
|
+
kaminari-actionview (1.2.2)
|
105
|
+
actionview
|
106
|
+
kaminari-core (= 1.2.2)
|
107
|
+
kaminari-activerecord (1.2.2)
|
108
|
+
activerecord
|
109
|
+
kaminari-core (= 1.2.2)
|
110
|
+
kaminari-core (1.2.2)
|
98
111
|
loofah (2.15.0)
|
99
112
|
crass (~> 1.0.2)
|
100
113
|
nokogiri (>= 1.5.9)
|
@@ -128,11 +141,6 @@ GEM
|
|
128
141
|
nokogiri (1.13.3)
|
129
142
|
mini_portile2 (~> 2.8.0)
|
130
143
|
racc (~> 1.4)
|
131
|
-
nokogiri (1.13.3-x86_64-linux)
|
132
|
-
racc (~> 1.4)
|
133
|
-
parallel (1.22.0)
|
134
|
-
parser (3.1.1.0)
|
135
|
-
ast (~> 2.4.1)
|
136
144
|
pry (0.14.1)
|
137
145
|
coderay (~> 1.1)
|
138
146
|
method_source (~> 1.0)
|
@@ -167,9 +175,7 @@ GEM
|
|
167
175
|
rake (>= 12.2)
|
168
176
|
thor (~> 1.0)
|
169
177
|
zeitwerk (~> 2.5)
|
170
|
-
rainbow (3.1.1)
|
171
178
|
rake (13.0.6)
|
172
|
-
regexp_parser (2.2.1)
|
173
179
|
rexml (3.2.5)
|
174
180
|
rspec (3.11.0)
|
175
181
|
rspec-core (~> 3.11.0)
|
@@ -186,24 +192,12 @@ GEM
|
|
186
192
|
diff-lcs (>= 1.2.0, < 2.0)
|
187
193
|
rspec-support (~> 3.11.0)
|
188
194
|
rspec-support (3.11.0)
|
189
|
-
|
190
|
-
parallel (~> 1.10)
|
191
|
-
parser (>= 3.1.0.0)
|
192
|
-
rainbow (>= 2.2.2, < 4.0)
|
193
|
-
regexp_parser (>= 1.8, < 3.0)
|
194
|
-
rexml
|
195
|
-
rubocop-ast (>= 1.16.0, < 2.0)
|
196
|
-
ruby-progressbar (~> 1.7)
|
197
|
-
unicode-display_width (>= 1.4.0, < 3.0)
|
198
|
-
rubocop-ast (1.16.0)
|
199
|
-
parser (>= 3.1.1.0)
|
200
|
-
ruby-progressbar (1.11.0)
|
195
|
+
sqlite3 (1.3.13)
|
201
196
|
strscan (3.0.1)
|
202
197
|
thor (1.2.1)
|
203
198
|
timeout (0.2.0)
|
204
199
|
tzinfo (2.0.4)
|
205
200
|
concurrent-ruby (~> 1.0)
|
206
|
-
unicode-display_width (2.1.0)
|
207
201
|
webmock (3.14.0)
|
208
202
|
addressable (>= 2.8.0)
|
209
203
|
crack (>= 0.3.2)
|
@@ -220,12 +214,10 @@ PLATFORMS
|
|
220
214
|
DEPENDENCIES
|
221
215
|
app_manager!
|
222
216
|
dotenv (~> 2.1.1)
|
223
|
-
minitest (~> 5.0)
|
224
217
|
pry
|
225
218
|
rake (~> 13.0)
|
226
219
|
rspec
|
227
220
|
rspec-github
|
228
|
-
rubocop (~> 1.7)
|
229
221
|
webmock
|
230
222
|
|
231
223
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -1,21 +1,16 @@
|
|
1
1
|
# AppManager
|
2
2
|
|
3
|
-
Welcome to
|
3
|
+
Welcome to the new gem of Hulkapps.com ! An API wrapper of Hulkapps.com's AppManager portal.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
Step 1)
|
8
|
-
|
9
|
-
bundle config --local GITHUB__COM x___access___token:ACCESS_TOKEN_GITHUB
|
10
|
-
|
11
|
-
|
12
|
-
Step 2) Add this line to your application's Gemfile:
|
7
|
+
Step 1) Add following line to your application's Gemfile:
|
13
8
|
|
14
9
|
```ruby
|
15
|
-
gem 'app_manager'
|
10
|
+
gem 'app_manager'
|
16
11
|
```
|
17
12
|
|
18
|
-
Step
|
13
|
+
Step 2) Execute following in terminal:
|
19
14
|
|
20
15
|
bundle install
|
21
16
|
|
@@ -23,22 +18,133 @@ Step 3) And then execute:
|
|
23
18
|
rails g app_manager:install
|
24
19
|
|
25
20
|
|
26
|
-
this install command will mount routes in your rails route.
|
21
|
+
this install command will mount routes in your rails route and will create a config file at ```config/initializers/app_manager.rb```
|
22
|
+
|
23
|
+
```
|
24
|
+
AppManager.configure do |config|
|
25
|
+
config.enable_caching = false # Optional, True to enable app-manager api response caching, default is enabled from gem
|
26
|
+
config.expires_in = 1.days # Optional, Example: 30.seconds, 5.minutes or 2.days Default caching is for 1.days from gem
|
27
|
+
config.app_url = '' # App URL like https://volumediscount.hulkapps.dev/ or #https://5044-2409-4052-209a-69da-9d7-925a-9418-a9c3.ngrok.io
|
28
|
+
config.shopify_api_key = '' # Shopify api key of app
|
29
|
+
config.shopify_api_version = '' # Must be 2022-04 or latest
|
30
|
+
config.shopify_table_name = 'shops' # Table name which is generated by shopify mostly it is 'shops'
|
31
|
+
config.shopify_domain_field = 'shopify_domain' #shopify domain field
|
32
|
+
config.plan_id_or_name_field = 'plan_id'
|
33
|
+
config.field_names = {
|
34
|
+
'name' => 'shopify_domain', # demo-rahul-tiwari.myshopify.com
|
35
|
+
'shopify_email' => 'email', # rahul.t@hulkapps.com
|
36
|
+
'shopify_token' => 'shopify_token',
|
37
|
+
'shopify_plan' => 'plan_name', # partner_test
|
38
|
+
'plan_id' => 'plan_id', # 1. t
|
39
|
+
'created_at' => 'created_at', # 2022-04-15 10:43:05
|
40
|
+
'trial_activated_at' => 'trial_activated_at' # field name that stores trial start/activated date
|
41
|
+
}
|
42
|
+
config.plan_features = [
|
43
|
+
{
|
44
|
+
"uuid" => "b48a3a6c-c1fb-11ec-9d64-0242ac120002",
|
45
|
+
"name" => "Features 1",
|
46
|
+
"slug" => "feature-1",
|
47
|
+
"description" => "Feature Description",
|
48
|
+
"value_type" => "integer",
|
49
|
+
"format" => "count",
|
50
|
+
"display_order" => 1
|
51
|
+
},
|
52
|
+
{
|
53
|
+
"uuid" => "9f18f95a-bfaf-11ec-9d64-0242ac120002",
|
54
|
+
"name" => "Features 2",
|
55
|
+
"slug" => "feature-2",
|
56
|
+
"description" => "Feature Description",
|
57
|
+
"value_type" => "boolean",
|
58
|
+
"format" => "percentage",
|
59
|
+
"display_order" => 2
|
60
|
+
},
|
61
|
+
{
|
62
|
+
"uuid" => "9f190a26-bfaf-11ec-9d64-0242ac120002",
|
63
|
+
"name" => "Features 3",
|
64
|
+
"slug" => "feature-3",
|
65
|
+
"description" => "Feature Description",
|
66
|
+
"value_type" => "string",
|
67
|
+
"format" => "string",
|
68
|
+
"display_order" => 3
|
69
|
+
},
|
70
|
+
{
|
71
|
+
"uuid" => "9f191340-bfaf-11ec-9d64-0242ac12000",
|
72
|
+
"name" => "Features 4",
|
73
|
+
"slug" => "feature-4",
|
74
|
+
"description" => "Feature Description",
|
75
|
+
"value_type" => "array",
|
76
|
+
"values" => [
|
77
|
+
"val 1",
|
78
|
+
"val 2"
|
79
|
+
],
|
80
|
+
"format" => "string",
|
81
|
+
"display_order" => 4
|
82
|
+
}
|
83
|
+
] #Required, Values type : integer, boolean, string, array
|
84
|
+
end
|
85
|
+
```
|
27
86
|
|
87
|
+
|
88
|
+
Please note: Your shops table must have 'plan_id' as int/bigint and 'trial_activated_at' as datetime otherwise add its migration. Sample example:
|
89
|
+
```
|
90
|
+
class AddPlanIdToShops < ActiveRecord::Migration[5.2]
|
91
|
+
def change
|
92
|
+
add_column :shops, :plan_id, :bigint
|
93
|
+
add_column :shops, :trial_activated_at, :datetime
|
94
|
+
end
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
and map these new fields in 'config.field_names' in above initializer file.
|
28
99
|
|
29
|
-
Step
|
100
|
+
Step 3) You must have to set ENV variable with key 'APP_MANAGER_ACCESS_TOKEN' in your application.yml or .env file like this:
|
101
|
+
|
102
|
+
APP_MANAGER_ACCESS_TOKEN: 'XXXXXXXXXXXXXXXXXXX'
|
103
|
+
APP_MANAGER_API_URL: 'https://XXXXXXXX.com'
|
104
|
+
|
105
|
+
Steps 4) App Manager provides a rake task that must needs to include in your existing app cron for every 10 minutes. Like if you are using [whenever](https://github.com/javan/whenever) gem then you must need to include following rake take in your 'schedule.rb' (created by whenever gem)
|
106
|
+
|
107
|
+
```
|
108
|
+
every 10.minutes do
|
109
|
+
rake 'sync:local_app_manager'
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
Steps 5) App Manager provides a helper module which needs to include in your 'shop' model something like below
|
114
|
+
|
115
|
+
```
|
116
|
+
class Shop < ActiveRecord::Base
|
117
|
+
include AppManager::Model
|
118
|
+
end
|
119
|
+
```
|
30
120
|
|
31
|
-
APP_MANAGER_ACCESS_TOKEN: 'XXXXXXXXXXXXXXXXXXX'
|
32
121
|
|
33
122
|
## Usage
|
34
123
|
|
124
|
+
Using above 5th step you can access following methods from your shop object.
|
125
|
+
|
126
|
+
```
|
127
|
+
@shop.has_plan # return true or false
|
128
|
+
|
129
|
+
@shop.plan_features # return array of plan features of your shop's plan
|
130
|
+
|
131
|
+
@shop.has_feature('feature-1') # provide slug of feature which you set in your 'config.plan_features' in config/initializers/app_manager.rb
|
132
|
+
#return true/false
|
133
|
+
|
134
|
+
@shop.get_feature('feature-3') # provide slug of feature and this returns value of feature which is set in portal.
|
135
|
+
|
136
|
+
@shop.get_remaining_days # return integer based on trial activated date.
|
137
|
+
```
|
138
|
+
|
139
|
+
|
140
|
+
|
35
141
|
#### As a helper:
|
36
142
|
|
37
143
|
|
38
144
|
Then, initialize app_manager instance like with App Manager Portal access:
|
39
145
|
|
40
146
|
```ruby
|
41
|
-
ob = AppManager::Client.new('
|
147
|
+
ob = AppManager::Client.new(ENV['APP_MANAGER_ACCESS_TOKEN'])
|
42
148
|
```
|
43
149
|
|
44
150
|
To get banners use this command:
|
@@ -1,5 +1,12 @@
|
|
1
1
|
module AppManager
|
2
2
|
class ApplicationController < ActionController::Base
|
3
|
+
include AppManager::Actions
|
4
|
+
cache_response_of_app_manager
|
3
5
|
protect_from_forgery with: :exception
|
6
|
+
include AppManager::Authenticate
|
7
|
+
# rescue_from StandardError do |exception|
|
8
|
+
# render json: { :error => exception.message }, :status => 500
|
9
|
+
# end
|
10
|
+
|
4
11
|
end
|
5
12
|
end
|
@@ -3,8 +3,13 @@ require_dependency "app_manager/application_controller"
|
|
3
3
|
module AppManager
|
4
4
|
class BannersController < ApplicationController
|
5
5
|
def marketing_banner
|
6
|
-
|
7
|
-
|
6
|
+
begin
|
7
|
+
banner_obj = AppManager::Client.new
|
8
|
+
render json: banner_obj.get_banners
|
9
|
+
rescue Exception => e
|
10
|
+
@fs = AppManager::FailSafe.new
|
11
|
+
render json: @fs.get_local_app_structures
|
12
|
+
end
|
8
13
|
end
|
9
14
|
end
|
10
15
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require_dependency "app_manager/application_controller"
|
2
|
+
|
3
|
+
module AppManager
|
4
|
+
class ChargesController < ApplicationController
|
5
|
+
include HTTParty
|
6
|
+
skip_before_action :verify_authenticity_token, :only => [:process_plan]
|
7
|
+
before_action :params_permit
|
8
|
+
require 'time'
|
9
|
+
require 'rack'
|
10
|
+
|
11
|
+
def process_plan
|
12
|
+
if params[:shop].present? && params[:plan_id].present?
|
13
|
+
@shop = shop_data
|
14
|
+
if !@shop.nil?
|
15
|
+
plan_obj = AppManager::Client.new
|
16
|
+
plan_data = plan_obj.get_plan(params[:plan_id],params[:shop])
|
17
|
+
if plan_data.present? && plan_data.is_a?(Hash)
|
18
|
+
request_data = {'shop' => @shop.shopify_domain, 'timestamp' => Time.now.to_i, 'plan' => params[:plan_id]}
|
19
|
+
return_url = "#{app_url}#{plan_callback_path}?#{Rack::Utils.build_query(request_data)}"
|
20
|
+
gq_obj = AppManager::GraphqlHelper.new(@shop.shopify_domain,@shop.shopify_token)
|
21
|
+
data = gq_obj.recurring_charge_api_call(plan_data,return_url,@shop)
|
22
|
+
if !data["errors"].present? && (data["data"].present? && data["data"]["appSubscriptionCreate"].present? && ( !data["data"]["appSubscriptionCreate"]["userErrors"].any? && data["data"]["appSubscriptionCreate"]["confirmationUrl"]))
|
23
|
+
redirect_charge = data["data"]["appSubscriptionCreate"]["confirmationUrl"]
|
24
|
+
render json: {'redirect_url' => redirect_charge}
|
25
|
+
else
|
26
|
+
render json: {'error' => data["errors"].as_json}
|
27
|
+
end
|
28
|
+
else
|
29
|
+
render json: {'error' => data["errors"]}
|
30
|
+
end
|
31
|
+
else
|
32
|
+
render json: {'error' => 'Shop not found'}
|
33
|
+
end
|
34
|
+
else
|
35
|
+
render json: {'error' => 'Missing Shop domain or plan id in params'}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def callback
|
41
|
+
if params[:charge_id].present? && params[:shop].present? && params[:plan].present?
|
42
|
+
@shop = shop_data
|
43
|
+
shopify_token = @field_names['shopify_token']
|
44
|
+
shopify_domain = @field_names['name']
|
45
|
+
if !@shop.nil?
|
46
|
+
headers = {"X-Shopify-Access-Token" => @shop[shopify_token]}
|
47
|
+
charges = HTTParty.get('https://'+@shop[shopify_domain]+'/admin/api/'+@api_version+'/recurring_application_charges/'+params[:charge_id]+'.json', :headers => headers)
|
48
|
+
|
49
|
+
if charges.parsed_response && charges.parsed_response.is_a?(Hash) && charges.parsed_response.has_key?('recurring_application_charge')
|
50
|
+
|
51
|
+
plan_obj = AppManager::Client.new
|
52
|
+
plan_data = plan_obj.get_plan(params[:plan],params[:shop])
|
53
|
+
|
54
|
+
charge = charges.parsed_response['recurring_application_charge']
|
55
|
+
charge['charge_id'] = charge['id'];
|
56
|
+
charge['type'] = 'recurring';
|
57
|
+
charge['plan_id'] = params[:plan];
|
58
|
+
charge['shop_domain'] = params[:shop];
|
59
|
+
charge['interval'] = plan_data['interval']['value'];
|
60
|
+
|
61
|
+
if !@plan_field.nil?
|
62
|
+
begin
|
63
|
+
plan_obj.cancel_charge(@shop[shopify_domain],@shop[@plan_field])
|
64
|
+
rescue Exception => e
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
charge_ob = AppManager::Client.new(nil,json_req=true)
|
69
|
+
response = charge_ob.store_charge(charge.to_json)
|
70
|
+
|
71
|
+
if response['message'] == "success"
|
72
|
+
model.update(@plan_field => params[:plan])
|
73
|
+
end
|
74
|
+
redirect_to "/?shop=#{params[:shop]}"
|
75
|
+
else
|
76
|
+
|
77
|
+
render json: {'error' => 'Invalid shopify charge'}
|
78
|
+
end
|
79
|
+
else
|
80
|
+
render json: {'error' => 'Shop not found'}
|
81
|
+
end
|
82
|
+
else
|
83
|
+
render json: {'error' => 'Invalid params'}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def params_permit
|
90
|
+
params.permit!
|
91
|
+
end
|
92
|
+
|
93
|
+
def model
|
94
|
+
@models = ActiveRecord::Base.connection.tables
|
95
|
+
@config_table = AppManager.configuration.shopify_table_name
|
96
|
+
@shopify_domain = AppManager.configuration.shopify_domain_field
|
97
|
+
@plan_field = AppManager.configuration.plan_id_or_name_field
|
98
|
+
@field_names = AppManager.configuration.field_names
|
99
|
+
@api_version = AppManager.configuration.shopify_api_version
|
100
|
+
if @models.include?(@config_table) && !@plan_field.nil?
|
101
|
+
return @config_table.classify.constantize
|
102
|
+
else
|
103
|
+
return nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def shop_data
|
108
|
+
if model
|
109
|
+
return model.where(@shopify_domain => params[:shop]).first rescue nil
|
110
|
+
else
|
111
|
+
return nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def app_url
|
116
|
+
AppManager.configuration.app_url
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require_dependency "app_manager/application_controller"
|
2
|
+
|
3
|
+
module AppManager
|
4
|
+
class PlansController < ApplicationController
|
5
|
+
skip_before_action :verify_authenticity_token, :only => [:active_without_plan,:burst_cache,:fail_safe_backup]
|
6
|
+
def index
|
7
|
+
render :json => {"features" => AppManager.configuration.plan_features || []}
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def plans
|
12
|
+
active_plan_id_or_name = shopify_plan = plan = nil
|
13
|
+
default_plan_id = nil
|
14
|
+
plan_obj = AppManager::Client.new
|
15
|
+
plans = plan_obj.get_plans
|
16
|
+
if params[:shop_domain].present? && !AppManager.configuration.plan_features.nil?
|
17
|
+
@shop = shop_data
|
18
|
+
if !@shop.nil?
|
19
|
+
active_plan_id_or_name = @shop[@plan_field]
|
20
|
+
if !@field_names.nil? && @field_names.has_key?('shopify_plan') && !@field_names.nil?
|
21
|
+
shopify_plan_field = AppManager.configuration.field_names['shopify_plan']
|
22
|
+
shopify_plan = @shop[shopify_plan_field] rescue nil
|
23
|
+
plan = plans.any? && !active_plan_id_or_name.nil? ? (plans.find{|x| x["id"] == active_plan_id_or_name}.present? ? plans.find{|x| x["id"] == active_plan_id_or_name} : nil ) : nil
|
24
|
+
end
|
25
|
+
else
|
26
|
+
Rails.logger.info "APP MANGAGER >>>> Either model is defined wrong or config.plan_id_or_name_field is nil in initializer ==="
|
27
|
+
end
|
28
|
+
else
|
29
|
+
Rails.logger.info "APP MANGAGER >>>> Either params missing store_domain or config.plan_features is nil in initializer ==="
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
default_plan_id = 0;
|
34
|
+
default_plan_data = plans.select{|x| x['interval'] == 'EVERY_30_DAYS' }.sort_by { |k| -k["price"] }
|
35
|
+
store_base_plan = default_plan_data.map{|e| e['store_base_plan']}.first rescue false
|
36
|
+
|
37
|
+
if store_base_plan
|
38
|
+
begin
|
39
|
+
shopify_plans = default_plan_data.map { |e| e.map { |key, value| [e['shopify_plans'], e['id']] }.to_h }
|
40
|
+
shopify_plans.each do |shp|
|
41
|
+
if shp.keys && shp.keys.first && shp.keys.first.class == Array
|
42
|
+
if shp.keys.first.include?(shopify_plan) && shp.values && shp.values.first && shp.values.first.to_i > 0
|
43
|
+
default_plan_id = shp.values.first.to_i
|
44
|
+
break
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
rescue Exception => e
|
49
|
+
Rails.logger.info "APP MANGAGER >>>> ERROR #{e.inspect}"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
default_plan_id = default_plan_data.map{|e| e['id']}.first if default_plan_data.any? rescue nil
|
53
|
+
end
|
54
|
+
|
55
|
+
response = {
|
56
|
+
'plans' => plan_obj.get_plans,
|
57
|
+
'shopify_plan' => shopify_plan,
|
58
|
+
'plan' => plan,
|
59
|
+
'default_plan_id' => default_plan_id
|
60
|
+
}
|
61
|
+
render json: response
|
62
|
+
end
|
63
|
+
|
64
|
+
def users
|
65
|
+
if model
|
66
|
+
data = model.page(params[:page]).per(10)
|
67
|
+
users = {
|
68
|
+
"current_page" => data.current_page,
|
69
|
+
"data" => data.collect{|st| @field_names.map{ |key, value| [key, "#{st[value]}"] }.to_h },
|
70
|
+
"first_page_url" => "#{app_url}/api/app-manager/users?page=1",
|
71
|
+
"from" => data.total_pages ? 1 : nil,
|
72
|
+
"last_page" => data.total_pages,
|
73
|
+
"last_page_url" => data.total_pages ? "#{app_url}/api/app-manager/users?page=#{data.total_pages}" : nil,
|
74
|
+
"links"=> '',
|
75
|
+
"next_page_url" => data.next_page ? "#{app_url}/api/app-manager/users?page=#{data.next_page}" : nil,
|
76
|
+
"path" => "#{app_url}/api/app-manager/users",
|
77
|
+
"per_page" => 1,
|
78
|
+
"prev_page_url" => data.prev_page ? "#{app_url}/api/app-manager/users?page=#{data.prev_page}" : nil,
|
79
|
+
"to" => data.total_pages,
|
80
|
+
"total" => data.total_pages
|
81
|
+
}
|
82
|
+
render json: users
|
83
|
+
|
84
|
+
else
|
85
|
+
render json: nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def active_without_plan
|
90
|
+
if params[:shop_domain].present? && params[:plan_id].present? && model
|
91
|
+
@trial_activated_field = AppManager.configuration.field_names['trial_activated_at']
|
92
|
+
model.update(@plan_field => params[:plan_id],@trial_activated_field => DateTime.now)
|
93
|
+
render json: {'status' => true}
|
94
|
+
else
|
95
|
+
render json: {'status' => false,'error' => 'Shop not found or missing shop'}, status: 422
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
def burst_cache
|
101
|
+
AppManager.clear_cache
|
102
|
+
head :ok
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
def fail_safe_backup
|
107
|
+
params_permit
|
108
|
+
@fs = AppManager::FailSafe.new
|
109
|
+
begin
|
110
|
+
@fs.sync_app_manager
|
111
|
+
rescue Exception => e
|
112
|
+
Rails.logger.info "APP MANGAGER >>>> LOCAL DB couldn't sync with POTAL DB #{e.inspect}"
|
113
|
+
end
|
114
|
+
|
115
|
+
begin
|
116
|
+
@fs.save_api_data(params)
|
117
|
+
rescue Exception => e
|
118
|
+
Rails.logger.info "APP MANGAGER >>>> #{e.inspect}"
|
119
|
+
end
|
120
|
+
head :ok
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def params_permit
|
127
|
+
params.permit!
|
128
|
+
end
|
129
|
+
|
130
|
+
def model
|
131
|
+
@models = ActiveRecord::Base.connection.tables
|
132
|
+
@config_table = AppManager.configuration.shopify_table_name
|
133
|
+
@shopify_domain = AppManager.configuration.shopify_domain_field
|
134
|
+
@plan_field = AppManager.configuration.plan_id_or_name_field
|
135
|
+
@field_names = AppManager.configuration.field_names
|
136
|
+
@api_version = AppManager.configuration.shopify_api_version
|
137
|
+
if @models.include?(@config_table) && !@plan_field.nil?
|
138
|
+
return @config_table.classify.constantize
|
139
|
+
else
|
140
|
+
return nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def shop_data
|
145
|
+
if model
|
146
|
+
return model.where(@shopify_domain => params[:shop_domain]).first rescue nil
|
147
|
+
else
|
148
|
+
return nil
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def app_url
|
153
|
+
AppManager.configuration.app_url
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
end
|
Binary file
|
data/app_manager.gemspec
CHANGED
@@ -31,9 +31,9 @@ Gem::Specification.new do |spec|
|
|
31
31
|
# Uncomment to register a new dependency of your gem
|
32
32
|
# spec.add_dependency "example-gem", "~> 1.0"
|
33
33
|
spec.add_dependency "httparty"
|
34
|
-
spec.add_dependency "rails",
|
35
|
-
|
36
|
-
|
34
|
+
spec.add_dependency "rails", '>= 5.2.0'
|
35
|
+
spec.add_dependency "kaminari", '>= 0.16.3'
|
36
|
+
spec.add_dependency "sqlite3", '~> 1.3.0'
|
37
37
|
# For more information and examples about making a new gem, checkout our
|
38
38
|
# guide at: https://bundler.io/guides/creating_gem.html
|
39
39
|
end
|
data/config/routes.rb
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
AppManager::Engine.routes.draw do
|
2
2
|
scope 'api/app-manager' do
|
3
3
|
get 'marketing-banners' => 'banners#marketing_banner'
|
4
|
+
|
5
|
+
get 'plan-features' => 'plans#index'
|
6
|
+
get 'plans' => 'plans#plans'
|
7
|
+
get 'users' => 'plans#users'
|
8
|
+
post 'active-without-plan' => 'plans#active_without_plan'
|
9
|
+
post 'burst-cache' => 'plans#burst_cache'
|
10
|
+
post 'fail-safe-backup' => 'plans#fail_safe_backup'
|
11
|
+
get 'plan/process/:plan_id' => 'charges#process_plan'
|
12
|
+
get 'plan/callback' => 'charges#callback', as: :plan_callback
|
13
|
+
|
14
|
+
scope 'app-manager-api' do
|
15
|
+
post 'store-charge' => 'plans#store_charge'
|
16
|
+
end
|
4
17
|
end
|
5
|
-
end
|
18
|
+
end
|