flowcommerce_spree 0.0.3 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +35 -6
  3. data/app/controllers/concerns/current_zone_loader_decorator.rb +11 -17
  4. data/app/controllers/flowcommerce_spree/inventory_controller.rb +23 -0
  5. data/app/controllers/flowcommerce_spree/orders_controller.rb +20 -0
  6. data/app/controllers/flowcommerce_spree/webhooks_controller.rb +16 -18
  7. data/app/controllers/users/sessions_controller_decorator.rb +19 -2
  8. data/app/helpers/spree/core/controller_helpers/flow_io_order_helper_decorator.rb +0 -16
  9. data/app/models/flowcommerce_spree/settings.rb +1 -0
  10. data/app/models/spree/address_decorator.rb +1 -1
  11. data/app/models/spree/calculator/flow_io.rb +24 -12
  12. data/app/models/spree/calculator/shipping/flow_io.rb +5 -2
  13. data/app/models/spree/flow_io_credit_card_decorator.rb +21 -0
  14. data/app/models/spree/flow_io_order_decorator.rb +181 -0
  15. data/app/models/spree/flow_io_product_decorator.rb +5 -0
  16. data/app/models/spree/flow_io_variant_decorator.rb +16 -6
  17. data/app/models/spree/gateway/flow_io.rb +61 -24
  18. data/app/models/spree/{credit_card_decorator.rb → payment_capture_event_decorator.rb} +1 -1
  19. data/app/models/spree/zones/flow_io_product_zone_decorator.rb +4 -0
  20. data/app/overrides/spree/admin/order_sidebar_summary_flow_link.rb +13 -0
  21. data/app/overrides/spree/admin/products/order_price_flow_message.rb +9 -0
  22. data/app/serializers/api/v2/order_serializer_decorator.rb +20 -0
  23. data/app/services/flowcommerce_spree/import_experience_items.rb +1 -21
  24. data/app/services/flowcommerce_spree/import_item.rb +45 -0
  25. data/app/services/flowcommerce_spree/order_sync.rb +50 -222
  26. data/app/services/flowcommerce_spree/order_updater.rb +78 -0
  27. data/app/services/flowcommerce_spree/webhooks/capture_upserted_v2.rb +76 -0
  28. data/app/services/flowcommerce_spree/webhooks/card_authorization_upserted_v2.rb +66 -0
  29. data/app/services/flowcommerce_spree/webhooks/experience_upserted_v2.rb +25 -0
  30. data/app/services/flowcommerce_spree/webhooks/fraud_status_changed.rb +35 -0
  31. data/app/services/flowcommerce_spree/webhooks/local_item_upserted.rb +40 -0
  32. data/app/views/spree/admin/payments/source_views/_flow_io_gateway.html.erb +21 -0
  33. data/app/workers/flowcommerce_spree/import_item_worker.rb +24 -0
  34. data/config/routes.rb +3 -1
  35. data/db/migrate/20201021755957_add_meta_to_spree_tables.rb +6 -4
  36. data/lib/flow/simple_gateway.rb +0 -36
  37. data/lib/flowcommerce_spree.rb +6 -2
  38. data/lib/flowcommerce_spree/engine.rb +6 -1
  39. data/lib/flowcommerce_spree/experience_service.rb +1 -27
  40. data/lib/flowcommerce_spree/logging_http_client.rb +29 -13
  41. data/lib/flowcommerce_spree/session.rb +5 -25
  42. data/lib/flowcommerce_spree/version.rb +1 -1
  43. data/lib/tasks/flowcommerce_spree.rake +4 -1
  44. metadata +77 -28
  45. data/app/mailers/spree/spree_order_mailer_decorator.rb +0 -24
  46. data/app/models/spree/line_item_decorator.rb +0 -15
  47. data/app/models/spree/order_decorator.rb +0 -244
  48. data/app/views/spree/order_mailer/confirm_email.html.erb +0 -86
  49. data/app/views/spree/order_mailer/confirm_email.text.erb +0 -38
  50. data/lib/flow/error.rb +0 -73
  51. data/lib/flow/pay_pal.rb +0 -25
  52. data/lib/flowcommerce_spree/webhook_service.rb +0 -184
  53. data/lib/simple_csv_writer.rb +0 -44
