spree_gladly 1.0.0 → 1.1.0
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 +4 -4
- data/.travis.yml +13 -5
- data/README.md +90 -1
- data/app/models/spree/order_decorator.rb +16 -0
- data/app/models/spree/refund_decorator.rb +11 -0
- data/app/models/spree_gladly/configuration.rb +13 -1
- data/app/services/gladly/api/client.rb +66 -0
- data/app/services/gladly/api/conversations/create.rb +17 -0
- data/app/services/gladly/api/error_handling.rb +21 -0
- data/app/services/gladly/events/order/base.rb +34 -0
- data/app/services/gladly/events/order/placed.rb +38 -0
- data/app/services/gladly/events/order/refunded.rb +37 -0
- data/lib/generators/spree_gladly/install/templates/config/initializers/spree_gladly.rb +5 -0
- data/lib/spree_gladly/version.rb +1 -1
- metadata +11 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 838966d87c3ac9621653856b60d79a1b55b318efaa16a1bb532c255f48982d1f
|
4
|
+
data.tar.gz: 1243ce174014bc76281167c3b9a9ed7d5b0fc0620dbca2132661d5e367cad8f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
@@ -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,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
|
data/lib/spree_gladly/version.rb
CHANGED
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.
|
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
|
+
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.
|
205
|
+
rubygems_version: 3.2.17
|
198
206
|
signing_key:
|
199
207
|
specification_version: 4
|
200
208
|
summary: Spree Connector API
|