spree_gladly 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79f58571478fed7fa33637006c8b2157fc3b78816ba0c8607bfe1bfb940b390e
4
- data.tar.gz: 4d8d50389dec9a281fc53b023e1d58fcec863116938d1b50671703012bd5fe85
3
+ metadata.gz: 838966d87c3ac9621653856b60d79a1b55b318efaa16a1bb532c255f48982d1f
4
+ data.tar.gz: 1243ce174014bc76281167c3b9a9ed7d5b0fc0620dbca2132661d5e367cad8f6
5
5
  SHA512:
6
- metadata.gz: be1fdeefa5f51e74dd636703e72b385e8c40c10d0a6e1ce2d153e0c7bfc09869b93cdf579f2ff1d5fc2721bfd56b62c4d62703f24dcc7d745b2439921b6998a8
7
- data.tar.gz: ece65399dc55fd6f0cde6c5554e93c683d45cabb9c749341137fc7fb7bca78cd06f618c6a80d86020dc292c92df277b3de35da0c1dcc2db6e119b7d302b08ac4
6
+ metadata.gz: 07b9c6075897f3cf6023b38eff000c950359c3fefcbd5c89936ce54e42f1891a285e4555ffe15a0016dae5dd99343a9ba8ef26ebe7924719c6a88161aa84d1f3
7
+ data.tar.gz: 9acf57058969584c7b63afd13f388684679b5e2a36e352d2fabdc4eae5777ea0ad8730ece1192f98bb1e758da4b26a44e2dcf5814513ef1c0f49965504e37f60
data/.travis.yml CHANGED
@@ -14,7 +14,6 @@ services:
14
14
  language: ruby
15
15
 
16
16
  rvm:
17
- - 2.3
18
17
  - 2.4
19
18
  - 2.5
20
19
  - 2.7
@@ -28,6 +27,9 @@ gemfile:
28
27
  - gemfiles/spree_3_0.gemfile
29
28
  - gemfiles/spree_3_1.gemfile
30
29
  - gemfiles/spree_3_7.gemfile
30
+ - gemfiles/spree_4_0.gemfile
31
+ - gemfiles/spree_4_1.gemfile
32
+ - gemfiles/spree_4_2.gemfile
31
33
  - gemfiles/spree_master.gemfile
32
34
 
33
35
  jobs:
@@ -35,14 +37,16 @@ jobs:
35
37
  allow_failures:
36
38
  - gemfile: gemfiles/spree_master.gemfile
37
39
  exclude:
38
- - rvm: 2.3
39
- gemfile: gemfiles/spree_3_7.gemfile
40
- - rvm: 2.3
41
- gemfile: gemfiles/spree_master.gemfile
42
40
  - rvm: 2.4
43
41
  gemfile: gemfiles/spree_3_7.gemfile
44
42
  - rvm: 2.4
45
43
  gemfile: gemfiles/spree_master.gemfile
44
+ - rvm: 2.4
45
+ gemfile: gemfiles/spree_4_0.gemfile
46
+ - rvm: 2.4
47
+ gemfile: gemfiles/spree_4_1.gemfile
48
+ - rvm: 2.4
49
+ gemfile: gemfiles/spree_4_2.gemfile
46
50
  - rvm: 2.5
47
51
  gemfile: gemfiles/spree_3_0.gemfile
48
52
  - rvm: 2.5
@@ -59,6 +63,10 @@ jobs:
59
63
  gemfile: gemfiles/spree_3_1.gemfile
60
64
  - rvm: 3.0
61
65
  gemfile: gemfiles/spree_3_7.gemfile
66
+ - rvm: 3.0
67
+ gemfile: gemfiles/spree_4_0.gemfile
68
+ - rvm: 3.0
69
+ gemfile: gemfiles/spree_4_1.gemfile
62
70
 
63
71
  script:
64
72
  - bundle exec rake test_app