data/lib/flow/pay_pal.rb DELETED
@@ -1,25 +0,0 @@
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
@@ -1,184 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FlowcommerceSpree
4
- # communicates with flow api, responds to webhook events
5
- class WebhookService
6
- attr_accessor :errors
7
- alias full_messages errors
8
-
9
- def self.process(data, opts = {})
10
- new(data, opts).process
11
- end
12
-
13
- def initialize(data, opts = {})
14
- @data = data
15
- @opts = opts
16
- @errors = []
17
- end
18
-
19
- def process
20
- discriminator = @data['discriminator']
21
- hook_method = "hook_#{discriminator}"
22
- # If hook processing method registered an error, a self.object of WebhookService with this error will be
23
- # returned, else an ActiveRecord object will be returned
24
- return __send__(hook_method) if respond_to?(hook_method, true)
25
-
26
- errors << { message: "No hook for #{discriminator}" }
27
- self
28
- end
29
-
30
- private
31
-
32
- def hook_capture_upserted_v2
33
- capture = @data['capture']
34
- order_number = capture.dig('authorization', 'order', 'number')
35
- if (order = Spree::Order.find_by(number: order_number))
36
- order.flow_data['captures'] ||= []
37
- order_captures = order.flow_data['captures']
38
- order_captures.delete_if do |c|
39
- c['id'] == capture['id']
40
- end
41
- order_captures << capture
42
-
43
- order.update_column(:meta, order.meta.to_json)
44
- order
45
- else
46
- errors << { message: "Order #{order_number} not found" }
47
- self
48
- end
49
- end
50
-
51
- def hook_experience_upserted_v2
52
- experience = @data['experience']
53
- Spree::Zones::Product.find_or_initialize_by(name: experience['key'].titleize).store_flow_io_data(experience)
54
- end
55
-
56
- def hook_fraud_status_changed
57
- if (order_number = @data.dig('order', 'number'))
58
- if @data['status'] == 'declined'
59
- if (order = Spree::Order.find_by(number: order_number))
60
- order.update_columns(fraudulent: true)
61
- order.cancel!
62
- return order
63
- else
64
- errors << { message: "Order #{order_number} not found" }
65
- end
66
- end
67
- else
68
- errors << { message: 'Order number param missing' }
69
- end
70
-
71
- self
72
- end
73
-
74
- def hook_local_item_upserted
75
- errors << { message: 'Local item param missing' } && (return self) unless (local_item = @data['local_item'])
76
-
77
- errors << { message: 'SKU param missing' } && (return self) unless (flow_sku = local_item.dig('item', 'number'))
78
-
79
- if (variant = Spree::Variant.find_by(sku: flow_sku))
80
- variant.add_flow_io_experience_data(
81
- local_item.dig('experience', 'key'),
82
- 'prices' => [local_item.dig('pricing', 'price')], 'status' => local_item['status']
83
- )
84
-
85
- variant.update_column(:meta, variant.meta.to_json)
86
- return variant
87
- else
88
- errors << { message: "Variant with sku [#{flow_sku}] not found!" }
89
- end
90
-
91
- self
92
- end
93
-
94
- def hook_order_placed_v2
95
- order_placed = @data['order_placed']
96
- flow_order = order_placed['order']
97
- flow_allocation = order_placed['allocation']
98
-
99
- errors << { message: 'Order number param missing' } && (return self) unless (order_number = flow_order['number'])
100
-
101
- if (order = Spree::Order.find_by(number: order_number))
102
- order.flow_data['order'] = flow_order.to_hash
103
- order.flow_data['allocations'] = flow_allocation.to_hash
104
- order_flow_data = order.flow_data['order']
105
- attrs_to_update = { meta: order.meta.to_json }
106
- flow_data_submitted = order_flow_data['submitted_at'].present?
107
- if flow_data_submitted && !order.complete?
108
- if order_flow_data['payments'].present? && (order_flow_data.dig('balance', 'amount')&.to_i == 0)
109
- attrs_to_update[:state] = 'complete'
110
- attrs_to_update[:payment_state] = 'paid'
111
- attrs_to_update[:completed_at] = Time.zone.now.utc
112
- attrs_to_update[:email] = order.flow_customer_email
113
- else
114
- attrs_to_update[:state] = 'confirmed'
115
- end
116
- end
117
-
118
- attrs_to_update.merge!(order.prepare_flow_addresses) if order.complete? || attrs_to_update[:state] == 'complete'
119
-
120
- if flow_data_submitted
121
- order.create_proposed_shipments
122
- order.shipment.update_amounts
123
- order.line_items.each(&:store_ets)
124
- end
125
-
126
- order.update_columns(attrs_to_update)
127
-
128
- # TODO: To be refactored once we have the capture_upserted_v2 webhook configured
129
- if flow_data_submitted
130
- order.create_tax_charge!
131
- order.finalize!
132
- order.update_totals
133
- order.save
134
- end
135
-
136
- return order
137
- else
138
- errors << { message: "Order #{order_number} not found" }
139
- end
140
-
141
- self
142
- end
143
-
144
- def hook_order_upserted_v2
145
- errors << { message: 'Order param missing' } && (return self) unless (flow_order = @data['order'])
146
-
147
- errors << { message: 'Order number param missing' } && (return self) unless (order_number = flow_order['number'])
148
-
149
- if (order = Spree::Order.find_by(number: order_number))
150
- order.flow_data['order'] = flow_order.to_hash
151
- order_flow_data = order.flow_data['order']
152
- attrs_to_update = { meta: order.meta.to_json }
153
- flow_data_submitted = order_flow_data['submitted_at'].present?
154
- if flow_data_submitted && !order.complete?
155
- if order_flow_data['payments'].present? && (order_flow_data.dig('balance', 'amount')&.to_i == 0)
156
- attrs_to_update[:state] = 'complete'
157
- attrs_to_update[:payment_state] = 'paid'
158
- attrs_to_update[:completed_at] = Time.zone.now.utc
159
- attrs_to_update[:email] = order.flow_customer_email
160
- else
161
- attrs_to_update[:state] = 'confirmed'
162
- end
163
- end
164
-
165
- attrs_to_update.merge!(order.prepare_flow_addresses) if order.complete? || attrs_to_update[:state] == 'complete'
166
-
167
- order.update_columns(attrs_to_update)
168
- order.create_tax_charge! if flow_data_submitted
169
- return order
170
- else
171
- errors << { message: "Order #{order_number} not found" }
172
- end
173
-
174
- self
175
- end
176
-
177
- # send en email when order is refunded
178
- def hook_refund_upserted_v2
179
- Spree::OrderMailer.refund_complete_email(@data).deliver
180
-
181
- 'Email delivered'
182
- end
183
- end
184
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # simple class to build scv files
4
-
5
- # csv = CsvWriter.new
6
- # csv.add a: 1, b: 'a', c: '"a'
7
- # csv.add a: ',', b: 'foo, bar'
8
- # csv.to_s
9
-
10
- class SimpleCsvWriter
11
- def initialize(delimiter: nil)
12
- @data = []
13
- @delimiter = delimiter || "\t"
14
- end
15
-
16
- # add hash or list
17
- def add(data)
18
- list = if data.class == Hash
19
- @keys ||= data.keys
20
- @keys.map { |key| data[key] }
21
- else
22
- data
23
- end
24
-
25
- @data.push list.map { |el| fmt(el) }.join(@delimiter)
26
- end
27
-
28
- def to_s
29
- if @keys
30
- @keys.map(&:to_s).join(@delimiter) + "\n" +
31
- @data.join($RS)
32
- else
33
- @data.join($RS)
34
- end
35
- end
36
-
37
- private
38
-
39
- def fmt(item)
40
- item = item.to_s.gsub($RS, '\\n').gsub('"', '""')
41
-
42
- item.include?(@delimiter) || item.include?('\\') ? "\"#{item}\"" : item
43
- end
44
- end