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 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