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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6893ddfb8f021ff6400c0bbe31fc6b2c532886892730a1c9097d172944a8eca8
4
+ data.tar.gz: 9d3a1b190708053a5ad664588abe553617cf07a02ce6fb8f8b2b9d8d17b393a7
5
+ SHA512:
6
+ metadata.gz: 531a87c9a666b3057d16983c3e6168492ac124112a881821891e3bb2174f7e5589785301e023348f3bb06ef2ea105961f20a6a2aaa884e9845e92896973586d7
7
+ data.tar.gz: c84a3cb370744c3313b04cdc513d38d70ea0aaa01e7e09470bdf768f77d41fdb0c4bb9df240bbe4fec58adc4068b96d64fa538a315d73e8a361a1f718ecc6b46
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2020 Aurel Branzeanu
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ <img src="https://i.imgur.com/tov8bTw.png" alt="flowcommerce_spree" style="float:right">
2
+
3
+ # Flow.io < - > Spree adapter
4
+
5
+ All flowcommerce_spree code is located in the ./app and ./lib folders.
6
+
7
+ ## Installation
8
+ - Add the gem to main application's Gemfile:
9
+
10
+ ```
11
+ gem 'flowcommerce_spree', git: 'https://github.com/mejuri-inc/flowcommerce_spree'
12
+ ```
13
+
14
+ - If the main application's Rails version is less than 4.2, add also to main application's Gemfile the `activerecord
15
+ -postgres-json` gem (the mejuri-inc fork allows using a recent Rake version:
16
+
17
+ ```
18
+ gem 'activerecord-postgres-json', git: 'https://github.com/mejuri-inc/activerecord-postgres-json'
19
+ ```
20
+
21
+
22
+ - Run `bundle install`.
23
+
24
+ - Define this additional ENV variables. You will find them in
25
+ [Flow console](https://console.flow.io/org_account_name/organization/integrations):
26
+
27
+ ```
28
+ FLOW_TOKEN='SUPERsecretTOKEN' # API_KEY
29
+ FLOW_ORGANIZATION='spree-app-sandbox'
30
+ FLOW_BASE_COUNTRY='usa'
31
+ ```
32
+
33
+ - The only piece of code that is needed to enable payments with the FlowCommerce engine
34
+
35
+ ```
36
+ # config/application.rb
37
+ config.after_initialize do |app|
38
+ # init Flow payments as an option
39
+ app.config.spree.payment_methods << Spree::Gateway::Flow
40
+ end
41
+ ```
42
+
43
+ - To see and optionally invoke the list of FlowCommerce tasks, run `bundle exec rake flowcommerce_spree:list_tasks
44
+ `. Any task from the list could be invoked, typing at the `Type the task number to be invoked:` prompt the task
45
+ number, or from a terminal prompt, in the main application's root folder, running `bundle exec rake {task_name}`
46
+
47
+ - Run the `flowcommerce_spree:install:migrations` task to copy the DB migrations' file into the main application's
48
+ `db/migrate` folder.
49
+
50
+ - Run `bundle exec rake db:migrate SCOPE=flowcommerce_spree
51
+ ` from a terminal prompt. This will add an `meta` jsonb column to the Spree::CreditCard, Spree::Product,
52
+ Spree::Variant, Spree::Order, Spree::Promotion models' DB tables, if there is not yet such a column defined.
53
+
54
+ - If the main application's Rails version is less than 4.2, add the JSON serializer for the `meta` column to the
55
+ affected models' decorators (Spree::CreditCard, Spree::Product, Spree::Variant, Spree::Order, Spree::Promotion models):
56
+
57
+ `serialize :flow_data, ActiveRecord::Coders::JSON.new(symbolize_keys: true)`
58
+
59
+
60
+
61
+ ## Flow API specific
62
+
63
+ Classes that begin with Flow are responsible for communicating with flow API.
64
+
65
+ ### Flow
66
+
67
+ Helper class that offers low level flow api access and few helper methods.
68
+
69
+ ### FlowcommerceSpree::ExperienceService
70
+
71
+ Responsible for selecting current experience. You have to define available experiences in flow console.
72
+
73
+ ### Flow::Order
74
+
75
+ Maintain and synchronizes Spree::Order with Flow API.
76
+
77
+ ### Flow::Session
78
+
79
+ Every shop user has a session. This class helps in creating and maintaining session with Flow.
80
+
81
+ ## Decorators
82
+
83
+ Decorators are found in ./app/flow/decorators folders and they decorate Spree models with Flow specific methods.
84
+
85
+ All methods are prefixed with ```flow_```.
86
+
87
+ ## Helper lib
88
+
89
+ ### Spree::Flow::Gateway
90
+
91
+ Adapter for Spree, that allows using [Flow.io](https://www.flow.io) as payment gateway. Flow is PCI compliant payment processor.
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rdoc/task'
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'FlowcommerceSpree'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.rdoc')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
20
+ load 'rails/tasks/engine.rake'
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+ task default: :test
data/SPREE_FLOW.md ADDED
@@ -0,0 +1,134 @@
1
+ # Flow, ActiveMerchant and Spree integration
2
+
3
+ Integration of Spree with Flow, how it is done.
4
+
5
+ I plan to be concise as possible, but cover all important topics.
6
+
7
+ ## Instalation
8
+
9
+ Add the following lines to `./config/application.rb` :
10
+
11
+ ```
12
+ config.to_prepare do
13
+ # add all flow libs
14
+ overload = Dir.glob('./app/flow/**/*.rb')
15
+ overload.reverse.each { |c| require(c) }
16
+ end
17
+
18
+ config.after_initialize do |app|
19
+ # init Flow payments as an option
20
+ app.config.spree.payment_methods << Spree::Gateway::Flow
21
+ end
22
+ ```
23
+
24
+ Additional configuration could be adjusted in the gem's initializer. For example, the following file could be created in the main application:
25
+
26
+ ```
27
+ # ./config/initializers/flowcommerce_spree.rb
28
+
29
+ FlowcommerceSpree.configure do |c|
30
+ c.experience_associator = FlowcommerceSpree::ExperienceAssociator
31
+ end
32
+ ```
33
+
34
+ ### Configurable settings
35
+
36
+ 1. experience_associator - this attribute could be assigned, if necessary, a service object to perform some
37
+ additional association actions when upserting a FlowcommerceSpree::Experience model
38
+
39
+ ## Things to take into account
40
+
41
+ ActiveMerchant is not supporting sessions and orders, natively. If one wants
42
+ to maintain sessions and orders in Flow, you have to do it outside the ActiveMerchant
43
+ terminology which focuses around purchases, voids and refunds.
44
+
45
+ Another thing to have in mind is that Spree can't work with ActiveMerchant directly, it has to have
46
+ an adapter. Adapter can be "stupid" and light, and can forward all the "heavy lifting" to ActiveMerchant gem
47
+ but it can also have all the logic localy.
48
+
49
+ In http://guides.spreecommerce.org/developer/payments.html at the bottom of the page Spree authors say
50
+
51
+ "better_spree_paypal_express and spree-adyen are good examples of standalone
52
+ custom gateways. No dependency on spree_gateway or activemerchant required."
53
+
54
+ Reading that we can see this is even considered good approach. For us, this is a possibility
55
+ but we consume ActiveMerchatFlow gem.
56
+
57
+ ## ActiveMerchant gem into more detail
58
+
59
+ https://github.com/flowcommerce/active_merchant
60
+
61
+ Sopporst stanard public ActiveMerchant actions which are
62
+ purchase, authorize, capture, void, store and refund.
63
+
64
+ It depends on following gems
65
+
66
+ * flowcommerce - api calls
67
+ * flow-reference - we use currency validations
68
+
69
+ It is not aware of Spree or any other shopping lib or framework.
70
+
71
+ ### ActiveMerchant::Flow supported actions in detail
72
+
73
+ * purchase - shortcut for authorize and then capture
74
+ * authorize - authorize the cc and funds.
75
+ * capture - capture the funds
76
+ * void - cancel the transaction
77
+ * store - store credit card (gets credit card flow token)
78
+ * refund - refund the funds
79
+
80
+ ## Spree Implementation in more detail
81
+
82
+ Not present as standalone gem, yet. I will do that once we agree on implementation details.
83
+
84
+ From product list to purchase, complete chain v1
85
+
86
+ 1. customer has to prepare data, migrate db and connect to Flow. In general
87
+ * create experiences in Flow console, add tiers, shipping methods, etc.
88
+ * add flow_data (jsonb) fields to this models
89
+ * Spree::Variant - we cache localized product prices
90
+ * Spree::Order - we cache flow order state details, shipping method
91
+ * create and sync product catalog via rake tasks
92
+ 1. now site users can browse prooducts and add them to cart.
93
+ 1. when user comes to shop, FlowSession is created
94
+ 1. once product is in cart
95
+ * spree order is created and linked to Experience that we get from FlowSession
96
+ * it is captured and synced with flow, realtime
97
+ * we do this all the time because we want to have 100% accurate prices.
98
+ Product prices that are shown in cart come directly from Flow API.
99
+ * in checkout, when customer address is added or shipping method defined,
100
+ all is synced with flow order.
101
+ * when order is complete, we trigger flow-cc-authorize or flow-cc-capture directly
102
+ on Spree::Order object instance. This is good because all gateway actions
103
+ are functions of the order object anyway.
104
+ * flow-cc-authorize or flow-cc-capture use ActiveMerchantFlow to execute this actions
105
+ * ActiveMerchantFlow included flow-reference gem
106
+
107
+ ## What can be better
108
+
109
+ We need a way to access the order in Rails. Access it after it is created in
110
+ controller but before it hits the render.
111
+ Current implementation is -> "overload" ApplicationController render
112
+ If we detect @spree_order object or debug flags, we react.
113
+
114
+ * good - elegant solution, all need code is in one file in few lines of code
115
+ * bad - somehow intrusive, we overload render, somw people will not like that.
116
+ * alternatives: gem that allows before_render bethod, call explicitly when needed
117
+
118
+ ## Aditional notes - view and frontend
119
+
120
+ I see many Spree merchant gems carry frontend code, js, coffe, views etc.
121
+ I thing that this is bad practise and that shop frontend has to be 100% customer code.
122
+
123
+ What I did not see but thing is great idea is to have custom light Flow admin present at
124
+
125
+ /admin/flow
126
+
127
+ that will ease the way of working with Flow. Code can be made to be Rails 4 and Rails 5 compatibile.
128
+ Part of that is allready done as can be seen here [Flow admin screenshot](https://i.imgur.com/FXbPrwK.png)
129
+
130
+ By default Flow Admin (on /admin/flow) is anybody that is Spree admin.
131
+
132
+ This way we provide good frontend info, some integration notes in realtime as opposed to running
133
+ rake tests to check for integrity of Flow integration.
134
+
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ CurrentZoneLoader.module_eval do
4
+ extend ActiveSupport::Concern
5
+
6
+ def flow_zone # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
7
+ return unless Spree::Zones::Product.active
8
+ .where("meta -> 'flow_data' ->> 'country' = ?",
9
+ ISO3166::Country[request_iso_code]&.alpha3).exists?
10
+
11
+ request_ip =
12
+ if Rails.env.production?
13
+ request.ip
14
+ else
15
+ Spree::Config[:debug_request_ip_address] || request.ip
16
+ # Germany ip: 85.214.132.117, Sweden ip: 62.20.0.196, Moldova ip: 89.41.76.29
17
+ end
18
+ flow_io_session = FlowcommerceSpree::Session
19
+ .new(ip: request_ip, visitor: visitor_id_for_flow_io)
20
+ # :create method will issue a request to flow.io. The experience, contained in the
21
+ # response, will be available in the session object - flow_io_session.experience
22
+ flow_io_session.create
23
+ zone = Spree::Zones::Product.active.find_by(name: flow_io_session.experience&.key&.titleize)
24
+ session['_f60_session'] = flow_io_session.id if zone
25
+ zone
26
+ end
27
+
28
+ # composes an unique vistor id for FlowcommerceSpree::Session model
29
+ def visitor_id_for_flow_io
30
+ guest_token = cookies.signed[:guest_token]
31
+ uid = if guest_token
32
+ Digest::SHA1.hexdigest(guest_token)
33
+ else
34
+ session_id = session[:session_id]
35
+ session_id ? Digest::SHA1.hexdigest(session_id) : Digest::SHA1.hexdigest(request.ip + request.user_agent)
36
+ end
37
+
38
+ "session-#{uid}"
39
+ end
40
+
41
+ def fetch_product_for_zone(product)
42
+ Rails.cache.fetch(
43
+ "product_zone_#{current_zone.name}_#{product.sku}", expires_in: 1.day,
44
+ race_condition_ttl: 10.seconds, compress: true
45
+ ) do
46
+ Spree::Zones::Product.find_product_for_zone(product, current_zone)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowcommerceSpree
4
+ class WebhooksController < ActionController::Base
5
+ respond_to :json
6
+
7
+ # forward all incoming requests to Flow WebhookService object
8
+ # /flow/event-target endpoint
9
+ def handle_flow_web_hook_event
10
+ webhook_result = WebhookService.process(params[:webhook])
11
+ result = {}
12
+ result[:error] = webhook_result.full_messages.join("\n") if webhook_result.errors.any?
13
+ rescue StandardError => e
14
+ result = { error: e.class.to_s, message: e.message, backtrace: e.backtrace }
15
+ ensure
16
+ response_status = if result[:error]
17
+ logger.info(result)
18
+ :unprocessable_entity
19
+ else
20
+ :ok
21
+ end
22
+ render json: result.except(:backtrace), status: response_status
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowcommerceSpree
4
+ module ApplicationHelper
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Flow (2017)
4
+ # Enable this modifications if you want to display flow localized line item shipment price beside Spree default
5
+ # Example: https://i.imgur.com/7v2ix2G.png
6
+ module Spree
7
+ module Admin
8
+ OrdersHelper.module_eval do
9
+ # admin show line item total price
10
+ def line_item_shipment_price(line_item, quantity)
11
+ price = Spree::Money.new(line_item.price * quantity, currency: line_item.currency).to_s
12
+ price += " (#{@order.flow_line_item_price(line_item, quantity)})" if @order.flow_order
13
+ price.html_safe
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core
5
+ module ControllerHelpers
6
+ # Spree::Core::ControllerHelpers::Order decorator to inject Flow.io Experience into the order, if such an
7
+ # Experience is present in the Order's zone
8
+ module FlowIoOrderHelperDecorator
9
+ private
10
+
11
+ def adjust_zone_and_ip
12
+ update_meta = @current_order.zone_id ? nil : true
13
+ @current_order.zone = current_zone
14
+
15
+ if @current_order.zone&.flow_io_active_experience? && @current_order.flow_io_experience_key.nil?
16
+ @current_order.flow_io_experience_from_zone
17
+ order_flow_io_session_id = @current_order.flow_data['session_id']
18
+ flow_io_session_id = session['_f60_session']
19
+ if order_flow_io_session_id.present? && flow_io_session_id.blank?
20
+ session['_f60_session'] = order_flow_io_session_id
21
+ elsif flow_io_session_id.present?
22
+ @current_order.flow_data['session_id'] = flow_io_session_id
23
+ end
24
+ update_meta = true
25
+ end
26
+
27
+ if @current_order.new_record?
28
+ @current_order.last_ip_address = ip_address
29
+ return @current_order.save
30
+ end
31
+
32
+ attrs_to_update = {}
33
+
34
+ # Update last_ip_address only for a new request_id
35
+ attrs_to_update = { last_ip_address: ip_address } if @request_id != request_id
36
+
37
+ # :meta is a jsonb column costly to update every time, especially with all the flow.io data, that's why
38
+ # here it is updated only if no zone_id there was inside :meta
39
+ attrs_to_update[:meta] = @current_order.meta.to_json if update_meta
40
+
41
+ @current_order.update_columns(attrs_to_update) if attrs_to_update.present?
42
+ attrs_to_update
43
+ end
44
+
45
+ def request_id
46
+ @request_id ||= env['action_dispatch.request_id']
47
+ end
48
+
49
+ ApplicationController.prepend(self) if ApplicationController.included_modules.exclude?(self)
50
+ end
51
+ end
52
+ end
53
+ end