spree_channable 0.0.18.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +24 -0
  5. data/.travis.yml +35 -0
  6. data/Appraisals +27 -0
  7. data/Gemfile +17 -0
  8. data/LICENSE +29 -0
  9. data/README.md +56 -0
  10. data/Rakefile +21 -0
  11. data/app/assets/javascripts/spree/backend/spree_channable.js +2 -0
  12. data/app/assets/javascripts/spree/frontend/spree_channable.js +2 -0
  13. data/app/assets/stylesheets/spree/backend/spree_channable.css +4 -0
  14. data/app/assets/stylesheets/spree/frontend/spree_channable.css +4 -0
  15. data/app/controllers/spree/admin/channable_settings_controller.rb +14 -0
  16. data/app/controllers/spree/api/v1/channable_controller.rb +21 -0
  17. data/app/jobs/application_job.rb +7 -0
  18. data/app/jobs/spree_channable/order_import_job.rb +37 -0
  19. data/app/jobs/spree_channable/return_import_job.rb +36 -0
  20. data/app/models/channable_setting.rb +10 -0
  21. data/app/models/spree/order_decorator.rb +127 -0
  22. data/app/models/spree/product_decorator.rb +118 -0
  23. data/app/models/spree/reimbursement_decorator.rb +39 -0
  24. data/app/models/spree/shipment_decorator.rb +28 -0
  25. data/app/models/spree/shipment_handler_decorator.rb +11 -0
  26. data/app/models/spree/variant_decorator.rb +78 -0
  27. data/app/overrides/add_settings_to_admin_configurator.rb +32 -0
  28. data/app/overrides/order_index.rb +13 -0
  29. data/app/views/spree/admin/channable_settings/_form.html.erb +105 -0
  30. data/app/views/spree/admin/channable_settings/edit.html.erb +1 -0
  31. data/app/views/spree/admin/channable_settings/new.html.erb +1 -0
  32. data/app/views/spree/admin/orders/_index_channable_state_override.html.erb +7 -0
  33. data/app/views/spree/admin/orders/_index_channable_state_override_head.html.erb +1 -0
  34. data/bin/rails +8 -0
  35. data/config/locales/en.yml +5 -0
  36. data/config/routes.rb +18 -0
  37. data/db/migrate/20190710092345_create_channable_settings.rb +16 -0
  38. data/db/migrate/20190710103701_add_settings_to_settings_table.rb +9 -0
  39. data/db/migrate/20190710115409_add_order_columns.rb +9 -0
  40. data/db/migrate/20190711122425_set_order_connection_defaults.rb +5 -0
  41. data/db/migrate/20190711123402_add_channable_fields_to_shipping_methods.rb +8 -0
  42. data/db/migrate/20190711140015_add_payment_method_for_channable.rb +7 -0
  43. data/db/migrate/20190711145940_add_order_import_settings.rb +9 -0
  44. data/db/migrate/20190717120144_add_channable_id_to_return_authorisations.rb +5 -0
  45. data/gemfiles/spree_3_2.gemfile +10 -0
  46. data/gemfiles/spree_3_5.gemfile +10 -0
  47. data/gemfiles/spree_3_7.gemfile +10 -0
  48. data/gemfiles/spree_master.gemfile +10 -0
  49. data/lib/channable/client.rb +42 -0
  50. data/lib/channable/response.rb +15 -0
  51. data/lib/generators/spree_channable/install/install_generator.rb +20 -0
  52. data/lib/spree_channable/engine.rb +20 -0
  53. data/lib/spree_channable/factories.rb +6 -0
  54. data/lib/spree_channable/order_importer.rb +280 -0
  55. data/lib/spree_channable/return_importer.rb +63 -0
  56. data/lib/spree_channable/version.rb +18 -0
  57. data/lib/spree_channable.rb +36 -0
  58. data/spec/fixtures/invalid_channable_order.json +117 -0
  59. data/spec/fixtures/valid_channable_order.json +117 -0
  60. data/spree_channable.gemspec +50 -0
  61. metadata +451 -0
