solidus_bactracs 3.0.0 → 3.1.2
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/.gem_release.yml +2 -2
- data/.github/CODEOWNERS +54 -0
- data/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +3 -0
- data/.github/workflows/release.yml +50 -0
- data/.gitignore +0 -2
- data/.rubocop_todo.yml +3 -3
- data/.ruby-version +1 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +10 -1
- data/PULL_REQUEST_TEMPLATE.md +3 -0
- data/README.md +7 -6
- data/Rakefile +1 -0
- data/app/assets/javascripts/spree/backend/{solidus_backtracs.js → solidus_bactracs.js} +0 -0
- data/app/assets/javascripts/spree/frontend/{solidus_backtracs.js → solidus_bactracs.js} +0 -0
- data/app/assets/stylesheets/spree/backend/{solidus_backtracs.css → solidus_bactracs.css} +0 -0
- data/app/assets/stylesheets/spree/frontend/{solidus_backtracs.css → solidus_bactracs.css} +0 -0
- data/app/controllers/spree/{backtracs_controller.rb → bactracs_controller.rb} +9 -9
- data/app/decorators/models/solidus_bactracs/spree/shipment_decorator.rb +46 -0
- data/app/helpers/{solidus_backtracs → solidus_bactracs}/export_helper.rb +2 -2
- data/app/jobs/{solidus_backtracs → solidus_bactracs}/api/schedule_shipment_syncs_job.rb +7 -7
- data/app/jobs/{solidus_backtracs → solidus_bactracs}/api/sync_shipment_job.rb +1 -1
- data/app/jobs/{solidus_backtracs → solidus_bactracs}/api/sync_shipments_job.rb +7 -3
- data/app/queries/{solidus_backtracs → solidus_bactracs}/shipment/between_query.rb +1 -1
- data/app/queries/{solidus_backtracs → solidus_bactracs}/shipment/exportable_query.rb +3 -3
- data/app/queries/{solidus_backtracs → solidus_bactracs}/shipment/pending_api_sync_query.rb +6 -6
- data/app/views/spree/{backtracs → bactracs}/export.xml.builder +5 -5
- data/app/workers/verify_bactracs_sync_worker.rb +14 -0
- data/bin/console +1 -1
- data/bin/rails-engine +1 -1
- data/bin/sandbox +1 -1
- data/config/routes.rb +2 -2
- data/db/migrate/20210220093010_add_bactracs_api_sync_fields.rb +11 -0
- data/db/migrate/20220701000001_bactracs_typo_correction.rb +10 -0
- data/db/migrate/20220704144504_rename_bactracs_columns_in_spree_shipment.rb +10 -0
- data/lib/bactracs_service.rb +66 -0
- data/lib/generators/{solidus_backtracs → solidus_bactracs}/install/install_generator.rb +3 -3
- data/lib/generators/{solidus_backtracs → solidus_bactracs}/install/templates/initializer.rb +42 -12
- data/lib/solidus_backtracs/version.rb +1 -1
- data/lib/{solidus_backtracs → solidus_bactracs}/api/batch_syncer.rb +5 -5
- data/lib/{solidus_backtracs → solidus_bactracs}/api/client.rb +4 -4
- data/lib/{solidus_backtracs → solidus_bactracs}/api/rate_limited_error.rb +1 -1
- data/lib/{solidus_backtracs → solidus_bactracs}/api/request_error.rb +1 -1
- data/lib/solidus_bactracs/api/request_runner.rb +135 -0
- data/lib/{solidus_backtracs → solidus_bactracs}/api/shipment_serializer.rb +28 -27
- data/lib/{solidus_backtracs → solidus_bactracs}/api/threshold_verifier.rb +6 -6
- data/lib/{solidus_backtracs → solidus_bactracs}/configuration.rb +4 -4
- data/lib/{solidus_backtracs → solidus_bactracs}/engine.rb +2 -2
- data/lib/{solidus_backtracs → solidus_bactracs}/errors.rb +1 -1
- data/lib/{solidus_backtracs → solidus_bactracs}/shipment_notice.rb +2 -2
- data/lib/{solidus_backtracs → solidus_bactracs}/testing_support/factories.rb +0 -0
- data/lib/solidus_bactracs/version.rb +5 -0
- data/lib/solidus_bactracs.rb +16 -0
- data/lib/tasks/solidus_bactracs.rake +16 -0
- data/solidus_bactracs.gemspec +3 -2
- data/spec/controllers/spree/{backtracs_controller_spec.rb → bactracs_controller_spec.rb} +9 -9
- data/spec/fixtures/{backtracs_xml_schema.xsd → bactracs_xml_schema.xsd} +0 -0
- data/spec/jobs/{solidus_backtracs → solidus_bactracs}/api/schedule_shipment_syncs_job_spec.rb +5 -5
- data/spec/jobs/{solidus_backtracs → solidus_bactracs}/api/sync_shipments_job_spec.rb +10 -10
- data/spec/lib/{solidus_backtracs → solidus_bactracs}/api/batch_syncer_spec.rb +28 -28
- data/spec/lib/{solidus_backtracs → solidus_bactracs}/api/client_spec.rb +10 -10
- data/spec/lib/{solidus_backtracs → solidus_bactracs}/api/rate_limited_error_spec.rb +1 -1
- data/spec/lib/{solidus_backtracs → solidus_bactracs}/api/request_error_spec.rb +1 -1
- data/spec/lib/{solidus_backtracs → solidus_bactracs}/api/request_runner_spec.rb +3 -3
- data/spec/lib/{solidus_backtracs → solidus_bactracs}/api/shipment_serializer_spec.rb +1 -1
- data/spec/lib/{solidus_backtracs → solidus_bactracs}/api/threshold_verifier_spec.rb +9 -9
- data/spec/lib/{solidus_backtracs → solidus_bactracs}/shipment_notice_spec.rb +4 -4
- data/spec/lib/solidus_bactracs_spec.rb +9 -0
- data/spec/models/spree/shipment_spec.rb +2 -2
- data/spec/queries/{solidus_backtracs → solidus_bactracs}/shipment/between_query_spec.rb +1 -1
- data/spec/queries/{solidus_backtracs → solidus_bactracs}/shipment/exportable_query_spec.rb +1 -1
- data/spec/queries/{solidus_backtracs → solidus_bactracs}/shipment/pending_api_sync_query_spec.rb +4 -4
- data/spec/spec_helper.rb +2 -2
- data/spec/support/configuration_helper.rb +1 -1
- metadata +81 -68
- data/app/decorators/models/solidus_backtracs/spree/shipment_decorator.rb +0 -33
- data/db/migrate/20210220093010_add_backtracs_api_sync_fields.rb +0 -8
- data/lib/solidus_backtracs/api/request_runner.rb +0 -109
- data/lib/solidus_backtracs.rb +0 -16
- data/spec/lib/solidus_backtracs_spec.rb +0 -9
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class RenameBactracsColumnsInSpreeShipment < ActiveRecord::Migration[5.2]
|
4
|
+
def change
|
5
|
+
if ( ActiveRecord::Base.connection.column_exists?(:spree_shipments, :backtracs_sync_verified_at) &&
|
6
|
+
!ActiveRecord::Base.connection.column_exists?(:spree_shipments, :bactracs_sync_verified_at))
|
7
|
+
rename_column :spree_shipments, :backtracs_sync_verified_at, :bactracs_sync_verified_at
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "uri"
|
4
|
+
require "net/http"
|
5
|
+
|
6
|
+
class BactracsService
|
7
|
+
attr_accessor :token
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@username = SolidusBactracs.configuration.authentication_username
|
11
|
+
@password = SolidusBactracs.configuration.authentication_password
|
12
|
+
@runner = SolidusBactracs::Api::RequestRunner.new
|
13
|
+
# Authenticate account
|
14
|
+
authenticate!
|
15
|
+
end
|
16
|
+
|
17
|
+
def rma_was_synced?(shipment)
|
18
|
+
if @token.present?
|
19
|
+
|
20
|
+
response =
|
21
|
+
@runner.call(
|
22
|
+
method: :post,
|
23
|
+
path: "/webservices/rma/rmaservice.asmx?op=Read",
|
24
|
+
params:
|
25
|
+
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n
|
26
|
+
<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n
|
27
|
+
<soap:Body>
|
28
|
+
<Read xmlns=\"http://bactracs.andlor.com/rmaservice\">\n
|
29
|
+
<sGuid>#{@token}</sGuid>\n
|
30
|
+
<sRMANumber>#{shipment.number}</sRMANumber>\n
|
31
|
+
</Read>\n
|
32
|
+
</soap:Body>\n
|
33
|
+
</soap:Envelope>"
|
34
|
+
)
|
35
|
+
|
36
|
+
if response
|
37
|
+
return response.dig("Envelope", "Body", "ReadResponse", "ReadResult", "oRMA").present? rescue false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
return false
|
42
|
+
|
43
|
+
rescue => e
|
44
|
+
Rails.logger.error({ message: e.message.to_s, file: "bactracs_service.rb" })
|
45
|
+
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def authenticate!
|
52
|
+
|
53
|
+
response =
|
54
|
+
@runner.call(
|
55
|
+
method: :get,
|
56
|
+
path: "/webservices/user/Authentication.asmx/Login?sUserName=#{@username}&sPassword=#{@password}"
|
57
|
+
)
|
58
|
+
|
59
|
+
if response.dig("AuthenticationResponse", "Result") == "true"
|
60
|
+
@token = response.dig("AuthenticationResponse", "Message")
|
61
|
+
end
|
62
|
+
|
63
|
+
rescue => e
|
64
|
+
Rails.logger.error({ message: "#{e.message}, file: bactracs_service.rb" })
|
65
|
+
end
|
66
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module SolidusBactracs
|
4
4
|
module Generators
|
5
5
|
class InstallGenerator < Rails::Generators::Base
|
6
6
|
class_option :auto_run_migrations, type: :boolean, default: false
|
7
7
|
source_root File.expand_path('templates', __dir__)
|
8
8
|
|
9
9
|
def copy_initializer
|
10
|
-
template 'initializer.rb', 'config/initializers/
|
10
|
+
template 'initializer.rb', 'config/initializers/solidus_bactracs.rb'
|
11
11
|
end
|
12
12
|
|
13
13
|
def add_migrations
|
14
|
-
run 'bin/rails railties:install:migrations FROM=
|
14
|
+
run 'bin/rails railties:install:migrations FROM=solidus_bactracs'
|
15
15
|
end
|
16
16
|
|
17
17
|
def run_migrations
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
SolidusBactracs.configure do |config|
|
4
4
|
# Choose between Grams, Ounces or Pounds.
|
5
5
|
config.weight_units = "Grams"
|
6
6
|
|
7
|
-
# Capture payment when
|
7
|
+
# Capture payment when Bactracs notifies a shipping label creation.
|
8
8
|
# Set this to `true` and `Spree::Config.require_payment_to_ship` to `false` if you
|
9
9
|
# want to charge your customers at the time of shipment.
|
10
10
|
config.capture_at_notification = false
|
@@ -13,8 +13,8 @@ SolidusBacktracs.configure do |config|
|
|
13
13
|
config.api_base = ENV['BACKTRACS_API_BASE'] || 'https://bactracstest.andlor.com'
|
14
14
|
config.api_retries = ENV['BACKTRACS_API_RETRIES'] || 3
|
15
15
|
|
16
|
-
#
|
17
|
-
# Set the username and password you desire for
|
16
|
+
# Bactracs expects the endpoint to be protected by HTTP Basic Auth.
|
17
|
+
# Set the username and password you desire for Bactracs to use.
|
18
18
|
config.webhook_username = "smoking_jay_cutler"
|
19
19
|
config.webhook_password = "my-awesome-password"
|
20
20
|
|
@@ -42,14 +42,14 @@ SolidusBacktracs.configure do |config|
|
|
42
42
|
####### XML integration
|
43
43
|
# Only uncomment these lines if you're going to use the XML integration.
|
44
44
|
|
45
|
-
# Export canceled shipments to
|
45
|
+
# Export canceled shipments to Bactracs
|
46
46
|
# Set this to `true` if you want canceled shipments included in the endpoint.
|
47
47
|
# config.export_canceled_shipments = false
|
48
48
|
|
49
49
|
# You can customize the class used to receive notifications from the POST request
|
50
50
|
# Make sure it has a class method `from_payload` which receives the notification hash
|
51
51
|
# and an instance method `apply`
|
52
|
-
# config.shipment_notice_class = '
|
52
|
+
# config.shipment_notice_class = 'SolidusBactracs::ShipmentNotice'
|
53
53
|
|
54
54
|
####### API integration
|
55
55
|
# Only uncomment these lines if you're going to use the API integration.
|
@@ -58,21 +58,21 @@ SolidusBacktracs.configure do |config|
|
|
58
58
|
# that responds to `#call`. At the very least, you'll need to uncomment the
|
59
59
|
# following lines and customize your store ID.
|
60
60
|
# config.api_shipment_serializer = proc do |shipment|
|
61
|
-
#
|
61
|
+
# SolidusBactracs::Api::ShipmentSerializer.new(store_id: '12345678').call(shipment)
|
62
62
|
# end
|
63
63
|
|
64
|
-
# Override the logic used to match a
|
64
|
+
# Override the logic used to match a Bactracs order to a shipment from a
|
65
65
|
# given collection. This can be useful when you override the default serializer
|
66
66
|
# and change the logic used to generate the order number.
|
67
|
-
# config.api_shipment_matcher = proc do |
|
68
|
-
# shipments.find { |shipment| shipment.number ==
|
67
|
+
# config.api_shipment_matcher = proc do |bactracs_order, shipments|
|
68
|
+
# shipments.find { |shipment| shipment.number == bactracs_order['orderNumber'] }
|
69
69
|
# end
|
70
70
|
|
71
|
-
# API key and secret for accessing the
|
71
|
+
# API key and secret for accessing the Bactracs API.
|
72
72
|
# config.api_key = "api-key"
|
73
73
|
# config.api_secret = "api-secret"
|
74
74
|
|
75
|
-
# Number of shipments to import into
|
75
|
+
# Number of shipments to import into Bactracs at once.
|
76
76
|
# If unsure, leave this set to 100, which is the maximum
|
77
77
|
# number of shipments that can be imported at once.
|
78
78
|
config.api_batch_size = 100
|
@@ -90,3 +90,33 @@ SolidusBacktracs.configure do |config|
|
|
90
90
|
Sentry.capture_exception(error, extra: context)
|
91
91
|
}
|
92
92
|
end
|
93
|
+
|
94
|
+
class Spree
|
95
|
+
class Shipment
|
96
|
+
def normalize_valid_variants_from_bundles
|
97
|
+
self.line_items.reduce([]) do |variants, line_item|
|
98
|
+
if line_item.product.respond_to?(:assembly?) && line_item.product.assembly?
|
99
|
+
variants += line_item.product.parts.reject(&:invalid_part?)
|
100
|
+
else
|
101
|
+
variants << line_item.variant
|
102
|
+
end
|
103
|
+
variants
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def invalid_part?(part)
|
110
|
+
part.product
|
111
|
+
.product_properties
|
112
|
+
.where(property_id: default_property_id)
|
113
|
+
.present?
|
114
|
+
end
|
115
|
+
|
116
|
+
def default_property_id
|
117
|
+
::Spree::Property.find_by(
|
118
|
+
name: SolidusBactracs.config.default_property_name,
|
119
|
+
)&.id
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module SolidusBactracs
|
4
4
|
module Api
|
5
5
|
class BatchSyncer
|
6
6
|
class << self
|
7
7
|
def from_config
|
8
8
|
new(
|
9
|
-
client:
|
10
|
-
shipment_matcher:
|
9
|
+
client: SolidusBactracs::Api::Client.from_config,
|
10
|
+
shipment_matcher: SolidusBactracs.config.api_shipment_matcher,
|
11
11
|
)
|
12
12
|
end
|
13
13
|
end
|
@@ -24,7 +24,7 @@ module SolidusBacktracs
|
|
24
24
|
response = client.bulk_create_orders(shipments)
|
25
25
|
rescue RateLimitedError => e
|
26
26
|
::Spree::Event.fire(
|
27
|
-
'
|
27
|
+
'solidus_bactracs.api.rate_limited',
|
28
28
|
shipments: shipments,
|
29
29
|
error: e,
|
30
30
|
)
|
@@ -32,7 +32,7 @@ module SolidusBacktracs
|
|
32
32
|
raise e
|
33
33
|
rescue RequestError => e
|
34
34
|
::Spree::Event.fire(
|
35
|
-
'
|
35
|
+
'solidus_bactracs.api.sync_errored',
|
36
36
|
shipments: shipments,
|
37
37
|
error: e,
|
38
38
|
)
|
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module SolidusBactracs
|
4
4
|
module Api
|
5
5
|
class Client
|
6
6
|
class << self
|
7
7
|
def from_config
|
8
8
|
new(
|
9
9
|
request_runner: RequestRunner.new,
|
10
|
-
error_handler:
|
11
|
-
shipment_serializer:
|
10
|
+
error_handler: SolidusBactracs.config.error_handler,
|
11
|
+
shipment_serializer: SolidusBactracs.config.api_shipment_serializer,
|
12
12
|
)
|
13
13
|
end
|
14
14
|
end
|
@@ -23,7 +23,7 @@ module SolidusBacktracs
|
|
23
23
|
|
24
24
|
def bulk_create_orders(shipments)
|
25
25
|
shipments.each do |shipment|
|
26
|
-
|
26
|
+
SolidusBactracs::Api::SyncShipmentJob.perform_now(
|
27
27
|
shipment_id: shipment.id,
|
28
28
|
error_handler: @error_handler,
|
29
29
|
shipment_serializer: @shipment_serializer,
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "uri"
|
3
|
+
require "net/http"
|
4
|
+
|
5
|
+
module SolidusBactracs
|
6
|
+
module Api
|
7
|
+
class RequestRunner
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@username = SolidusBactracs.configuration.authentication_username
|
11
|
+
@password = SolidusBactracs.configuration.authentication_password
|
12
|
+
@api_base = SolidusBactracs.configuration.api_base
|
13
|
+
@retries = SolidusBactracs.configuration.api_retries
|
14
|
+
end
|
15
|
+
|
16
|
+
def authenticated_call(method: nil, path: nil, serializer: nil, shipment: nil, count: 0)
|
17
|
+
if count <= @retries
|
18
|
+
sguid = authenticate! rescue nil
|
19
|
+
|
20
|
+
if !sguid.presence
|
21
|
+
clear_cache
|
22
|
+
count += 1
|
23
|
+
self.authenticated_call(method: :post, path: '/webservices/rma/rmaservice.asmx', serializer: serializer, shipment: shipment, count: count)
|
24
|
+
else
|
25
|
+
params = serializer.call(shipment, sguid)
|
26
|
+
|
27
|
+
rma_response = call(method: :post, path: path, params: params)
|
28
|
+
if create_rma_success?(rma_response)
|
29
|
+
Rails.logger.info({ event: 'success CreateRMA', rma: shipment.number, response: parse_rma_creation_response(rma_response, "Message")})
|
30
|
+
shipment_synced(shipment)
|
31
|
+
return true
|
32
|
+
elsif rma_exists?(rma_response)
|
33
|
+
return false
|
34
|
+
else
|
35
|
+
clear_cache
|
36
|
+
count += 1
|
37
|
+
Rails.logger.warn({ event: 'bactracs failed CreateRMA', error: parse_rma_creation_response(rma_response, "Message")})
|
38
|
+
self.authenticated_call(method: :post, path: '/webservices/rma/rmaservice.asmx', serializer: serializer, shipment: shipment, count: count)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
else
|
42
|
+
shipment_sync_failed(shipment)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def call(method: nil, path: nil, params: {})
|
48
|
+
doc = {}
|
49
|
+
if params.present?
|
50
|
+
doc = Nokogiri::XML(params.to_s)
|
51
|
+
end
|
52
|
+
response = HTTParty.send(
|
53
|
+
method,
|
54
|
+
URI.join(@api_base, path),
|
55
|
+
body: doc.to_xml,
|
56
|
+
http_proxyaddr: SolidusBactracs.configuration.proxy_address,
|
57
|
+
http_proxyport: SolidusBactracs.configuration.proxy_port,
|
58
|
+
http_proxyuser: SolidusBactracs.configuration.proxy_username,
|
59
|
+
http_proxypass: SolidusBactracs.configuration.proxy_password,
|
60
|
+
headers: {
|
61
|
+
'Content-Type' => 'text/xml',
|
62
|
+
},
|
63
|
+
)
|
64
|
+
|
65
|
+
case response.code.to_s
|
66
|
+
when /2\d{2}/
|
67
|
+
response
|
68
|
+
when '429'
|
69
|
+
raise RateLimitedError.from_response(response)
|
70
|
+
else
|
71
|
+
raise RequestError.from_response(response)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def clear_cache
|
76
|
+
Rails.cache.delete('bactracks_cache_key')
|
77
|
+
@response = nil
|
78
|
+
end
|
79
|
+
|
80
|
+
def authenticate!()
|
81
|
+
unless @username.present? || @password.present? || @api_base.present?
|
82
|
+
raise "Credentials not defined for Authentication"
|
83
|
+
end
|
84
|
+
|
85
|
+
@response = Rails.cache.fetch("backtracks_cache_key", expires_in: 1.hour, skip_nil: true) do
|
86
|
+
self.call(method: :get, path: "/webservices/user/Authentication.asmx/Login?sUserName=#{@username}&sPassword=#{@password}")
|
87
|
+
end
|
88
|
+
|
89
|
+
raise RequestError.from_response(@response) unless @response # just try again for @retries?
|
90
|
+
if "false" == parse_authentication_response(@response, "Result")
|
91
|
+
Rails.logger.warn({ event: 'bactracs auth failed', error: parse_authentication_response(@response, "Message")})
|
92
|
+
raise RequestError.from_response(@response)
|
93
|
+
end
|
94
|
+
sguid = parse_authentication_response(@response, "Message")
|
95
|
+
|
96
|
+
return sguid
|
97
|
+
end
|
98
|
+
|
99
|
+
def parse_authentication_response(response, field)
|
100
|
+
response.dig("AuthenticationResponse", field)
|
101
|
+
end
|
102
|
+
|
103
|
+
def parse_rma_creation_response(response, field = "Result")
|
104
|
+
response.dig("Envelope", "Body", "CreateNewResponse", "CreateNewResult", field).to_s.downcase
|
105
|
+
end
|
106
|
+
|
107
|
+
def create_rma_success?(response)
|
108
|
+
parse_rma_creation_response(response) == 'true' && parse_rma_creation_response(response, "Message") == "ok"
|
109
|
+
end
|
110
|
+
|
111
|
+
def rma_exists?(response)
|
112
|
+
if parse_rma_creation_response(response, "Message").match(/rma .* already exists/)
|
113
|
+
Rails.logger.warn({ event: 'bactracs failed CreateRMA', error: parse_rma_creation_response(rma_response, "Message")})
|
114
|
+
return true
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def shipment_synced(shipment)
|
119
|
+
shipment.update_column(:bactracs_synced_at, Time.zone.now)
|
120
|
+
|
121
|
+
::Spree::Event.fire(
|
122
|
+
'solidus_bactracs.api.sync_completed',
|
123
|
+
shipment: shipment
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
def shipment_sync_failed(shipment)
|
128
|
+
::Spree::Event.fire(
|
129
|
+
'solidus_bactracs.api.sync_failed',
|
130
|
+
shipment: shipment
|
131
|
+
)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -1,20 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module SolidusBactracs
|
4
4
|
module Api
|
5
5
|
class ShipmentSerializer
|
6
6
|
|
7
7
|
def initialize(shipment:)
|
8
8
|
@shipment = shipment
|
9
|
-
@config =
|
10
|
-
@property_id = ::Spree::Property.find_by(name:
|
9
|
+
@config = SolidusBactracs.config
|
10
|
+
@property_id = ::Spree::Property.find_by(name: SolidusBactracs.config.default_property_name)&.id
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(sguid: nil)
|
14
14
|
order = @shipment.order
|
15
15
|
user = @shipment.user
|
16
16
|
|
17
|
-
xml = Builder::XmlMarkup.new
|
17
|
+
xml = Builder::XmlMarkup.new
|
18
18
|
xml.instruct!(:xml, :encoding => "UTF-8")
|
19
19
|
|
20
20
|
xml.soap(:Envelope, {"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/"}) do
|
@@ -24,28 +24,28 @@ module SolidusBacktracs
|
|
24
24
|
xml.NewRMA {
|
25
25
|
xml.RMANumber @shipment.number
|
26
26
|
xml.RMATypeName @config.default_rma_type
|
27
|
-
xml.RMASubTypeName
|
28
|
-
xml.CustomerRef
|
29
|
-
xml.InboundShippingPriority
|
27
|
+
xml.RMASubTypeName
|
28
|
+
xml.CustomerRef
|
29
|
+
xml.InboundShippingPriority
|
30
30
|
xml.InboundTrackingNumber @shipment.tracking
|
31
31
|
|
32
32
|
xml.Ship {
|
33
33
|
xml.Carrier @config.default_carrier
|
34
34
|
xml.ShipMethod @config.default_ship_method
|
35
|
-
xml.ShipDate @shipment.created_at.strftime(
|
35
|
+
xml.ShipDate @shipment.created_at.strftime(SolidusBactracs::ExportHelper::BACTRACS_DATE_FORMAT)
|
36
36
|
xml.TrackingNumber @shipment.tracking
|
37
37
|
xml.SerialNumber @shipment.number
|
38
|
-
xml.Ud1
|
38
|
+
xml.Ud1
|
39
39
|
}
|
40
40
|
xml.Customer {
|
41
|
-
|
42
|
-
|
41
|
+
SolidusBactracs::ExportHelper.bactracs_address(xml, order, :ship)
|
42
|
+
SolidusBactracs::ExportHelper.bactracs_address(xml, order, :bill)
|
43
43
|
}
|
44
44
|
xml.Rep {
|
45
|
-
xml.Code
|
45
|
+
xml.Code
|
46
46
|
xml.Name user.full_name
|
47
47
|
xml.Email user.email
|
48
|
-
}
|
48
|
+
}
|
49
49
|
|
50
50
|
xml.RMALines {
|
51
51
|
@shipment.line_items.each do |line|
|
@@ -60,39 +60,40 @@ module SolidusBacktracs
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
}
|
63
|
-
xml.OrderDate order.completed_at.strftime(
|
64
|
-
xml.CreateDate @shipment.created_at.strftime(
|
63
|
+
xml.OrderDate order.completed_at.strftime(SolidusBactracs::ExportHelper::BACTRACS_DATE_FORMAT)
|
64
|
+
xml.CreateDate @shipment.created_at.strftime(SolidusBactracs::ExportHelper::BACTRACS_DATE_FORMAT)
|
65
65
|
xml.Status @config.default_status
|
66
66
|
xml.RMAId @shipment.id
|
67
67
|
xml.ClientGuid
|
68
68
|
}
|
69
69
|
end
|
70
|
-
end
|
70
|
+
end
|
71
71
|
end
|
72
|
+
Rails.logger.info(xml.to_s)
|
72
73
|
xml
|
73
74
|
end
|
74
75
|
|
75
76
|
def line_items_xml(xml: nil, line_item: nil, variant: nil, order: nil)
|
76
|
-
shipment_notice = @shipment.shipment_notice
|
77
|
+
shipment_notice = @shipment.shipment_notice
|
77
78
|
xml.RMALine {
|
78
79
|
xml.DFItem find_sku_variant(variant)
|
79
80
|
xml.DFModelNum find_sku_variant(variant)
|
80
|
-
xml.DFCategory
|
81
|
-
xml.DFCategoryDescription
|
81
|
+
xml.DFCategory
|
82
|
+
xml.DFCategoryDescription
|
82
83
|
xml.DFQuantity line_item.quantity
|
83
84
|
xml.DFUnitPrice line_item.price
|
84
|
-
xml.DFSerialNumbers
|
85
|
-
xml.Ud1s
|
86
|
-
xml.CurrentWarranties
|
87
|
-
xml.DFComments
|
85
|
+
xml.DFSerialNumbers
|
86
|
+
xml.Ud1s
|
87
|
+
xml.CurrentWarranties
|
88
|
+
xml.DFComments
|
88
89
|
xml.DFStatus @shipment.state
|
89
|
-
xml.PurchaseDate order.completed_at.strftime(
|
90
|
+
xml.PurchaseDate order.completed_at.strftime(SolidusBactracs::ExportHelper::BACTRACS_DATE_FORMAT)
|
90
91
|
xml.ServiceProvider shipment_notice&.service
|
91
|
-
xml.WarrantyRepair
|
92
|
-
xml.RMALineTest
|
92
|
+
xml.WarrantyRepair
|
93
|
+
xml.RMALineTest
|
93
94
|
xml.InboundShipWeight variant.weight.to_f
|
94
95
|
xml.RPLocation @config.default_rp_location
|
95
|
-
}
|
96
|
+
}
|
96
97
|
end
|
97
98
|
|
98
99
|
def find_sku_variant(variant)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module SolidusBactracs
|
4
4
|
module Api
|
5
5
|
class ThresholdVerifier
|
6
6
|
class << self
|
@@ -13,14 +13,14 @@ module SolidusBacktracs
|
|
13
13
|
private
|
14
14
|
|
15
15
|
def shipment_requires_creation?(shipment)
|
16
|
-
shipment.
|
17
|
-
Time.zone.now - shipment.order.updated_at <
|
16
|
+
shipment.bactracs_synced_at.nil? &&
|
17
|
+
Time.zone.now - shipment.order.updated_at < SolidusBactracs.config.api_sync_threshold
|
18
18
|
end
|
19
19
|
|
20
20
|
def shipment_requires_update?(shipment)
|
21
|
-
shipment.
|
22
|
-
shipment.
|
23
|
-
Time.zone.now - shipment.order.updated_at <
|
21
|
+
shipment.bactracs_synced_at &&
|
22
|
+
shipment.bactracs_synced_at < shipment.order.updated_at &&
|
23
|
+
Time.zone.now - shipment.order.updated_at < SolidusBactracs.config.api_sync_threshold
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module SolidusBactracs
|
4
4
|
class Configuration
|
5
5
|
attr_accessor(
|
6
6
|
:webhook_username,
|
@@ -41,11 +41,11 @@ module SolidusBacktracs
|
|
41
41
|
@error_handler = ->(_error, _extra = {}) {
|
42
42
|
Rails.logger.error "#{error.inspect} (#{extra.inspect})"
|
43
43
|
}
|
44
|
-
@api_shipment_matcher = proc do |
|
45
|
-
shipments.find { |shipment| shipment.number ==
|
44
|
+
@api_shipment_matcher = proc do |bactracs_order, shipments|
|
45
|
+
shipments.find { |shipment| shipment.number == bactracs_order['orderNumber'] }
|
46
46
|
end
|
47
47
|
|
48
|
-
@shipment_notice_class = '
|
48
|
+
@shipment_notice_class = 'SolidusBactracs::ShipmentNotice'
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -3,13 +3,13 @@
|
|
3
3
|
require 'solidus_core'
|
4
4
|
require 'solidus_support'
|
5
5
|
|
6
|
-
module
|
6
|
+
module SolidusBactracs
|
7
7
|
class Engine < Rails::Engine
|
8
8
|
include SolidusSupport::EngineExtensions
|
9
9
|
|
10
10
|
isolate_namespace ::Spree
|
11
11
|
|
12
|
-
engine_name '
|
12
|
+
engine_name 'solidus_bactracs'
|
13
13
|
|
14
14
|
# use rspec for tests
|
15
15
|
config.generators do |g|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module SolidusBactracs
|
4
4
|
class ShipmentNotice
|
5
5
|
attr_reader :shipment_number, :shipment_tracking
|
6
6
|
|
@@ -38,7 +38,7 @@ module SolidusBacktracs
|
|
38
38
|
def process_payment
|
39
39
|
return if shipment.order.paid?
|
40
40
|
|
41
|
-
unless
|
41
|
+
unless SolidusBactracs.configuration.capture_at_notification
|
42
42
|
raise OrderNotPaidError, shipment.order
|
43
43
|
end
|
44
44
|
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'httparty'
|
4
|
+
|
5
|
+
require 'solidus_bactracs/api/batch_syncer'
|
6
|
+
require 'solidus_bactracs/api/request_runner'
|
7
|
+
require 'solidus_bactracs/api/client'
|
8
|
+
require 'solidus_bactracs/api/request_error'
|
9
|
+
require 'solidus_bactracs/api/rate_limited_error'
|
10
|
+
require 'solidus_bactracs/api/shipment_serializer'
|
11
|
+
require 'solidus_bactracs/api/threshold_verifier'
|
12
|
+
require 'solidus_bactracs/configuration'
|
13
|
+
require 'solidus_bactracs/errors'
|
14
|
+
require 'solidus_bactracs/shipment_notice'
|
15
|
+
require 'solidus_bactracs/version'
|
16
|
+
require 'solidus_bactracs/engine'
|