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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +91 -0
- data/Rakefile +33 -0
- data/SPREE_FLOW.md +134 -0
- data/app/assets/javascripts/flowcommerce_spree/application.js +13 -0
- data/app/assets/stylesheets/flowcommerce_spree/application.css +15 -0
- data/app/controllers/concerns/current_zone_loader_decorator.rb +49 -0
- data/app/controllers/flowcommerce_spree/webhooks_controller.rb +25 -0
- data/app/helpers/flowcommerce_spree/application_helper.rb +6 -0
- data/app/helpers/spree/admin/orders_helper_decorator.rb +17 -0
- data/app/helpers/spree/core/controller_helpers/flow_io_order_helper_decorator.rb +53 -0
- data/app/mailers/spree/spree_order_mailer_decorator.rb +24 -0
- data/app/models/flowcommerce_spree/settings.rb +8 -0
- data/app/models/spree/credit_card_decorator.rb +9 -0
- data/app/models/spree/flow_io_product_decorator.rb +91 -0
- data/app/models/spree/flow_io_variant_decorator.rb +205 -0
- data/app/models/spree/gateway/spree_flow_gateway.rb +116 -0
- data/app/models/spree/line_item_decorator.rb +15 -0
- data/app/models/spree/order_decorator.rb +179 -0
- data/app/models/spree/promotion_decorator.rb +10 -0
- data/app/models/spree/promotion_handler/coupon_decorator.rb +30 -0
- data/app/models/spree/spree_user_decorator.rb +15 -0
- data/app/models/spree/taxon_decorator.rb +37 -0
- data/app/models/spree/zone_decorator.rb +7 -0
- data/app/models/spree/zones/flow_io_product_zone_decorator.rb +55 -0
- data/app/services/flowcommerce_spree/import_experience_items.rb +76 -0
- data/app/services/flowcommerce_spree/import_experiences.rb +37 -0
- data/app/services/flowcommerce_spree/order_sync.rb +231 -0
- data/app/views/layouts/flowcommerce_spree/application.html.erb +14 -0
- data/app/views/spree/admin/payments/index.html.erb +28 -0
- data/app/views/spree/admin/promotions/edit.html.erb +57 -0
- data/app/views/spree/admin/shared/_order_summary.html.erb +44 -0
- data/app/views/spree/admin/shared/_order_summary_flow.html.erb +13 -0
- data/app/views/spree/order_mailer/confirm_email.html.erb +86 -0
- data/app/views/spree/order_mailer/confirm_email.text.erb +38 -0
- data/config/initializers/flowcommerce_spree.rb +7 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20201021160159_add_type_and_meta_to_spree_zone.rb +23 -0
- data/db/migrate/20201021755957_add_meta_to_spree_tables.rb +17 -0
- data/db/migrate/20201022173210_add_zone_type_to_spree_zone_members.rb +24 -0
- data/db/migrate/20201022174252_add_kind_to_zone.rb +22 -0
- data/lib/flow/error.rb +73 -0
- data/lib/flow/pay_pal.rb +25 -0
- data/lib/flow/simple_gateway.rb +115 -0
- data/lib/flowcommerce_spree.rb +31 -0
- data/lib/flowcommerce_spree/api.rb +48 -0
- data/lib/flowcommerce_spree/engine.rb +27 -0
- data/lib/flowcommerce_spree/experience_service.rb +65 -0
- data/lib/flowcommerce_spree/logging_http_client.rb +43 -0
- data/lib/flowcommerce_spree/logging_http_handler.rb +15 -0
- data/lib/flowcommerce_spree/refresher.rb +81 -0
- data/lib/flowcommerce_spree/session.rb +71 -0
- data/lib/flowcommerce_spree/version.rb +5 -0
- data/lib/flowcommerce_spree/webhook_service.rb +98 -0
- data/lib/simple_csv_writer.rb +44 -0
- data/lib/tasks/flowcommerce_spree.rake +289 -0
- metadata +220 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
<%= Spree.t('order_mailer.confirm_email.dear_customer') %>
|
2
|
+
|
3
|
+
<%= Spree.t('order_mailer.confirm_email.instructions') %>
|
4
|
+
|
5
|
+
============================================================
|
6
|
+
<%= Spree.t('order_mailer.confirm_email.order_summary') %>
|
7
|
+
============================================================
|
8
|
+
<% @order.line_items.each do |item| %>
|
9
|
+
<%= item.variant.sku %> <%= raw(item.variant.product.name) %> <%= raw(item.variant.options_text) -%> (<%=item.quantity%>) @ <%= item.single_money %> = <%= @order.flow_line_item_price(line_item, :with_quantity) %>
|
10
|
+
<% end %>
|
11
|
+
============================================================
|
12
|
+
<%= Spree.t('order_mailer.confirm_email.subtotal', :subtotal => @order.display_item_total) %>
|
13
|
+
<% if @order.line_item_adjustments.exists? %>
|
14
|
+
<% if @order.all_adjustments.promotion.eligible.exists? %>
|
15
|
+
<% @order.all_adjustments.promotion.eligible.group_by(&:label).each do |label, adjustments| %>
|
16
|
+
<%= Spree.t(:promotion) %>: <%= label %> <%= Spree::Money.new(adjustments.sum(&:amount), currency: @order.currency) %>
|
17
|
+
<% end %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<% @order.shipments.group_by { |s| s.selected_shipping_rate.try(:name) }.each do |name, shipments| %>
|
22
|
+
<%= Spree.t(:shipping) %>: <%= name %> <%= Spree::Money.new(shipments.sum(&:discounted_cost), currency: @order.currency) %>
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
<% if @order.all_adjustments.eligible.tax.exists? %>
|
26
|
+
<% @order.all_adjustments.eligible.tax.group_by(&:label).each do |label, adjustments| %>
|
27
|
+
<%= Spree.t(:tax) %>: <%= label %> <%= Spree::Money.new(adjustments.sum(&:amount), currency: @order.currency) %>
|
28
|
+
<% end %>
|
29
|
+
<% end %>
|
30
|
+
|
31
|
+
<% @order.adjustments.eligible.each do |adjustment| %>
|
32
|
+
<% next if (adjustment.source_type == 'Spree::TaxRate') and (adjustment.amount == 0) %>
|
33
|
+
<%= adjustment.label %> <%= adjustment.display_amount %>
|
34
|
+
<% end %>
|
35
|
+
============================================================
|
36
|
+
<%= Spree.t('order_mailer.confirm_email.total', :total => @order.display_total) %>
|
37
|
+
|
38
|
+
<%= Spree.t('order_mailer.confirm_email.thanks') %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class AddTypeAndMetaToSpreeZone < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
add_column :spree_zones, :klass, :text unless column_exists?(:spree_zones, :klass)
|
4
|
+
add_column :spree_zones, :status, :text unless column_exists?(:spree_zones, :status)
|
5
|
+
add_column :spree_zones, :meta, :jsonb, default: '{}' unless column_exists?(:spree_zones, :meta)
|
6
|
+
|
7
|
+
add_index :spree_zones, :meta, using: :gin unless index_exists?(:spree_zones, :meta)
|
8
|
+
add_index :spree_zones, %i[id klass] unless index_exists?(:spree_zones, %i[id klass])
|
9
|
+
add_index :spree_zones, %i[klass name], unique: true unless index_exists?(:spree_zones, %i[klass name])
|
10
|
+
add_index :spree_zones, :status unless index_exists?(:spree_zones, :status)
|
11
|
+
end
|
12
|
+
|
13
|
+
def down
|
14
|
+
remove_index :spree_zones, :status if index_exists?(:spree_zones, :status)
|
15
|
+
remove_index :spree_zones, %i[klass name] if index_exists?(:spree_zones, %i[klass name])
|
16
|
+
remove_index :spree_zones, %i[id klass] if index_exists?(:spree_zones, %i[id klass])
|
17
|
+
remove_index :spree_zones, :meta if index_exists?(:spree_zones, :meta)
|
18
|
+
|
19
|
+
remove_column :spree_zones, :meta if column_exists?(:spree_zones, :meta)
|
20
|
+
remove_column :spree_zones, :status if column_exists?(:spree_zones, :status)
|
21
|
+
remove_column :spree_zones, :klass if column_exists?(:spree_zones, :klass)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class AddMetaToSpreeTables < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
add_column :spree_products, :meta, :jsonb, default: '{}' unless column_exists?(:spree_products, :meta)
|
4
|
+
add_column :spree_variants, :meta, :jsonb, default: '{}' unless column_exists?(:spree_variants, :meta)
|
5
|
+
add_column :spree_orders, :meta, :jsonb, default: '{}' unless column_exists?(:spree_orders, :meta)
|
6
|
+
add_column :spree_promotions, :meta, :jsonb, default: '{}' unless column_exists?(:spree_promotions, :meta)
|
7
|
+
add_column :spree_credit_cards, :meta, :jsonb, default: '{}' unless column_exists?(:spree_credit_cards, :meta)
|
8
|
+
end
|
9
|
+
|
10
|
+
def down
|
11
|
+
remove_column :spree_products, :meta if column_exists?(:spree_products, :meta)
|
12
|
+
remove_column :spree_variants, :meta if column_exists?(:spree_variants, :meta)
|
13
|
+
remove_column :spree_orders, :meta if column_exists?(:spree_orders, :meta)
|
14
|
+
remove_column :spree_promotions, :meta if column_exists?(:spree_promotions, :meta)
|
15
|
+
remove_column :spree_credit_cards, :meta if column_exists?(:spree_credit_cards, :meta)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class AddZoneTypeToSpreeZoneMembers < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
add_column :spree_zone_members, :zone_type, :text unless column_exists?(:spree_zone_members, :zone_type)
|
4
|
+
|
5
|
+
unless index_exists?(:spree_zone_members, %i[zone_id zone_type])
|
6
|
+
add_index :spree_zone_members, %i[zone_id zone_type],
|
7
|
+
name: "index_spree_zone_members_on_zone_id_and_zone_type", using: :btree
|
8
|
+
end
|
9
|
+
|
10
|
+
if index_exists?(:spree_zone_members, name: "index_spree_zone_members_on_zone_id")
|
11
|
+
remove_index :spree_zone_members, name: "index_spree_zone_members_on_zone_id"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def down
|
16
|
+
add_index :spree_zone_members, :zone_id unless index_exists?(:spree_zone_members, :zone_id)
|
17
|
+
|
18
|
+
if index_exists?(:spree_zone_members, %i[zone_id zone_type])
|
19
|
+
remove_index :spree_zone_members, name: "index_spree_zone_members_on_zone_id_and_zone_type"
|
20
|
+
end
|
21
|
+
|
22
|
+
remove_column :spree_zone_members, :zone_type if column_exists?(:spree_zone_members, :zone_type)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# This is from Spree 3.0
|
2
|
+
# https://github.com/spree/spree/commit/f9509a511def39de9d98199ddbf35f35c8580ca4#diff-984b308f2dc59ffb6e47183ac28b9895cfaa58bb26fb6f6e56a6afbe888fdece
|
3
|
+
class AddKindToZone < ActiveRecord::Migration
|
4
|
+
def up
|
5
|
+
unless column_exists?(:spree_zones, :kind)
|
6
|
+
add_column :spree_zones, :kind, :string
|
7
|
+
add_index :spree_zones, :kind
|
8
|
+
|
9
|
+
Spree::Zone.find_each do |zone|
|
10
|
+
last_type = zone.members.where.not(zoneable_type: nil).pluck(:zoneable_type).last
|
11
|
+
zone.update_column :kind, last_type.demodulize.underscore if last_type
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index :spree_zones, :kind unless index_exists?(:spree_zones, :kind)
|
16
|
+
end
|
17
|
+
|
18
|
+
def down
|
19
|
+
remove_index :spree_zones, :kind if index_exists?(:spree_zones, :kind)
|
20
|
+
remove_column :spree_zones, :kind if column_exists?(:spree_zones, :kind)
|
21
|
+
end
|
22
|
+
end
|
data/lib/flow/error.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Flow (2017)
|
4
|
+
# api error logger and formater
|
5
|
+
|
6
|
+
require 'digest/sha1'
|
7
|
+
|
8
|
+
class Flow::Error < StandardError
|
9
|
+
# logs error to file for easy discovery and fix
|
10
|
+
def self.log(exception, request)
|
11
|
+
history = exception.backtrace.reject { |el| el.index('/gems/') }.map { |el| el.sub(Rails.root.to_s, '') }.join($/)
|
12
|
+
|
13
|
+
msg = "#{exception.class} in #{request.url}"
|
14
|
+
data = [msg, exception.message, history].join("\n\n")
|
15
|
+
key = Digest::SHA1.hexdigest(exception.backtrace.first.split(' ').first)
|
16
|
+
|
17
|
+
folder = Rails.root.join('log/exceptions').to_s
|
18
|
+
Dir.mkdir(folder) unless Dir.exist?(folder)
|
19
|
+
|
20
|
+
folder += "/#{exception.class.to_s.tableize.gsub('/', '-')}"
|
21
|
+
Dir.mkdir(folder) unless Dir.exist?(folder)
|
22
|
+
|
23
|
+
"#{folder}/#{key}.txt".tap do |path|
|
24
|
+
File.write(path, data)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.format_message(exception)
|
29
|
+
# format Flow errors in a special way
|
30
|
+
# Io::Flow::V0::HttpClient::ServerError - 422 Unprocessable Entity:
|
31
|
+
# {"code":"invalid_number","messages":["Card number is not valid"]}
|
32
|
+
# hash['code'] = 'invalid_number'
|
33
|
+
# hash['message'] = 'Card number is not valid'
|
34
|
+
# hash['title'] = '422 Unprocessable Entity'
|
35
|
+
# hash['klass'] = 'Io::Flow::V0::HttpClient::ServerError'
|
36
|
+
if exception.class == Io::Flow::V0::HttpClient::ServerError
|
37
|
+
parts = exception.message.split(': ', 2)
|
38
|
+
hash = Oj.load(parts[1])
|
39
|
+
|
40
|
+
hash[:message] = hash['messages'].join(', ')
|
41
|
+
hash[:title] = parts[0]
|
42
|
+
hash[:klass] = exception.class
|
43
|
+
hash[:code] = hash['code']
|
44
|
+
else
|
45
|
+
msg = exception.message.is_a?(Array) ? exception.message.join(' - ') : exception.message
|
46
|
+
|
47
|
+
hash = {}
|
48
|
+
hash[:message] = msg
|
49
|
+
hash[:title] = '-'
|
50
|
+
hash[:klass] = exception.class
|
51
|
+
hash[:code] = '-'
|
52
|
+
end
|
53
|
+
|
54
|
+
hash
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.format_order_message(order)
|
58
|
+
message = if order['messages']
|
59
|
+
msg = order['messages'].join(', ')
|
60
|
+
msg += " (#{Spree::Variant.where(id: order['numbers']).map(&:name).join(', ')})" if order['numbers']
|
61
|
+
msg
|
62
|
+
else
|
63
|
+
'Order not properly localized (sync issue)'
|
64
|
+
end
|
65
|
+
|
66
|
+
# sub_info = 'Flow.io'
|
67
|
+
# sub_info += ' - %s' % flow_experience.key[0, 15] if flow_experience
|
68
|
+
|
69
|
+
# '%s (%s)' % [message, sub_info]
|
70
|
+
|
71
|
+
message
|
72
|
+
end
|
73
|
+
end
|
data/lib/flow/pay_pal.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Flow.io (2017)
|
4
|
+
# communicates with flow api to synchronize Spree order with PayPal
|
5
|
+
|
6
|
+
module Flow::PayPal
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def get_id(order)
|
10
|
+
raise 'PayPal only supported while using flow' unless order.flow_order
|
11
|
+
|
12
|
+
# get PayPal ID using Flow api
|
13
|
+
body = {
|
14
|
+
# discriminator: 'merchant_of_record_payment_form',
|
15
|
+
method: 'paypal',
|
16
|
+
order_number: order.number,
|
17
|
+
amount: order.flow_order.total.amount,
|
18
|
+
currency: order.flow_order.total.currency
|
19
|
+
}
|
20
|
+
|
21
|
+
# FlowcommerceSpree::Api.run :post, '/:organization/payments', {}, body
|
22
|
+
form = ::Io::Flow::V0::Models::MerchantOfRecordPaymentForm.new body
|
23
|
+
FlowcommerceSpree.client.payments.post FlowcommerceSpree::ORGANIZATION, form
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Flow.io (2017)
|
4
|
+
# communicates with Flow payments API, easy access to session
|
5
|
+
# to basic shop frontend and backend needs
|
6
|
+
module Flow
|
7
|
+
class SimpleGateway
|
8
|
+
cattr_accessor :clear_zero_amount_payments
|
9
|
+
|
10
|
+
def initialize(order)
|
11
|
+
@order = order
|
12
|
+
end
|
13
|
+
|
14
|
+
# authorises credit card and prepares for capture
|
15
|
+
def cc_authorization
|
16
|
+
response = FlowcommerceSpree.client.authorizations.post(FlowcommerceSpree::ORGANIZATION, build_authorization_form)
|
17
|
+
status_message = response.result.status.value
|
18
|
+
status = status_message == ::Io::Flow::V0::Models::AuthorizationStatus.authorized.value
|
19
|
+
|
20
|
+
store = { key: response.key,
|
21
|
+
amount: response.amount,
|
22
|
+
currency: response.currency,
|
23
|
+
authorization_id: response.id }
|
24
|
+
|
25
|
+
@order.flow_data['authorization'] = store
|
26
|
+
@order.update_column(:meta, @order.meta.to_json)
|
27
|
+
|
28
|
+
if self.class.clear_zero_amount_payments
|
29
|
+
@order.payments.where(amount: 0, state: %w[invalid processing pending]).map(&:destroy)
|
30
|
+
end
|
31
|
+
|
32
|
+
ActiveMerchant::Billing::Response.new(status, status_message, { response: response }, authorization: store)
|
33
|
+
rescue Io::Flow::V0::HttpClient::ServerError => e
|
34
|
+
error_response(e)
|
35
|
+
end
|
36
|
+
|
37
|
+
# capture authorised funds
|
38
|
+
def cc_capture
|
39
|
+
# GET /:organization/authorizations, order_number: abc
|
40
|
+
data = @order.flow_data['authorization']
|
41
|
+
|
42
|
+
raise ArgumentError, 'No Authorization data, please authorize first' unless data
|
43
|
+
|
44
|
+
capture_form = ::Io::Flow::V0::Models::CaptureForm.new(data)
|
45
|
+
response = FlowcommerceSpree.client.captures.post(FlowcommerceSpree::ORGANIZATION, capture_form)
|
46
|
+
|
47
|
+
return ActiveMerchant::Billing::Response.new false, 'error', response: response unless response.id
|
48
|
+
|
49
|
+
@order.update_column :flow_data, @order.flow_data.merge('capture': response.to_hash)
|
50
|
+
@order.flow_finalize!
|
51
|
+
|
52
|
+
ActiveMerchant::Billing::Response.new true, 'success', response: response
|
53
|
+
rescue StandardError => e
|
54
|
+
error_response(e)
|
55
|
+
end
|
56
|
+
|
57
|
+
def cc_refund
|
58
|
+
raise ArgumentError, 'capture info is not available' unless @order.flow_data['capture']
|
59
|
+
|
60
|
+
# we allways have capture ID, so we use it
|
61
|
+
refund_data = { capture_id: @order.flow_data['capture']['id'] }
|
62
|
+
refund_form = ::Io::Flow::V0::Models::RefundForm.new(refund_data)
|
63
|
+
response = FlowcommerceSpree.client.refunds.post(FlowcommerceSpree::ORGANIZATION, refund_form)
|
64
|
+
|
65
|
+
return ActiveMerchant::Billing::Response.new false, 'error', response: response unless response.id
|
66
|
+
|
67
|
+
@order.update_column :flow_data, @order.flow_data.merge('refund': response.to_hash)
|
68
|
+
ActiveMerchant::Billing::Response.new true, 'success', response: response
|
69
|
+
rescue StandardError => e
|
70
|
+
error_response(e)
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
# if order is not in flow, we use local Spree settings
|
76
|
+
def in_flow?
|
77
|
+
@order.flow_order ? true : false
|
78
|
+
end
|
79
|
+
|
80
|
+
def build_authorization_form
|
81
|
+
if in_flow?
|
82
|
+
# we have order id so we allways use MerchantOfRecordAuthorizationForm
|
83
|
+
::Io::Flow::V0::Models::MerchantOfRecordAuthorizationForm.new('order_number': @order.flow_number,
|
84
|
+
'currency': @order.flow_order.total.currency,
|
85
|
+
'amount': @order.flow_order.total.amount,
|
86
|
+
'token': cc_get_token)
|
87
|
+
else
|
88
|
+
# when not using Flow, we fall back to Spree default
|
89
|
+
::Io::Flow::V0::Models::DirectAuthorizationForm.new('currency': @order.currency,
|
90
|
+
'amount': @order.total,
|
91
|
+
'token': cc_get_token)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# gets credit card token
|
96
|
+
def cc_get_token
|
97
|
+
cards = @order.credit_cards.select(&:gateway_customer_profile_id)
|
98
|
+
raise StandardError, 'Credit card with token not found' unless cards.first
|
99
|
+
|
100
|
+
cards.first.gateway_customer_profile_id
|
101
|
+
end
|
102
|
+
|
103
|
+
# we want to return errors in standardized format
|
104
|
+
def error_response(exception_object)
|
105
|
+
message = if exception_object.respond_to?(:body) && exception_object.body.length > 0
|
106
|
+
description = Oj.load(exception_object.body)['messages'].to_sentence
|
107
|
+
"#{exception_object.details}: #{description} (#{exception_object.code})"
|
108
|
+
else
|
109
|
+
exception_object.message
|
110
|
+
end
|
111
|
+
|
112
|
+
ActiveMerchant::Billing::Response.new(false, message, exception: exception_object)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'flowcommerce'
|
4
|
+
require 'flowcommerce_spree/api'
|
5
|
+
require 'flowcommerce_spree/refresher'
|
6
|
+
require 'flowcommerce_spree/engine'
|
7
|
+
require 'flowcommerce_spree/logging_http_client'
|
8
|
+
require 'flowcommerce_spree/logging_http_handler'
|
9
|
+
require 'flowcommerce_spree/webhook_service'
|
10
|
+
require 'flowcommerce_spree/session'
|
11
|
+
require 'flow/simple_gateway'
|
12
|
+
|
13
|
+
module FlowcommerceSpree
|
14
|
+
def self.client(logger: FlowcommerceSpree.logger, **opts)
|
15
|
+
FlowCommerce.instance(http_handler: LoggingHttpHandler.new(logger: logger), **opts)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.configure
|
19
|
+
yield self if block_given?
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.logger
|
23
|
+
logger = ActiveSupport::Logger.new(STDOUT, 3, 10_485_760)
|
24
|
+
|
25
|
+
# Broadcast the log into the file besides STDOUT, if `log` folder exists
|
26
|
+
if Dir.exist?('log')
|
27
|
+
logger.extend(ActiveSupport::Logger.broadcast(ActiveSupport::Logger.new('log/flowcommerce_spree.log')))
|
28
|
+
end
|
29
|
+
logger
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# module for communication and customization based on Flow API
|
4
|
+
# for now all in same class
|
5
|
+
module FlowcommerceSpree
|
6
|
+
module Api
|
7
|
+
extend self
|
8
|
+
|
9
|
+
# builds curl command and gets remote data
|
10
|
+
def run(action, path, params = {}, body = nil)
|
11
|
+
body ||= params.delete(:BODY)
|
12
|
+
|
13
|
+
remote_params = URI.encode_www_form params
|
14
|
+
remote_path = debug_path = path.sub('%o', ORGANIZATION).sub(':organization', ORGANIZATION)
|
15
|
+
remote_path += "?#{remote_params}" unless remote_params.blank?
|
16
|
+
|
17
|
+
curl = ['curl -s']
|
18
|
+
curl.push "-X #{action.to_s.upcase}"
|
19
|
+
curl.push "-u #{API_KEY}:"
|
20
|
+
|
21
|
+
if body
|
22
|
+
body = body.to_json unless body.is_a?(Array)
|
23
|
+
curl.push '-H "Content-Type: application/json"'
|
24
|
+
curl.push "-d '#{body.gsub(%['], %['"'"'])}'" if body
|
25
|
+
end
|
26
|
+
|
27
|
+
curl.push "\"https://api.flow.io#{remote_path}\""
|
28
|
+
command = curl.join(' ')
|
29
|
+
|
30
|
+
puts command if defined?(Rails::Console)
|
31
|
+
|
32
|
+
dir = Rails.root.join('log/api')
|
33
|
+
Dir.mkdir(dir) unless Dir.exist?(dir)
|
34
|
+
debug_file = "#{dir}/#{debug_path.gsub(/[^\w]+/, '_')}.bash"
|
35
|
+
File.write debug_file, command + "\n"
|
36
|
+
|
37
|
+
JSON.load `#{command}`
|
38
|
+
end
|
39
|
+
|
40
|
+
def logger
|
41
|
+
@logger ||= Logger.new('./log/flow.log') # or nil for no logging
|
42
|
+
end
|
43
|
+
|
44
|
+
def format_default_price(amount)
|
45
|
+
format('$%<price>.2f', amount)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|