@@ -0,0 +1,280 @@
1
+ module SpreeChannable
2
+ class OrderImporter
3
+
4
+ def self.import(user, params)
5
+ begin
6
+ ensure_country_id_from_params params[:ship_address_attributes]
7
+ ensure_state_id_from_params params[:ship_address_attributes]
8
+ ensure_country_id_from_params params[:bill_address_attributes]
9
+ ensure_state_id_from_params params[:bill_address_attributes]
10
+
11
+ create_params = params.slice :currency
12
+ order = Spree::Order.create! create_params
13
+ order.associate_user!(user) if user.present?
14
+
15
+ shipments_attrs = params.delete(:shipments_attributes)
16
+
17
+ create_line_items_from_params(params.delete(:line_items_attributes), order)
18
+ create_shipments_from_params(shipments_attrs, order)
19
+ create_adjustments_from_params(params.delete(:adjustments_attributes), order)
20
+ create_payments_from_params(params.delete(:payments_attributes), order)
21
+
22
+ if completed_at = params.delete(:completed_at)
23
+ order.completed_at = completed_at
24
+ order.state = 'complete'
25
+ end
26
+
27
+ params.delete(:user_id) unless user.present? && user.try(:has_spree_role?, "admin") && params.key?(:user_id)
28
+
29
+ order.update_attributes!(params)
30
+
31
+ order.create_proposed_shipments unless shipments_attrs.present?
32
+
33
+ # Really ensure that the order totals & states are correct
34
+ order.updater.update
35
+ if shipments_attrs.present?
36
+ order.shipments.each_with_index do |shipment, index|
37
+ shipment.update_columns(cost: shipments_attrs[index][:cost].to_f) if shipments_attrs[index][:cost].present?
38
+ end
39
+ end
40
+ order.reload
41
+ rescue Exception => e
42
+ order.destroy if order && order.persisted?
43
+ raise e.message
44
+ end
45
+ end
46
+
47
+ def self.create_payments_from_params(payments_hash, order)
48
+ return [] unless payments_hash
49
+ payments_hash.each do |p|
50
+ begin
51
+ payment = order.payments.build order: order
52
+ payment.amount = p[:amount].to_f || order.total
53
+ # Order API should be using state as that's the normal payment field.
54
+ # spree_wombat serializes payment state as status so imported orders should fall back to status field.
55
+ payment.state = p[:state] || p[:status] || 'completed'
56
+ payment.created_at = p[:created_at] if p[:created_at]
57
+ payment.payment_method = p[:payment_method]
58
+ payment.source = create_source_payment_from_params(p[:source], payment) if p[:source]
59
+ payment.save!
60
+ rescue Exception => e
61
+ raise "Order import payments: #{e.message} #{p}"
62
+ end
63
+ end
64
+ end
65
+
66
+ def self.create_shipments_from_params(shipments_hash, order)
67
+ return [] unless shipments_hash
68
+
69
+ inventory_units = Spree::Stock::InventoryUnitBuilder.new(order).units
70
+
71
+ shipments_hash.each do |s|
72
+ begin
73
+ shipment = order.shipments.build
74
+ shipment.tracking = s[:tracking]
75
+ shipment.stock_location = s[:stock_location]
76
+
77
+ shipment_units = s[:inventory_units] || []
78
+ shipment_units.each do |su|
79
+ ensure_variant_id_from_params(su)
80
+
81
+ inventory_unit = inventory_units.detect {|iu| iu.variant_id.to_i == su[:variant_id].to_i}
82
+
83
+ if inventory_unit.present?
84
+ inventory_unit.shipment = shipment
85
+
86
+ if s[:shipped_at].present?
87
+ inventory_unit.pending = false
88
+ inventory_unit.state = 'shipped'
89
+ end
90
+
91
+ inventory_unit.save!
92
+
93
+ # Don't assign shipments to this inventory unit more than once
94
+ inventory_units.delete(inventory_unit)
95
+ end
96
+ end
97
+
98
+ if s[:shipped_at].present?
99
+ shipment.shipped_at = s[:shipped_at]
100
+ shipment.state = 'shipped'
101
+ end
102
+
103
+ shipment.save!
104
+
105
+ shipping_method = Spree::ShippingMethod.where("channable_channel_name LIKE CONCAT('%', ?, '%')", s[:shipping_method]).first || shipping_method = Spree::ShippingMethod.find_by(name: s[:shipping_method]) || Spree::ShippingMethod.find_by!(admin_name: s[:shipping_method])
106
+ rate = shipment.shipping_rates.create!(shipping_method: shipping_method, cost: s[:cost])
107
+
108
+ shipment.selected_shipping_rate_id = rate.id
109
+ shipment.update_amounts
110
+
111
+ adjustments = s.delete(:adjustments_attributes)
112
+ create_adjustments_from_params(adjustments, order, shipment)
113
+ rescue Exception => e
114
+ raise "Order import shipments: #{e.message} #{s}"
115
+ end
116
+ end
117
+ end
118
+
119
+ def self.create_line_items_from_params(line_items, order)
120
+ return {} unless line_items
121
+ iterator = case line_items
122
+ when Hash
123
+ ActiveSupport::Deprecation.warn(<<-EOS, caller)
124
+ Passing a hash is now deprecated and will be removed in Spree 4.0.
125
+ It is recommended that you pass it as an array instead.
126
+
127
+ New Syntax:
128
+
129
+ {
130
+ "order": {
131
+ "line_items": [
132
+ { "variant_id": 123, "quantity": 1 },
133
+ { "variant_id": 456, "quantity": 1 }
134
+ ]
135
+ }
136
+ }
137
+
138
+ Old Syntax:
139
+
140
+ {
141
+ "order": {
142
+ "line_items": {
143
+ "1": { "variant_id": 123, "quantity": 1 },
144
+ "2": { "variant_id": 123, "quantity": 1 }
145
+ }
146
+ }
147
+ }
148
+ EOS
149
+ :each_value
150
+ when Array
151
+ :each
152
+ end
153
+
154
+ line_items.send(iterator) do |line_item|
155
+ begin
156
+ adjustments = line_item.delete(:adjustments_attributes)
157
+ extra_params = line_item.except(:variant_id, :quantity, :sku)
158
+ line_item = ensure_variant_id_from_params(line_item)
159
+ variant = Spree::Variant.find(line_item[:variant_id])
160
+ line_item = order.contents.add(variant, line_item[:quantity])
161
+ # Raise any errors with saving to prevent import succeeding with line items
162
+ # failing silently.
163
+ if extra_params.present?
164
+ line_item.update_attributes!(extra_params)
165
+ else
166
+ line_item.save!
167
+ end
168
+ create_adjustments_from_params(adjustments, order, line_item)
169
+ rescue Exception => e
170
+ raise "Order import line items: #{e.message} #{line_item}"
171
+ end
172
+ end
173
+ end
174
+
175
+ def self.create_adjustments_from_params(adjustments, order, adjustable = nil)
176
+ return [] unless adjustments
177
+ adjustments.each do |a|
178
+ begin
179
+ adjustment = (adjustable || order).adjustments.build(
180
+ order: order,
181
+ amount: a[:amount].to_f,
182
+ label: a[:label],
183
+ source_type: source_type_from_adjustment(a)
184
+ )
185
+ adjustment.save!
186
+ adjustment.close!
187
+ rescue Exception => e
188
+ raise "Order import adjustments: #{e.message} #{a}"
189
+ end
190
+ end
191
+ end
192
+
193
+ def self.create_source_payment_from_params(source_hash, payment)
194
+ begin
195
+ Spree::CreditCard.create(
196
+ month: source_hash[:month],
197
+ year: source_hash[:year],
198
+ cc_type: source_hash[:cc_type],
199
+ last_digits: source_hash[:last_digits],
200
+ name: source_hash[:name],
201
+ payment_method: payment.payment_method,
202
+ gateway_customer_profile_id: source_hash[:gateway_customer_profile_id],
203
+ gateway_payment_profile_id: source_hash[:gateway_payment_profile_id],
204
+ imported: true
205
+ )
206
+ rescue Exception => e
207
+ raise "Order import source payments: #{e.message} #{source_hash}"
208
+ end
209
+ end
210
+
211
+ def self.ensure_variant_id_from_params(hash)
212
+ begin
213
+ sku = hash.delete(:sku)
214
+ unless hash[:variant_id].present?
215
+ hash[:variant_id] = Spree::Variant.active.find_by_sku!(sku).id
216
+ end
217
+ hash
218
+ rescue ActiveRecord::RecordNotFound => e
219
+ raise "Ensure order import variant: Variant w/SKU #{sku} not found."
220
+ rescue Exception => e
221
+ raise "Ensure order import variant: #{e.message} #{hash}"
222
+ end
223
+ end
224
+
225
+ def self.ensure_country_id_from_params(address)
226
+ return if address.nil? or address[:country_id].present? or address[:country].nil?
227
+
228
+ begin
229
+ search = {}
230
+ if name = address[:country]['name']
231
+ search[:name] = name
232
+ elsif iso_name = address[:country]['iso_name']
233
+ search[:iso_name] = iso_name.upcase
234
+ elsif iso = address[:country]['iso']
235
+ search[:iso] = iso.upcase
236
+ elsif iso3 = address[:country]['iso3']
237
+ search[:iso3] = iso3.upcase
238
+ end
239
+
240
+ address.delete(:country)
241
+ address[:country_id] = Spree::Country.where(search).first!.id
242
+
243
+ rescue Exception => e
244
+ raise "Ensure order import address country: #{e.message} #{search}"
245
+ end
246
+ end
247
+
248
+ def self.ensure_state_id_from_params(address)
249
+ return if address.nil? or address[:state_id].present? or address[:state].nil?
250
+
251
+ begin
252
+ search = {}
253
+ if name = address[:state]['name']
254
+ search[:name] = name
255
+ elsif abbr = address[:state]['abbr']
256
+ search[:abbr] = abbr.upcase
257
+ end
258
+
259
+ address.delete(:state)
260
+ search[:country_id] = address[:country_id]
261
+
262
+ if state = Spree::State.where(search).first
263
+ address[:state_id] = state.id
264
+ else
265
+ address[:state_name] = search[:name] || search[:abbr]
266
+ end
267
+ rescue Exception => e
268
+ raise "Ensure order import address state: #{e.message} #{search}"
269
+ end
270
+ end
271
+
272
+ def self.source_type_from_adjustment(adjustment)
273
+ if adjustment[:tax]
274
+ 'Spree::TaxRate'
275
+ elsif adjustment[:promotion]
276
+ 'Spree::PromotionAction'
277
+ end
278
+ end
279
+ end
280
+ end
@@ -0,0 +1,63 @@
1
+ module SpreeChannable
2
+ class ReturnImporter
3
+
4
+
5
+ # {
6
+ # "status": "new",
7
+ # "channel_name": "bol",
8
+ # "channel_id": "61284922",
9
+ # "channable_id": 151,
10
+ # "data": {
11
+ # "item": {
12
+ # "id": "11694321",
13
+ # "order_id": "4522232111",
14
+ # "gtin": "0884500642113",
15
+ # "title": "Nike Air Force 1 Winter Premium GS Flax Pack",
16
+ # "quantity": 1,
17
+ # "reason": "Anders, namelijk:",
18
+ # "comment": "De schoenen vielen te groot."
19
+ # },
20
+ # "customer": {
21
+ # "gender": "male",
22
+ # "first_name": "Jans",
23
+ # "last_name": "Van Janssen",
24
+ # "email": "2ixee2337ca74m23423uu@verkopen.bol.com"
25
+ # },
26
+ # "address": {
27
+ # "first_name": "Jans",
28
+ # "last_name": "Van Janssen",
29
+ # "email": "2ixee2337ca74m23423uu@verkopen.bol.com",
30
+ # "street": "Teststraat",
31
+ # "house_number": 12,
32
+ # "address1": "Teststraat 12",
33
+ # "adderss2": "",
34
+ # "city": "Utrecht",
35
+ # "country_code": "NL",
36
+ # "zip_code": "1234 XZ"
37
+ # }
38
+ # }
39
+ # }
40
+ def self.import(return_data)
41
+ order = Spree::Order.find_by_channable_order_id(return_data.data.item.order_id)
42
+
43
+ return_reason_id = Spree::ReturnAuthorizationReason.first.id
44
+ inventory_unit = order.line_items.detect {|li| li.variant.sku == return_data.data.item.gtin}&.inventory_units&.first
45
+
46
+
47
+ if order && inventory_unit
48
+ return_authorization = Spree::ReturnAuthorization.create!(
49
+ order_id: order.id,
50
+ stock_location: ::SpreeChannable.configuration.stock_location,
51
+ return_authorization_reason_id: return_reason_id
52
+ )
53
+ Spree::CustomerReturn.create(
54
+ stock_location: ::SpreeChannable.configuration.stock_location,
55
+ channable_order_id: return_data.channable_id,
56
+ return_items_attributes: {
57
+ return_authorization_id: return_authorization.id, inventory_unit_id: inventory_unit.id
58
+ })
59
+ end
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,18 @@
1
+ module SpreeChannable
2
+ module_function
3
+
4
+ # Returns the version of the currently loaded SpreeChannable as a
5
+ # <tt>Gem::Version</tt>.
6
+ def version
7
+ Gem::Version.new VERSION::STRING
8
+ end
9
+
10
+ module VERSION
11
+ MAJOR = 0
12
+ MINOR = 0
13
+ TINY = 18
14
+ PRE = 'alpha'.freeze
15
+
16
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ require 'spree_core'
2
+ require 'spree_extension'
3
+ require 'spree_channable/engine'
4
+ require 'spree_channable/version'
5
+ require 'spree_channable/order_importer'
6
+
7
+ require 'channable/client'
8
+ require 'channable/response'
9
+
10
+ require 'whenever'
11
+
12
+ module SpreeChannable
13
+
14
+ class << self
15
+ def configuration
16
+ Configuration.new
17
+ end
18
+ end
19
+
20
+ class Configuration
21
+ ATTR_LIST = [:host, :url_prefix, :image_host, :product_condition, :brand, :delivery_period, :use_variant_images, :channable_api_key, :company_id, :project_id, :stock_location, :payment_method, :polling_interval, :active?]
22
+
23
+ ATTR_LIST.each do |a|
24
+ define_method a do
25
+ setting_model.try(a)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def setting_model
32
+ ::ChannableSetting.last
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,117 @@
1
+ {
2
+ "order": {
3
+ "channel_id": "123",
4
+ "channel_name": "bol",
5
+ "created": "2017-08-02T14:31:48",
6
+ "data": {
7
+ "billing": {
8
+ "address1": "Billingstraat 1",
9
+ "address2": "Onder de brievanbus huisnummer 1 extra adres info",
10
+ "address_supplement": "Onder de brievanbus huisnummer 1 extra adres info",
11
+ "city": "Amsterdam",
12
+ "company": "Bol.com",
13
+ "country_code": "NL",
14
+ "email": "dontemail@me.net",
15
+ "first_name": "Jans",
16
+ "house_number": 1,
17
+ "house_number_ext": "",
18
+ "last_name": "Janssen",
19
+ "middle_name": "",
20
+ "region": "",
21
+ "street": "Billingstraat",
22
+ "zip_code": "5000 ZZ"
23
+ },
24
+ "customer": {
25
+ "company": "Bol.com",
26
+ "email": "dontemail@me.net",
27
+ "first_name": "Jans",
28
+ "gender": "male",
29
+ "last_name": "Janssen",
30
+ "middle_name": "",
31
+ "mobile": "",
32
+ "phone": "0201234567"
33
+ },
34
+ "extra": {
35
+ "comment": "Bol.com order id: 123",
36
+ "memo": "Order from Channable \n Bol.com order id: 123\n Customer receipt: https:\/\/www.bol.com\/sdd\/orders\/downloadallpackageslips.html"
37
+ },
38
+ "price": {
39
+ "commission": 1.5,
40
+ "currency": "EUR",
41
+ "payment_method": "bol",
42
+ "shipping": 0,
43
+ "subtotal": 123.45,
44
+ "total": 123.45,
45
+ "transaction_fee": 0
46
+ },
47
+ "products": [
48
+ {
49
+ "commission": 1.5,
50
+ "delivery_period": "2017-08-02+02:00",
51
+ "ean": "does_not_exist",
52
+ "id": "11693020",
53
+ "price": 61.725,
54
+ "quantity": 2,
55
+ "reference_code": "123",
56
+ "shipping": 0,
57
+ "title": "Harry Potter"
58
+ }
59
+ ],
60
+ "shipping": {
61
+ "address1": "Shipmentstraat 42 bis",
62
+ "address2": "",
63
+ "address_supplement": "3 hoog achter extra adres info",
64
+ "city": "Amsterdam",
65
+ "company": "The Company",
66
+ "country_code": "NL",
67
+ "email": "nospam4me@myaccount.com",
68
+ "first_name": "Jan",
69
+ "house_number": 42,
70
+ "house_number_ext": "bis",
71
+ "last_name": "Janssen",
72
+ "middle_name": "",
73
+ "region": "",
74
+ "street": "Shipmentstraat",
75
+ "zip_code": "1000 AA"
76
+ }
77
+ },
78
+ "error": false,
79
+ "fulfillment": {},
80
+ "id": 299623,
81
+ "modified": "2017-08-10T18:08:13.699449",
82
+ "platform_id": "299623",
83
+ "platform_name": "channable",
84
+ "project_id": 6496,
85
+ "status_paid": "paid",
86
+ "status_shipped": "shipped"
87
+ },
88
+ "events": [
89
+ {
90
+ "created": "2016-10-20T10:55:08.507355",
91
+ "id": 1234545,
92
+ "message": "Sent shipment update to Amazon",
93
+ "modified": "2016-10-20T10:55:08.507378",
94
+ "order_id": 299623,
95
+ "project_id": 91919,
96
+ "status": "info"
97
+ },
98
+ {
99
+ "created": "2016-10-20T10:54:53.074700",
100
+ "id": 2370337,
101
+ "message": "Changed shipping status: not_shipped -> shipped",
102
+ "modified": "2016-10-20T10:54:53.074705",
103
+ "order_id": 299623,
104
+ "project_id": 91919,
105
+ "status": "info"
106
+ },
107
+ {
108
+ "created": "2016-10-19T10:54:15.008544",
109
+ "id": 1407404,
110
+ "message": "Channable order processed: 299623",
111
+ "modified": "2016-10-19T10:54:15.008551",
112
+ "order_id": 299623,
113
+ "project_id": 91919,
114
+ "status": "info"
115
+ }
116
+ ]
117
+ }
@@ -0,0 +1,117 @@
1
+ {
2
+ "order": {
3
+ "channel_id": "123",
4
+ "channel_name": "bol",
5
+ "created": "2017-08-02T14:31:48",
6
+ "data": {
7
+ "billing": {
8
+ "address1": "Billingstraat 1",
9
+ "address2": "Onder de brievanbus huisnummer 1 extra adres info",
10
+ "address_supplement": "Onder de brievanbus huisnummer 1 extra adres info",
11
+ "city": "Amsterdam",
12
+ "company": "Bol.com",
13
+ "country_code": "NL",
14
+ "email": "dontemail@me.net",
15
+ "first_name": "Jans",
16
+ "house_number": 1,
17
+ "house_number_ext": "",
18
+ "last_name": "Janssen",
19
+ "middle_name": "",
20
+ "region": "",
21
+ "street": "Billingstraat",
22
+ "zip_code": "5000 ZZ"
23
+ },
24
+ "customer": {
25
+ "company": "Bol.com",
26
+ "email": "dontemail@me.net",
27
+ "first_name": "Jans",
28
+ "gender": "male",
29
+ "last_name": "Janssen",
30
+ "middle_name": "",
31
+ "mobile": "",
32
+ "phone": "0201234567"
33
+ },
34
+ "extra": {
35
+ "comment": "Bol.com order id: 123",
36
+ "memo": "Order from Channable \n Bol.com order id: 123\n Customer receipt: https:\/\/www.bol.com\/sdd\/orders\/downloadallpackageslips.html"
37
+ },
38
+ "price": {
39
+ "commission": 1.5,
40
+ "currency": "EUR",
41
+ "payment_method": "bol",
42
+ "shipping": 10,
43
+ "subtotal": 123.44,
44
+ "total": 133.44,
45
+ "transaction_fee": 0
46
+ },
47
+ "products": [
48
+ {
49
+ "commission": 1.5,
50
+ "delivery_period": "2017-08-02+02:00",
51
+ "ean": "9789062387410",
52
+ "id": "11693020",
53
+ "price": 61.72,
54
+ "quantity": 2,
55
+ "reference_code": "123",
56
+ "shipping": 0,
57
+ "title": "Harry Potter"
58
+ }
59
+ ],
60
+ "shipping": {
61
+ "address1": "Shipmentstraat 42 bis",
62
+ "address2": "",
63
+ "address_supplement": "3 hoog achter extra adres info",
64
+ "city": "Amsterdam",
65
+ "company": "The Company",
66
+ "country_code": "NL",
67
+ "email": "nospam4me@myaccount.com",
68
+ "first_name": "Jan",
69
+ "house_number": 42,
70
+ "house_number_ext": "bis",
71
+ "last_name": "Janssen",
72
+ "middle_name": "",
73
+ "region": "",
74
+ "street": "Shipmentstraat",
75
+ "zip_code": "1000 AA"
76
+ }
77
+ },
78
+ "error": false,
79
+ "fulfillment": {},
80
+ "id": 299623,
81
+ "modified": "2017-08-10T18:08:13.699449",
82
+ "platform_id": "299623",
83
+ "platform_name": "channable",
84
+ "project_id": 6496,
85
+ "status_paid": "paid",
86
+ "status_shipped": "shipped"
87
+ },
88
+ "events": [
89
+ {
90
+ "created": "2016-10-20T10:55:08.507355",
91
+ "id": 1234545,
92
+ "message": "Sent shipment update to Amazon",
93
+ "modified": "2016-10-20T10:55:08.507378",
94
+ "order_id": 299623,
95
+ "project_id": 91919,
96
+ "status": "info"
97
+ },
98
+ {
99
+ "created": "2016-10-20T10:54:53.074700",
100
+ "id": 2370337,
101
+ "message": "Changed shipping status: not_shipped -> shipped",
102
+ "modified": "2016-10-20T10:54:53.074705",
103
+ "order_id": 299623,
104
+ "project_id": 91919,
105
+ "status": "info"
106
+ },
107
+ {
108
+ "created": "2016-10-19T10:54:15.008544",
109
+ "id": 1407404,
110
+ "message": "Channable order processed: 299623",
111
+ "modified": "2016-10-19T10:54:15.008551",
112
+ "order_id": 299623,
113
+ "project_id": 91919,
114
+ "status": "info"
115
+ }
116
+ ]
117
+ }
@@ -0,0 +1,50 @@
1
+ # encoding: UTF-8
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'spree_channable/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.platform = Gem::Platform::RUBY
9
+ s.name = 'spree_channable'
10
+ s.version = SpreeChannable.version
11
+ s.summary = 'Spree Channable'
12
+ s.description = 'Connect your spree store to channable. Receive orders, generate product feeds and send shipment updates.'
13
+ s.required_ruby_version = '>= 2.2.7'
14
+
15
+ s.author = 'Fabian Oudhaarlem'
16
+ s.email = 'fabian@oldharlem.nl'
17
+ s.homepage = 'https://github.com/Oldharlem/spree_channable'
18
+ s.license = 'BSD-3-Clause'
19
+
20
+ s.files = `git ls-files`.split("\n").reject { |f| f.match(/^spec/) && !f.match(/^spec\/fixtures/) }
21
+ s.require_path = 'lib'
22
+ s.requirements << 'none'
23
+
24
+ spree_version = '>= 3.1.0', '< 5.0'
25
+ s.add_dependency 'rails', '>= 4.2.0'
26
+ s.add_dependency 'spree_core', spree_version
27
+ s.add_dependency 'spree_backend', spree_version
28
+ s.add_dependency 'spree_extension'
29
+ s.add_dependency 'parallel'
30
+ s.add_dependency 'httparty'
31
+ s.add_dependency 'whenever'
32
+
33
+ s.add_development_dependency 'appraisal'
34
+ s.add_development_dependency 'awesome_print'
35
+ s.add_development_dependency 'capybara'
36
+ s.add_development_dependency 'capybara-screenshot'
37
+ s.add_development_dependency 'coffee-rails'
38
+ s.add_development_dependency 'database_cleaner'
39
+ s.add_development_dependency 'factory_bot', '~> 4.7'
40
+ s.add_development_dependency 'factory_bot_rails', '~> 4.7'
41
+ s.add_development_dependency 'ffaker'
42
+ s.add_development_dependency 'mysql2'
43
+ s.add_development_dependency 'pg'
44
+ s.add_development_dependency 'pry'
45
+ s.add_development_dependency 'rspec-rails'
46
+ s.add_development_dependency 'sass-rails'
47
+ s.add_development_dependency 'simplecov'
48
+ s.add_development_dependency 'sqlite3', '~> 1.3.6'
49
+ s.add_development_dependency 'webdrivers', '~> 3.8.0'
50
+ end