data/README.md CHANGED
@@ -31,6 +31,8 @@ Supported Spree versions: `3.0`, `3.1`, `3.7`, `4.0`, `4.1`, `4.2`
31
31
  - [Basic search](#basic-search)
32
32
  - [Detailed search](#detailed-search)
33
33
  - [Customization](#customization)
34
+ - [Events](#events)
35
+ - [Configuration](#configuration)
34
36
  - [Setup sandbox environment](#setup-sandbox-environment)
35
37
  - [Testing](#testing)
36
38
  - [Contributing](#contributing)
@@ -111,7 +113,94 @@ end
111
113
  ***Note: please adjust migration to yours Rails version***
112
114
 
113
115
 
114
- ### Gladly Service side
116
+ ### Gladly Service side:
117
+
118
+ Provide to your agent:
119
+ - lookup endpoint ( `https://example-spree-store.com/api/v1/customers/lookup` ), where `https://example-spree-store.com` is **your** Spree store URL.
120
+ - signing_key
121
+
122
+
123
+ ## Events
124
+
125
+ ### Description
126
+ Within gem we introduce [Conversations (Create Item)](https://developer.gladly.com/rest/#operation/createItem) using API client.
127
+ We implemented two events against `Spree::Order` model:
128
+ - `Placed` - it's fired up after Order is completed by customer ( `Gladly::Events::Order::Placed`)
129
+ - `Refundned` - it's fired up after Order items are returned to customer ( `Gladly::Events::Order::Refunded`)
130
+
131
+ More about [Conversations](https://developer.gladly.com/rest/#tag/Conversations)
132
+
133
+ ### Configuration
134
+
135
+ **Important !!!**
136
+
137
+ **Without bellow settings events will won't work. You will get those from yours Gladly dashboard**
138
+
139
+ ```ruby
140
+ config.gladly_api_username = 'api_username@example.com'
141
+ config.gladly_api_key = 'api_key'
142
+ config.gladly_api_base_url = 'https://dev-example.gladly.qa'
143
+ config.turn_off_built_in_events = false
144
+ ```
145
+
146
+ In case when you need write your own events class you can switch off built-in events by setting `turn_off_built_in_events` as `true`
147
+
148
+
149
+ ## Customization
150
+
151
+ Within `spree_gladly` gem we distinguish response for `guest` and `registerd` customer. For customize those, i.e [detailed lookup response](#detailed-lookup), to do that you have do following steps:
152
+
153
+ 1. replace `Customer::DetailedLookupPresenter` in `config/initializers/spree_gladly.rb` initializer file with your own.
154
+ 2. override methods `registerd_presenter` ( [default presenter](https://github.com/upsidelab/spree_gladly/blob/master/app/presenters/customer/registered/detailed_presenter.rb) ) or `guest_presenter` ( [default presenter](https://github.com/upsidelab/spree_gladly/blob/master/app/presenters/customer/guest/detailed_presenter.rb) ) with your own.
155
+
156
+ Please consider below example:
157
+
158
+ ```ruby
159
+ class GladlyCustomersPresenter
160
+ include Spree::Core::Engine.routes.url_helpers # this is important if you want to use Spree routes
161
+
162
+ def initialize(resource:)
163
+ @resource = resource
164
+ end
165
+
166
+ def to_h
167
+ return [] unless resource.customer.present?
168
+
169
+ resource.guest ? guest_presenter : registered_presenter
170
+ end
171
+
172
+ private
173
+
174
+ attr_reader :resource
175
+
176
+ def registered_presenter
177
+ YourOwn::DetailedPresenter.new(resource: resource).to_h
178
+ end
179
+
180
+ def guest_presenter
181
+ Customer::Guest::DetailedPresenter.new(resource: resource).to_h
182
+ end
183
+ ...
184
+ end
185
+ ```
186
+
187
+ `config/initializers/spree_gladly.rb`
188
+
189
+ ```ruby
190
+ SpreeGladly.setup do |config|
191
+ # ...
192
+
193
+ config.basic_lookup_presenter = Customer::BasicLookupPresenter
194
+ config.detailed_lookup_presenter = GladlyCustomersPresenter
195
+
196
+ # ...
197
+ end
198
+ ```
199
+
200
+ **!!! Important !!!**
201
+
202
+ If you would like to resign from `to_h` or change `initialize(resource:)` method, you have to override `Spree::Api::V1::CustomersController#serialize_collection` to do that, please follow by this [guide](https://guides.spreecommerce.org/developer/customization/logic.html#extending-controllers)
203
+
115
204
 
116
205
  To understand how to set up the integration in Gladly please refer to the Gladly help docs
117
206
 
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module OrderDecorator
5
+ def self.prepended(base)
6
+ base.state_machine do
7
+ after_transition to: :complete, do: :send_placed_order_event
8
+ end
9
+ end
10
+
11
+ def send_placed_order_event
12
+ Gladly::Events::Order::Placed.new(order: self).call
13
+ end
14
+ end
15
+ end
16
+ ::Spree::Order.prepend(Spree::OrderDecorator)
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module RefundDecorator
5
+ def perform!
6
+ super
7
+ Gladly::Events::Order::Refunded.new(order: payment.order, refund: self).call
8
+ end
9
+ end
10
+ end
11
+ ::Spree::Refund.prepend(Spree::RefundDecorator)
@@ -8,7 +8,11 @@ module SpreeGladly
8
8
  :order_limit,
9
9
  :order_includes,
10
10
  :order_sorting,
11
- :order_states
11
+ :order_states,
12
+ :gladly_api_username,
13
+ :gladly_api_key,
14
+ :gladly_api_base_url,
15
+ :turn_off_built_in_events
12
16
 
13
17
  @basic_lookup_presenter = nil
14
18
 
@@ -21,5 +25,13 @@ module SpreeGladly
21
25
  @order_sorting = nil
22
26
 
23
27
  @order_states = nil
28
+
29
+ @gladly_api_username = nil
30
+
31
+ @gladly_api_key = nil
32
+
33
+ @gladly_api_base_url = nil
34
+
35
+ @turn_off_built_in_events = nil
24
36
  end
25
37
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+
5
+ module Gladly
6
+ module Api
7
+ class Client
8
+ include Gladly::Api::ErrorHandling
9
+
10
+ def initialize(payload: {})
11
+ @api_username = SpreeGladly::Config.gladly_api_username
12
+ @api_key = SpreeGladly::Config.gladly_api_key
13
+ @base_url = SpreeGladly::Config.gladly_api_base_url
14
+ @payload = payload
15
+ end
16
+
17
+ def call
18
+ return if base_url.blank?
19
+
20
+ perform_request
21
+ end
22
+
23
+ def perform_request
24
+ post_request if request_method.eql?(:post)
25
+ end
26
+
27
+ def post_request
28
+ uri = URI(request_url)
29
+
30
+ http = Net::HTTP.new(uri.host, uri.port)
31
+ http.open_timeout = 20
32
+ http.use_ssl = true
33
+
34
+ request = Net::HTTP::Post.new(uri.path)
35
+ request.basic_auth(api_username, api_key)
36
+ request.body = payload.to_json
37
+
38
+ response = http.request(request)
39
+
40
+ formatted_response(response: response)
41
+ end
42
+
43
+ def request_url
44
+ "#{base_url}#{resource_url}"
45
+ end
46
+
47
+ def request_method
48
+ not_implemented_error
49
+ end
50
+
51
+ def resource_url
52
+ not_implemented_error
53
+ end
54
+
55
+ private
56
+
57
+ attr_reader :base_url, :api_key, :api_username, :payload
58
+
59
+ def formatted_response(response:)
60
+ parse_error(error: response) if net_http_errors.include?(response.class.to_s)
61
+
62
+ { id: JSON.parse(response.body)['id'], code: response.code, status: response.msg }
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gladly
4
+ module Api
5
+ module Conversations
6
+ class Create < Gladly::Api::Client
7
+ def request_method
8
+ :post
9
+ end
10
+
11
+ def resource_url
12
+ '/api/v1/conversation-items'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gladly
4
+ module Api
5
+ module ErrorHandling
6
+ # rubocop:disable Layout/LineLength
7
+ def net_http_errors
8
+ %w[Timeout::Error Errno::EINVAL Errno::ECONNRESET EOFError Net::HTTPBadResponse Net::HTTPHeaderSyntaxError Net::ProtocolError Net::HTTPUnauthorized]
9
+ end
10
+ # rubocop:enable Layout/LineLength
11
+
12
+ def parse_error(error:)
13
+ { errors: [{ code: error.code, detail: error.msg }] }
14
+ end
15
+
16
+ def not_implemented_error
17
+ raise NotImplementedError
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gladly
4
+ module Events
5
+ module Order
6
+ class Base
7
+ include Spree::Core::Engine.routes.url_helpers
8
+
9
+ def initialize(order:, refund: nil)
10
+ @order = order
11
+ @refund = refund
12
+ end
13
+
14
+ # rubocop:disable Layout/LineLength
15
+ def call
16
+ Gladly::Api::Conversations::Create.new(payload: payload).call unless SpreeGladly::Config.turn_off_built_in_events
17
+ end
18
+ # rubocop:enable Layout/LineLength
19
+
20
+ private
21
+
22
+ attr_reader :order, :refund
23
+
24
+ def customer_email
25
+ order.email || order.user.email
26
+ end
27
+
28
+ def order_url
29
+ edit_admin_order_url(id: order.number, host: Rails.application.routes.default_url_options[:host])
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gladly
4
+ module Events
5
+ module Order
6
+ class Placed < Gladly::Events::Order::Base
7
+ private
8
+
9
+ def payload
10
+ {
11
+ customer: {
12
+ emailAddress: customer_email
13
+ },
14
+ content: {
15
+ type: 'CUSTOMER_ACTIVITY',
16
+ title: "Order #{order.number}",
17
+ body: body_content,
18
+ activityType: 'EMAIL',
19
+ sourceName: 'Spree',
20
+ link: {
21
+ url: order_url,
22
+ text: 'Link to Order - Spree'
23
+ }
24
+ }
25
+ }
26
+ end
27
+
28
+ def body_content
29
+ [
30
+ "Order Total: #{Spree::Money.new(order.total).to_html}",
31
+ "Item Total: #{Spree::Money.new(order.line_items.map(&:total).sum).to_html}",
32
+ "Adjustment Total: #{Spree::Money.new(order.adjustment_total).to_html}"
33
+ ].join('<br>')
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gladly
4
+ module Events
5
+ module Order
6
+ class Refunded < Gladly::Events::Order::Base
7
+ private
8
+
9
+ def payload
10
+ {
11
+ customer: {
12
+ emailAddress: customer_email
13
+ },
14
+ content: {
15
+ type: 'CUSTOMER_ACTIVITY',
16
+ title: "Order Adjusted #{order.number}",
17
+ body: body_content,
18
+ activityType: 'EMAIL',
19
+ sourceName: 'Spree',
20
+ link: {
21
+ url: order_url,
22
+ text: 'Link to Order - Spree'
23
+ }
24
+ }
25
+ }
26
+ end
27
+
28
+ def body_content
29
+ [
30
+ "Amount Adjusted: #{Spree::Money.new(refund.amount).to_html}",
31
+ "Adjustment Reason: #{refund.reason&.name}"
32
+ ].join('<br>')
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -15,4 +15,9 @@ SpreeGladly.setup do |config|
15
15
  # Setting this value to `0` disables the threshold validation.
16
16
  # Default is `0`.
17
17
  # config.signing_threshold = 5.minutes
18
+
19
+ # API CONFIG
20
+ config.gladly_api_username = ''
21
+ config.gladly_api_key = ''
22
+ config.gladly_api_base_url = ''
18
23
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SpreeGladly
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_gladly
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Upsidelab.io
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-11 00:00:00.000000000 Z
11
+ date: 2021-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree_core
@@ -135,6 +135,8 @@ files:
135
135
  - app/finders/customer/guest/detailed_finder.rb
136
136
  - app/finders/customer/registered/basic_finder.rb
137
137
  - app/finders/customer/registered/detailed_finder.rb
138
+ - app/models/spree/order_decorator.rb
139
+ - app/models/spree/refund_decorator.rb
138
140
  - app/models/spree_gladly/configuration.rb
139
141
  - app/overrides/add_gladly_admin_menu_links.rb
140
142
  - app/presenters/customer/address_presenter.rb
@@ -152,6 +154,12 @@ files:
152
154
  - app/services/auth/request_normalizer.rb
153
155
  - app/services/auth/signature_validator.rb
154
156
  - app/services/auth/time_header.rb
157
+ - app/services/gladly/api/client.rb
158
+ - app/services/gladly/api/conversations/create.rb
159
+ - app/services/gladly/api/error_handling.rb
160
+ - app/services/gladly/events/order/base.rb
161
+ - app/services/gladly/events/order/placed.rb
162
+ - app/services/gladly/events/order/refunded.rb
155
163
  - app/validators/lookup_validator.rb
156
164
  - app/validators/validation_result.rb
157
165
  - app/views/spree/admin/gladly_settings/edit.html.erb
@@ -194,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
202
  - !ruby/object:Gem::Version
195
203
  version: '0'
196
204
  requirements: []
197
- rubygems_version: 3.0.9
205
+ rubygems_version: 3.2.17
198
206
  signing_key:
199
207
  specification_version: 4
200
208
  summary: Spree Connector API