flowcommerce_spree 0.0.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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +91 -0
  4. data/Rakefile +33 -0
  5. data/SPREE_FLOW.md +134 -0
  6. data/app/assets/javascripts/flowcommerce_spree/application.js +13 -0
  7. data/app/assets/stylesheets/flowcommerce_spree/application.css +15 -0
  8. data/app/controllers/concerns/current_zone_loader_decorator.rb +49 -0
  9. data/app/controllers/flowcommerce_spree/webhooks_controller.rb +25 -0
  10. data/app/helpers/flowcommerce_spree/application_helper.rb +6 -0
  11. data/app/helpers/spree/admin/orders_helper_decorator.rb +17 -0
  12. data/app/helpers/spree/core/controller_helpers/flow_io_order_helper_decorator.rb +53 -0
  13. data/app/mailers/spree/spree_order_mailer_decorator.rb +24 -0
  14. data/app/models/flowcommerce_spree/settings.rb +8 -0
  15. data/app/models/spree/credit_card_decorator.rb +9 -0
  16. data/app/models/spree/flow_io_product_decorator.rb +91 -0
  17. data/app/models/spree/flow_io_variant_decorator.rb +205 -0
  18. data/app/models/spree/gateway/spree_flow_gateway.rb +116 -0
  19. data/app/models/spree/line_item_decorator.rb +15 -0
  20. data/app/models/spree/order_decorator.rb +179 -0
  21. data/app/models/spree/promotion_decorator.rb +10 -0
  22. data/app/models/spree/promotion_handler/coupon_decorator.rb +30 -0
  23. data/app/models/spree/spree_user_decorator.rb +15 -0
  24. data/app/models/spree/taxon_decorator.rb +37 -0
  25. data/app/models/spree/zone_decorator.rb +7 -0
  26. data/app/models/spree/zones/flow_io_product_zone_decorator.rb +55 -0
  27. data/app/services/flowcommerce_spree/import_experience_items.rb +76 -0
  28. data/app/services/flowcommerce_spree/import_experiences.rb +37 -0
  29. data/app/services/flowcommerce_spree/order_sync.rb +231 -0
  30. data/app/views/layouts/flowcommerce_spree/application.html.erb +14 -0
  31. data/app/views/spree/admin/payments/index.html.erb +28 -0
  32. data/app/views/spree/admin/promotions/edit.html.erb +57 -0
  33. data/app/views/spree/admin/shared/_order_summary.html.erb +44 -0
  34. data/app/views/spree/admin/shared/_order_summary_flow.html.erb +13 -0
  35. data/app/views/spree/order_mailer/confirm_email.html.erb +86 -0
  36. data/app/views/spree/order_mailer/confirm_email.text.erb +38 -0
  37. data/config/initializers/flowcommerce_spree.rb +7 -0
  38. data/config/routes.rb +5 -0
  39. data/db/migrate/20201021160159_add_type_and_meta_to_spree_zone.rb +23 -0
  40. data/db/migrate/20201021755957_add_meta_to_spree_tables.rb +17 -0
  41. data/db/migrate/20201022173210_add_zone_type_to_spree_zone_members.rb +24 -0
  42. data/db/migrate/20201022174252_add_kind_to_zone.rb +22 -0
  43. data/lib/flow/error.rb +73 -0
  44. data/lib/flow/pay_pal.rb +25 -0
  45. data/lib/flow/simple_gateway.rb +115 -0
  46. data/lib/flowcommerce_spree.rb +31 -0
  47. data/lib/flowcommerce_spree/api.rb +48 -0
  48. data/lib/flowcommerce_spree/engine.rb +27 -0
  49. data/lib/flowcommerce_spree/experience_service.rb +65 -0
  50. data/lib/flowcommerce_spree/logging_http_client.rb +43 -0
  51. data/lib/flowcommerce_spree/logging_http_handler.rb +15 -0
  52. data/lib/flowcommerce_spree/refresher.rb +81 -0
  53. data/lib/flowcommerce_spree/session.rb +71 -0
  54. data/lib/flowcommerce_spree/version.rb +5 -0
  55. data/lib/flowcommerce_spree/webhook_service.rb +98 -0
  56. data/lib/simple_csv_writer.rb +44 -0
  57. data/lib/tasks/flowcommerce_spree.rake +289 -0
  58. metadata +220 -0
@@ -0,0 +1,289 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'flowcommerce'
4
+ require 'digest/sha1'
5
+ require 'colorize'
6
+
7
+ namespace :flowcommerce_spree do
8
+ logger = FlowcommerceSpree.logger
9
+ client = FlowcommerceSpree.client(logger: logger)
10
+ refresher = FlowcommerceSpree::Refresher.new(logger: logger)
11
+
12
+ desc 'Listing and possible invocation of all the Flow tasks'
13
+ task :list_tasks do |t|
14
+ task_list = `rake -T | grep flowcommerce_spree`.split($RS)
15
+ @exit = false
16
+ logger.info "Running task: #{t}"
17
+
18
+ loop do
19
+ puts 'Flowcommerce tasks:'
20
+ task_list.each_with_index do |task, index|
21
+ puts format(" %3d. #{task}", (index + 1))
22
+ end
23
+
24
+ print "\nType the task number to be invoked: "
25
+ task_number = $stdin.gets.to_i
26
+
27
+ if (1..task_list.size).cover?(task_number)
28
+ selected_task_name = task_list[task_number - 1].to_s.split(/\s+/)[1]
29
+ logger.info "\nRunning: #{selected_task_name}"
30
+ Rake::Task[selected_task_name].invoke
31
+ puts
32
+ else
33
+ puts "Unknown task number: #{task_number}".red, ''
34
+ end
35
+
36
+ break if @exit
37
+ end
38
+ end
39
+
40
+ # uploads catalog to Flow API using local Spree database
41
+ desc 'Upload catalog'
42
+ task upload_catalog: :environment do |t|
43
+ update_sum = 0
44
+ total_sum = 0
45
+ current_page = 0
46
+ variants = []
47
+
48
+ while current_page == 0 || !variants.empty?
49
+ current_page += 1
50
+ variants = Spree::Variant.order('updated_at desc').page(current_page).per(100).all
51
+
52
+ variants.each do |variant|
53
+ total_sum += 1
54
+ result = variant.sync_product_to_flow
55
+
56
+ # skip if sync not needed
57
+ next $stdout.print "\nVariant #{variant.sku} is synced, no need to update".green unless result
58
+
59
+ if result.is_a?(Hash) && result[:error]
60
+ $stdout.print "\nError uploading #{variant.sku}. Reason: #{result[:error]}".red
61
+ else
62
+ update_sum += 1
63
+ $stdout.print "\n#{variant.sku}: #{variant.product.name} (#{variant.price} #{variant.cost_currency})"
64
+ end
65
+ end
66
+ end
67
+
68
+ needed_update = (update_sum == 0 ? 'none' : update_sum).to_s.green
69
+ puts "\nFor total of #{total_sum.to_s.blue} products, #{needed_update} needed update"
70
+ t.reenable
71
+ end
72
+
73
+ desc 'Check if ENV vars, center and tier per experience is set'
74
+ task check: :environment do |t|
75
+ logger.info 'Environment check'
76
+ required_env_vars = %w[FLOW_TOKEN FLOW_ORGANIZATION FLOW_BASE_COUNTRY]
77
+ required_env_vars.each { |el| logger.info " ENV: #{el} - #{ENV[el].present? ? 'present'.green : 'MISSING'.red} " }
78
+ organization = FlowcommerceSpree::ORGANIZATION
79
+
80
+ logger.info 'Experiences:'
81
+ logger.info " Getting experiences for flow org: #{organization}"
82
+ experiences = client.experiences.get(organization)
83
+ logger.info " Got %d experiences - #{experiences.map(&:country).join(', ')}".green % experiences.length
84
+
85
+ # create default experience unless one exists
86
+ logger.info 'Centers:'
87
+ center_name = 'default'
88
+ current_centers = client.centers.get(organization).map(&:key)
89
+ if current_centers.include?(center_name)
90
+ logger.info " Default center: #{'present'.green}"
91
+ else
92
+ FlowcommerceSpree::Api.run(
93
+ :put, "/:organization/centers/#{center_name}", {},
94
+ 'key': center_name,
95
+ 'address': { 'contact': { 'name': { 'first': 'Kinto',
96
+ 'last': 'Doe' },
97
+ 'company': organization,
98
+ 'email': 'dcone@test.flow.io',
99
+ 'phone': '1-555-444-0001' },
100
+ 'location': { 'streets': ['88 East Broad Street'],
101
+ 'city': 'Columbus',
102
+ 'province': 'OH',
103
+ 'postal': '43215',
104
+ 'country': FlowcommerceSpree::BASE_COUNTRY } },
105
+ 'packaging': [{ 'dimensions': { 'packaging': { 'depth': { 'value': '9', 'units': 'inch' },
106
+ 'length': { 'value': '13', 'units': 'inch' },
107
+ 'weight': { 'value': '1', 'units': 'pound' },
108
+ 'width': { 'value': '3', 'units': 'inch' } } },
109
+ 'name': 'Big Box',
110
+ 'number': 'box1' }],
111
+ 'name': 'Spree Test',
112
+ 'services': [{ 'service': 'dhl-express-worldwide' },
113
+ { 'service': 'landmark-global' }],
114
+ 'schedule': { 'holiday': 'us_bank_holidays',
115
+ 'exception': [{ 'type': 'closed',
116
+ 'datetime_range': { 'from': '2016-05-05T18:30:00.000Z',
117
+ 'to': '2016-05-06T18:30:00.000Z' } }],
118
+ 'calendar': 'weekdays',
119
+ 'cutoff': '16:30' },
120
+ 'timezone': 'US/Eastern'
121
+ )
122
+ logger.info " Default center: #{'created'.blue} (run again)"
123
+ end
124
+
125
+ logger.info 'Tiers:'
126
+ experiences.each do |exp|
127
+ exp_tiers = client.tiers.get(FlowcommerceSpree::ORGANIZATION, experience: exp.key)
128
+ count = exp_tiers.length
129
+ count_desc = count == 0 ? '0 (error!)'.red : count.to_s.green
130
+ exp_services = exp_tiers.inject([]) { |total, tier| total.push(*tier.services.map(&:id)) }
131
+ services_str = if exp_services.empty?
132
+ 'and no delivery services defined!'.red
133
+ else
134
+ "with #{exp_services.length.to_s.green} delivery services defined (#{exp_services.join(', ')})"
135
+ end
136
+ logger.info " Experience #{exp.key.yellow} has #{count_desc} delivery tiers defined, #{services_str}"
137
+ end
138
+
139
+ logger.info 'Database fields (flow_data):'
140
+ [Spree::CreditCard, Spree::Product, Spree::Variant, Spree::Order, Spree::Promotion].each do |klass|
141
+ state = klass.new.respond_to?(:flow_data) ? 'exists'.green : 'not present (run DB migrations)'.red
142
+ logger.info " #{klass.to_s.ljust(18)} - #{state}"
143
+ end
144
+
145
+ logger.info 'Default store URL:'
146
+ url = Spree::Store.find_by(default: true).url
147
+ logger.info " Spree::Store.find_by(default:true).url == \"#{url.blue}\" (ensure this is valid and right URL)"
148
+
149
+ # rate cards check
150
+ ratecard_estimates_path = '/:organization/ratecard_estimates/summaries'
151
+ origins = []
152
+ errors = []
153
+ client.ratecards.get(FlowcommerceSpree::ORGANIZATION).each do |rc|
154
+ rc.origination_zones.each do |oz|
155
+ data = FlowcommerceSpree::Api.run(
156
+ :post, ratecard_estimates_path, {}, origin: oz.country, destination: origins.last || 'USA'
157
+ )
158
+
159
+ if data.is_a?(Hash) && data['code'] == 'generic_error'
160
+ errors << { origin: oz.country, messages: data['messages'] }
161
+ next
162
+ elsif data.is_a?(Array) && !data.empty?
163
+ origins << oz.country
164
+ else
165
+ errors << { origin: oz.country, messages: ['Unknown error'] }
166
+ end
167
+ end
168
+ end
169
+
170
+ unless origins.empty?
171
+ logger.info "\nRate cards set, OK:".green
172
+ origins.each_with_index do |origin, index|
173
+ logger.info format(" %3d. #{origin}", (index + 1))
174
+ end
175
+ end
176
+
177
+ unless errors.empty?
178
+ logger.info "\nRate cards errors:".red
179
+ errors.each_with_index do |err, index|
180
+ logger.info format(" %3d. Origin = #{err[:origin]}, errors:", (index + 1))
181
+ err[:messages].each do |m|
182
+ logger.info " #{m}".red
183
+ end
184
+ end
185
+ end
186
+ t.reenable
187
+ end
188
+
189
+ desc 'Sync experiences and localized product catalog items from Flow.io'
190
+ task sync_localized_items: :environment do |t|
191
+ next t.reenable unless refresher.needs_refresh?
192
+
193
+ logger.info 'Sync needed, running ...'.yellow
194
+
195
+ FlowcommerceSpree::ImportExperiences.run(with_items: true, client: client, refresher: refresher)
196
+
197
+ t.reenable
198
+ end
199
+
200
+ desc 'Force sync (no timeout) experiences and localized product catalog items from Flow.io'
201
+ task sync_localized_items_forced: :environment do |t|
202
+ next t.reenable if refresher.in_progress?
203
+
204
+ FlowcommerceSpree::ImportExperiences.run(with_items: true, client: client, refresher: refresher)
205
+
206
+ t.reenable
207
+ end
208
+
209
+ # checks existence of every item in local product catalog - remove product from flow unless exists locally
210
+ desc 'Remove unused items from flow catalog'
211
+ task clean_flow_catalog: :environment do |t|
212
+ page_size = 100
213
+ offset = 0
214
+ items = []
215
+ promises = []
216
+ thread_pool = Concurrent::FixedThreadPool.new(5)
217
+
218
+ while offset == 0 || items.length == 100
219
+ items = FlowcommerceSpree::Api.run :get, '/:organization/catalog/items', limit: page_size, offset: offset
220
+ offset += page_size
221
+
222
+ items.each do |item|
223
+ sku = item['number']
224
+
225
+ next if Spree::Variant.exists?(sku: sku)
226
+
227
+ promises << Concurrent::Promises.future_on(thread_pool, sku) do |number|
228
+ FlowcommerceSpree::Api.run :delete, "/:organization/catalog/items/#{number}"
229
+ $stdout.puts "Removed item: #{number.red}"
230
+ end
231
+ end
232
+ end
233
+
234
+ Concurrent::Promises.zip(*promises).value!
235
+ thread_pool.shutdown
236
+ thread_pool.wait_for_termination
237
+ t.reenable
238
+ end
239
+
240
+ # remove all the products from flow.io
241
+ desc 'Purge Product Catalog on flow.io'
242
+ task purge_catalog: :environment do |t|
243
+ page_size = 100
244
+ offset = 0
245
+ items = []
246
+ promises = []
247
+ thread_pool = Concurrent::FixedThreadPool.new(5)
248
+
249
+ while offset == 0 || items.length == 100
250
+ items = FlowcommerceSpree::Api.run :get, '/:organization/catalog/items', limit: page_size, offset: offset
251
+ offset += page_size
252
+
253
+ items.each do |item|
254
+ variant_sku = item['number']
255
+ promises << Concurrent::Promises.future_on(thread_pool, variant_sku) do |sku|
256
+ FlowcommerceSpree::Api.run :delete, "/:organization/catalog/items/#{sku}"
257
+ $stdout.puts "Removed item: #{sku.red}"
258
+ end
259
+ v = Spree::Variant.find_by(sku: variant_sku)
260
+ v.flow_data.delete('last_sync_sh1')
261
+ v.update_column(:meta, v.meta.to_json)
262
+ end
263
+ end
264
+
265
+ Concurrent::Promises.zip(*promises).value!
266
+ thread_pool.shutdown
267
+ thread_pool.wait_for_termination
268
+ t.reenable
269
+ end
270
+
271
+ desc 'Purge flow_data from all the Variants in the DB'
272
+ task purge_flow_data: :environment do |t|
273
+ record_counter = 0
274
+ Spree::Variant.where("meta->>'flow_data' IS NOT NULL").each do |v|
275
+ v.truncate_flow_data
276
+ record_counter += 1
277
+ print '.'
278
+ $stdout.flush
279
+ end
280
+ logger.info "\nTruncated flow_data on #{record_counter} records"
281
+
282
+ t.reenable
283
+ end
284
+
285
+ desc 'Exit list_tasks'
286
+ task exit: :environment do
287
+ @exit = true
288
+ end
289
+ end
metadata ADDED
@@ -0,0 +1,220 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flowcommerce_spree
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Aurel Branzeanu
8
+ - Sebastian De Luca
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2021-02-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: colorize
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: concurrent-ruby
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.0'
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: 1.1.7
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - "~>"
43
+ - !ruby/object:Gem::Version
44
+ version: '1.0'
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 1.1.7
48
+ - !ruby/object:Gem::Dependency
49
+ name: flowcommerce
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: flowcommerce-reference
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ type: :runtime
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ - !ruby/object:Gem::Dependency
77
+ name: oj
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ - !ruby/object:Gem::Dependency
91
+ name: pg
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.21'
97
+ type: :runtime
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.21'
104
+ - !ruby/object:Gem::Dependency
105
+ name: spree_backend
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 2.3.0
111
+ type: :runtime
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 2.3.0
118
+ - !ruby/object:Gem::Dependency
119
+ name: github_changelog_generator
120
+ requirement: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ type: :development
126
+ prerelease: false
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ description: Integration of popular Rails/Spree store framework with e-commerce Flow
133
+ API
134
+ email:
135
+ - a.branzeanu@datarockets.com
136
+ - sebastian.deluca@mejuri.com
137
+ executables: []
138
+ extensions: []
139
+ extra_rdoc_files: []
140
+ files:
141
+ - MIT-LICENSE
142
+ - README.md
143
+ - Rakefile
144
+ - SPREE_FLOW.md
145
+ - app/assets/javascripts/flowcommerce_spree/application.js
146
+ - app/assets/stylesheets/flowcommerce_spree/application.css
147
+ - app/controllers/concerns/current_zone_loader_decorator.rb
148
+ - app/controllers/flowcommerce_spree/webhooks_controller.rb
149
+ - app/helpers/flowcommerce_spree/application_helper.rb
150
+ - app/helpers/spree/admin/orders_helper_decorator.rb
151
+ - app/helpers/spree/core/controller_helpers/flow_io_order_helper_decorator.rb
152
+ - app/mailers/spree/spree_order_mailer_decorator.rb
153
+ - app/models/flowcommerce_spree/settings.rb
154
+ - app/models/spree/credit_card_decorator.rb
155
+ - app/models/spree/flow_io_product_decorator.rb
156
+ - app/models/spree/flow_io_variant_decorator.rb
157
+ - app/models/spree/gateway/spree_flow_gateway.rb
158
+ - app/models/spree/line_item_decorator.rb
159
+ - app/models/spree/order_decorator.rb
160
+ - app/models/spree/promotion_decorator.rb
161
+ - app/models/spree/promotion_handler/coupon_decorator.rb
162
+ - app/models/spree/spree_user_decorator.rb
163
+ - app/models/spree/taxon_decorator.rb
164
+ - app/models/spree/zone_decorator.rb
165
+ - app/models/spree/zones/flow_io_product_zone_decorator.rb
166
+ - app/services/flowcommerce_spree/import_experience_items.rb
167
+ - app/services/flowcommerce_spree/import_experiences.rb
168
+ - app/services/flowcommerce_spree/order_sync.rb
169
+ - app/views/layouts/flowcommerce_spree/application.html.erb
170
+ - app/views/spree/admin/payments/index.html.erb
171
+ - app/views/spree/admin/promotions/edit.html.erb
172
+ - app/views/spree/admin/shared/_order_summary.html.erb
173
+ - app/views/spree/admin/shared/_order_summary_flow.html.erb
174
+ - app/views/spree/order_mailer/confirm_email.html.erb
175
+ - app/views/spree/order_mailer/confirm_email.text.erb
176
+ - config/initializers/flowcommerce_spree.rb
177
+ - config/routes.rb
178
+ - db/migrate/20201021160159_add_type_and_meta_to_spree_zone.rb
179
+ - db/migrate/20201021755957_add_meta_to_spree_tables.rb
180
+ - db/migrate/20201022173210_add_zone_type_to_spree_zone_members.rb
181
+ - db/migrate/20201022174252_add_kind_to_zone.rb
182
+ - lib/flow/error.rb
183
+ - lib/flow/pay_pal.rb
184
+ - lib/flow/simple_gateway.rb
185
+ - lib/flowcommerce_spree.rb
186
+ - lib/flowcommerce_spree/api.rb
187
+ - lib/flowcommerce_spree/engine.rb
188
+ - lib/flowcommerce_spree/experience_service.rb
189
+ - lib/flowcommerce_spree/logging_http_client.rb
190
+ - lib/flowcommerce_spree/logging_http_handler.rb
191
+ - lib/flowcommerce_spree/refresher.rb
192
+ - lib/flowcommerce_spree/session.rb
193
+ - lib/flowcommerce_spree/version.rb
194
+ - lib/flowcommerce_spree/webhook_service.rb
195
+ - lib/simple_csv_writer.rb
196
+ - lib/tasks/flowcommerce_spree.rake
197
+ homepage: https://github.com/mejuri-inc/flowcommerce_spree
198
+ licenses:
199
+ - MIT
200
+ metadata: {}
201
+ post_install_message:
202
+ rdoc_options: []
203
+ require_paths:
204
+ - lib
205
+ required_ruby_version: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - "~>"
208
+ - !ruby/object:Gem::Version
209
+ version: 2.3.0
210
+ required_rubygems_version: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ requirements: []
216
+ rubygems_version: 3.0.8
217
+ signing_key:
218
+ specification_version: 4
219
+ summary: Integration of Spree with Flow API
220
+ test_files: []