ship_compliant 0.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 +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +8 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +50 -0
- data/Rakefile +47 -0
- data/cucumber.yml +9 -0
- data/features/add_update_brand.feature +20 -0
- data/features/add_update_product.feature +24 -0
- data/features/check_compliance_of_sales_order_with_address_validations.feature +18 -0
- data/features/commit_sales_order.feature +6 -0
- data/features/get_inventory_details.feature +7 -0
- data/features/get_sales_order_extended.feature +15 -0
- data/features/search_sales_orders.feature +13 -0
- data/features/step_definitions/brand_steps.rb +73 -0
- data/features/step_definitions/commit_sales_order/all_shipments.rb +15 -0
- data/features/step_definitions/compliance_check/available_product_steps.rb +175 -0
- data/features/step_definitions/compliance_check/missing_product_steps.rb +102 -0
- data/features/step_definitions/compliance_check/noncompliant_product.rb +102 -0
- data/features/step_definitions/credential_steps.rb +8 -0
- data/features/step_definitions/inventory_steps.rb +36 -0
- data/features/step_definitions/product_steps.rb +140 -0
- data/features/step_definitions/sales_order_extended_steps.rb +79 -0
- data/features/step_definitions/search_order_steps.rb +87 -0
- data/features/step_definitions/void_order_steps.rb +27 -0
- data/features/support/env.rb +14 -0
- data/features/void_sales_order.feature +11 -0
- data/fixtures/vcr_cassettes/brand_already_exists.yml +1038 -0
- data/fixtures/vcr_cassettes/brand_ignore_existing.yml +1037 -0
- data/fixtures/vcr_cassettes/brand_update_existing.yml +1037 -0
- data/fixtures/vcr_cassettes/brand_valid.yml +1037 -0
- data/fixtures/vcr_cassettes/commit_salesorder_all_shipments.yml +1034 -0
- data/fixtures/vcr_cassettes/compliance_available_product.yml +1075 -0
- data/fixtures/vcr_cassettes/compliance_missing_product.yml +1046 -0
- data/fixtures/vcr_cassettes/compliance_noncompliant_product.yml +1082 -0
- data/fixtures/vcr_cassettes/ignore_existing_product.yml +1035 -0
- data/fixtures/vcr_cassettes/invalid_search_sales_orders.yml +1038 -0
- data/fixtures/vcr_cassettes/inventory_details_for_everything.yml +1037 -0
- data/fixtures/vcr_cassettes/product_already_exists.yml +1036 -0
- data/fixtures/vcr_cassettes/product_invalid_brand.yml +1036 -0
- data/fixtures/vcr_cassettes/product_valid_brand.yml +1035 -0
- data/fixtures/vcr_cassettes/sales_order_extended.yml +1042 -0
- data/fixtures/vcr_cassettes/sales_order_missing.yml +1034 -0
- data/fixtures/vcr_cassettes/search_sales_orders.yml +1039 -0
- data/fixtures/vcr_cassettes/update_product.yml +1035 -0
- data/fixtures/vcr_cassettes/void_order.yml +1033 -0
- data/fixtures/vcr_cassettes/void_voided_order.yml +1034 -0
- data/lib/ship_compliant.rb +62 -0
- data/lib/ship_compliant/add_update_brand.rb +50 -0
- data/lib/ship_compliant/add_update_brand_result.rb +6 -0
- data/lib/ship_compliant/add_update_product.rb +66 -0
- data/lib/ship_compliant/add_update_product_result.rb +6 -0
- data/lib/ship_compliant/address.rb +87 -0
- data/lib/ship_compliant/address/suggested_address.rb +37 -0
- data/lib/ship_compliant/base_result.rb +43 -0
- data/lib/ship_compliant/channel_details.rb +31 -0
- data/lib/ship_compliant/check_compliance.rb +41 -0
- data/lib/ship_compliant/check_compliance_result.rb +95 -0
- data/lib/ship_compliant/client.rb +54 -0
- data/lib/ship_compliant/commit_sales_order.rb +48 -0
- data/lib/ship_compliant/commit_sales_order_result.rb +30 -0
- data/lib/ship_compliant/compliance_rule.rb +30 -0
- data/lib/ship_compliant/configuration.rb +46 -0
- data/lib/ship_compliant/error_result.rb +41 -0
- data/lib/ship_compliant/freight_sales_tax_rate.rb +8 -0
- data/lib/ship_compliant/get_inventory_details.rb +31 -0
- data/lib/ship_compliant/get_inventory_details_result.rb +41 -0
- data/lib/ship_compliant/get_sales_order_extended.rb +23 -0
- data/lib/ship_compliant/get_sales_order_extended_result.rb +65 -0
- data/lib/ship_compliant/inventory_product.rb +95 -0
- data/lib/ship_compliant/order_search.rb +92 -0
- data/lib/ship_compliant/package.rb +13 -0
- data/lib/ship_compliant/product_attributes.rb +98 -0
- data/lib/ship_compliant/product_sales_tax_rate.rb +23 -0
- data/lib/ship_compliant/sales_tax_rate.rb +22 -0
- data/lib/ship_compliant/search_sales_order_summary.rb +30 -0
- data/lib/ship_compliant/search_sales_orders.rb +53 -0
- data/lib/ship_compliant/search_sales_orders_result.rb +106 -0
- data/lib/ship_compliant/shipment.rb +59 -0
- data/lib/ship_compliant/shipment_compliance.rb +28 -0
- data/lib/ship_compliant/shipment_sales_tax_rate.rb +15 -0
- data/lib/ship_compliant/version.rb +3 -0
- data/lib/ship_compliant/void_sales_order.rb +42 -0
- data/lib/ship_compliant/void_sales_order_result.rb +20 -0
- data/ship_compliant.gemspec +33 -0
- data/spec/fixtures/add_update_product.xml +22 -0
- data/spec/fixtures/check_compliance.xml +125 -0
- data/spec/fixtures/coreservice.wsdl +1341 -0
- data/spec/fixtures/search_sales_orders.xml +52 -0
- data/spec/fixtures/void_order_failure.xml +31 -0
- data/spec/fixtures/void_order_success.xml +22 -0
- data/spec/lib/ship_compliant/add_update_brand_result_spec.rb +7 -0
- data/spec/lib/ship_compliant/add_update_brand_spec.rb +58 -0
- data/spec/lib/ship_compliant/add_update_product_result_spec.rb +7 -0
- data/spec/lib/ship_compliant/add_update_product_spec.rb +52 -0
- data/spec/lib/ship_compliant/address/suggested_address_spec.rb +28 -0
- data/spec/lib/ship_compliant/address_spec.rb +123 -0
- data/spec/lib/ship_compliant/base_result_spec.rb +127 -0
- data/spec/lib/ship_compliant/channel_details_spec.rb +40 -0
- data/spec/lib/ship_compliant/check_compliance_result_spec.rb +135 -0
- data/spec/lib/ship_compliant/check_compliance_spec.rb +43 -0
- data/spec/lib/ship_compliant/client_spec.rb +73 -0
- data/spec/lib/ship_compliant/commit_sales_order_result_spec.rb +32 -0
- data/spec/lib/ship_compliant/commit_sales_order_spec.rb +38 -0
- data/spec/lib/ship_compliant/compliance_rule_spec.rb +47 -0
- data/spec/lib/ship_compliant/configuration_spec.rb +47 -0
- data/spec/lib/ship_compliant/error_result_spec.rb +47 -0
- data/spec/lib/ship_compliant/freight_sales_tax_rate_spec.rb +7 -0
- data/spec/lib/ship_compliant/get_inventory_details_result_spec.rb +87 -0
- data/spec/lib/ship_compliant/get_inventory_details_spec.rb +35 -0
- data/spec/lib/ship_compliant/get_sales_order_extended_result_spec.rb +84 -0
- data/spec/lib/ship_compliant/get_sales_order_extended_spec.rb +39 -0
- data/spec/lib/ship_compliant/inventory_product_spec.rb +116 -0
- data/spec/lib/ship_compliant/order_search_spec.rb +21 -0
- data/spec/lib/ship_compliant/package_spec.rb +26 -0
- data/spec/lib/ship_compliant/product_attributes_spec.rb +36 -0
- data/spec/lib/ship_compliant/product_sales_tax_rate_spec.rb +22 -0
- data/spec/lib/ship_compliant/sales_tax_rate_spec.rb +21 -0
- data/spec/lib/ship_compliant/search_sales_order_summary_spec.rb +56 -0
- data/spec/lib/ship_compliant/search_sales_orders_result_spec.rb +121 -0
- data/spec/lib/ship_compliant/search_sales_orders_spec.rb +42 -0
- data/spec/lib/ship_compliant/shipment_compliance_spec.rb +46 -0
- data/spec/lib/ship_compliant/shipment_sales_tax_rate_spec.rb +20 -0
- data/spec/lib/ship_compliant/shipment_spec.rb +106 -0
- data/spec/lib/ship_compliant/void_sales_order_result_spec.rb +7 -0
- data/spec/lib/ship_compliant/void_sales_order_spec.rb +41 -0
- data/spec/spec_helper.rb +50 -0
- metadata +366 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'savon'
|
2
|
+
require 'active_support/all'
|
3
|
+
|
4
|
+
require "ship_compliant/version"
|
5
|
+
require "ship_compliant/configuration"
|
6
|
+
require "ship_compliant/client"
|
7
|
+
require "ship_compliant/base_result"
|
8
|
+
require "ship_compliant/error_result"
|
9
|
+
|
10
|
+
require "ship_compliant/address"
|
11
|
+
require "ship_compliant/address/suggested_address"
|
12
|
+
|
13
|
+
require "ship_compliant/shipment"
|
14
|
+
require "ship_compliant/package"
|
15
|
+
require "ship_compliant/channel_details"
|
16
|
+
|
17
|
+
# SEARCH SALES ORDERS
|
18
|
+
require "ship_compliant/order_search"
|
19
|
+
require "ship_compliant/search_sales_orders"
|
20
|
+
require "ship_compliant/search_sales_orders_result"
|
21
|
+
require "ship_compliant/search_sales_order_summary"
|
22
|
+
|
23
|
+
require "ship_compliant/get_sales_order_extended"
|
24
|
+
require "ship_compliant/get_sales_order_extended_result"
|
25
|
+
|
26
|
+
# VOID SALES ORDER
|
27
|
+
require "ship_compliant/void_sales_order"
|
28
|
+
require "ship_compliant/void_sales_order_result"
|
29
|
+
|
30
|
+
# ADD UPDATE PRODUCT
|
31
|
+
require "ship_compliant/product_attributes"
|
32
|
+
require "ship_compliant/add_update_product"
|
33
|
+
require "ship_compliant/add_update_product_result"
|
34
|
+
|
35
|
+
# ADD UPDATE BRAND
|
36
|
+
require "ship_compliant/add_update_brand"
|
37
|
+
require "ship_compliant/add_update_brand_result"
|
38
|
+
|
39
|
+
# SALES TAX
|
40
|
+
require "ship_compliant/shipment_sales_tax_rate"
|
41
|
+
require "ship_compliant/sales_tax_rate"
|
42
|
+
require "ship_compliant/product_sales_tax_rate"
|
43
|
+
require "ship_compliant/freight_sales_tax_rate"
|
44
|
+
|
45
|
+
# CHECK COMPLIANCE OF SALES ORDER WITH ADDRESS VALIDATION
|
46
|
+
require "ship_compliant/check_compliance"
|
47
|
+
require "ship_compliant/check_compliance_result"
|
48
|
+
|
49
|
+
require "ship_compliant/shipment_compliance"
|
50
|
+
require "ship_compliant/compliance_rule"
|
51
|
+
|
52
|
+
require "ship_compliant/commit_sales_order"
|
53
|
+
require "ship_compliant/commit_sales_order_result"
|
54
|
+
|
55
|
+
require "ship_compliant/inventory_product"
|
56
|
+
|
57
|
+
require "ship_compliant/get_inventory_details"
|
58
|
+
require "ship_compliant/get_inventory_details_result"
|
59
|
+
|
60
|
+
module ShipCompliant
|
61
|
+
# Your code goes here...
|
62
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ShipCompliant
|
2
|
+
# == ShipCompliant::AddUpdateBrand
|
3
|
+
#
|
4
|
+
# Checks to see if a brand with the same key already exists. If one does not
|
5
|
+
# exist, it will add the brand with the specified name. If a brand exists
|
6
|
+
# with the same brand key then the brand name will be updated.
|
7
|
+
#
|
8
|
+
# Use this method to add a new brand or update an existing brand in the
|
9
|
+
# system. A brand must be defined before adding products.
|
10
|
+
#
|
11
|
+
# ShipCompliant::AddUpdateBrand.brand({
|
12
|
+
# key: 'DENSNW',
|
13
|
+
# name: 'Denver Snow',
|
14
|
+
#
|
15
|
+
# this_brand_is_bottled_by_a_third_party: false,
|
16
|
+
# this_brand_is_produced_by_a_third_party: false,
|
17
|
+
# this_brand_operates_under_a_trade_name: false,
|
18
|
+
# this_brand_was_acquired_from_a_third_party: false
|
19
|
+
# })
|
20
|
+
class AddUpdateBrand
|
21
|
+
|
22
|
+
# Adds or updates a brand depending on +:update_mode+.
|
23
|
+
#
|
24
|
+
# +brand+ parameter must be a Hash.
|
25
|
+
#
|
26
|
+
# === Options
|
27
|
+
#
|
28
|
+
# You can specify the update mode by passing a hash as the second argument.
|
29
|
+
# The default is +ErrorOnExisting+.
|
30
|
+
#
|
31
|
+
# Available options are.
|
32
|
+
#
|
33
|
+
# * UpdateExisting - Existing brand information is updated.
|
34
|
+
# * IgnoreExisting - Pre-existing information is not updated.
|
35
|
+
# * ErrorOnExisting - An error message is returned if the brand already exists.
|
36
|
+
#
|
37
|
+
# ShipCompliant::AddUpdateBrand.product({
|
38
|
+
# # brand attributes
|
39
|
+
# }, update_mode: 'UpdateExisting')
|
40
|
+
def self.brand(brand, options = {})
|
41
|
+
result = ShipCompliant.client.call(:add_update_brand, {
|
42
|
+
'Brand' => brand.deep_transform_keys { |key| key.to_s.camelize },
|
43
|
+
'UpdateMode' => options.fetch(:update_mode, 'ErrorOnExisting')
|
44
|
+
})
|
45
|
+
|
46
|
+
AddUpdateBrandResult.new(result)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module ShipCompliant
|
2
|
+
# == ShipCompliant::AddUpdateProduct
|
3
|
+
#
|
4
|
+
# This method checks to see if a product with the same product key and brand
|
5
|
+
# key already exists.
|
6
|
+
#
|
7
|
+
# If one does not exist, it will add the product with the specified
|
8
|
+
# information.
|
9
|
+
#
|
10
|
+
# If a product exists with the same product key and brand key, but is not
|
11
|
+
# referenced by any shipments, the product will be updated with the specified
|
12
|
+
# information.
|
13
|
+
#
|
14
|
+
# If a product exists with the same product key and brand key, and is
|
15
|
+
# referenced by one or more shipments, the product will not be updated.
|
16
|
+
#
|
17
|
+
# result = ShipCompliant::AddUpdateProduct.product({
|
18
|
+
# # product attributes
|
19
|
+
# }, update_mode: 'IgnoreExisting')
|
20
|
+
#
|
21
|
+
# if result.success?
|
22
|
+
# puts "Product added successfully.
|
23
|
+
# else
|
24
|
+
# result.errors.each do |error|
|
25
|
+
# puts error.message
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
class AddUpdateProduct
|
29
|
+
|
30
|
+
# Adds or updates product depending on +:update_mode+.
|
31
|
+
#
|
32
|
+
# +product+ parameter must be a Hash. The keys must be related to the the
|
33
|
+
# keys located in ShipCompliant::ProductAttributes.
|
34
|
+
#
|
35
|
+
# === Options
|
36
|
+
#
|
37
|
+
# You can specify the update mode by passing a Hash as the second argument.
|
38
|
+
# The default is +ErrorOnExisting+.
|
39
|
+
#
|
40
|
+
# Available options are.
|
41
|
+
#
|
42
|
+
# * UpdateExisting - Existing product information is updated.
|
43
|
+
# * IgnoreExisting - Pre-existing information is not updated.
|
44
|
+
# * ErrorOnExisting - An error message is returned if the product already exists.
|
45
|
+
#
|
46
|
+
# ShipCompliant::AddUpdateProduct.product({
|
47
|
+
# # product attributes
|
48
|
+
# }, update_mode: 'UpdateExisting')
|
49
|
+
def self.product(product, options = {})
|
50
|
+
details = {
|
51
|
+
'Product' => ProductAttributes.new(product).to_h,
|
52
|
+
'UpdateMode' => options.fetch(:update_mode, 'ErrorOnExisting')
|
53
|
+
}
|
54
|
+
|
55
|
+
result = add_update_product(details)
|
56
|
+
AddUpdateProductResult.new(result)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def self.add_update_product(request)
|
62
|
+
ShipCompliant.client.call(:add_update_product, request)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module ShipCompliant
|
2
|
+
# == ShipCompliant::Address
|
3
|
+
#
|
4
|
+
# This is a value object that wraps an address node. +BillTo+ and +ShipTo+.
|
5
|
+
#
|
6
|
+
# address = ShipCompliant::Address.new(city: 'Boston', state: 'MA')
|
7
|
+
# address.city #=> 'Boston'
|
8
|
+
# address.state #=> 'MA'
|
9
|
+
class Address < Struct.new(:address)
|
10
|
+
|
11
|
+
# Returns the suggested city.
|
12
|
+
def city
|
13
|
+
address[:city]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the suggested county.
|
17
|
+
def county
|
18
|
+
address[:county]
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the suggested state.
|
22
|
+
def state
|
23
|
+
address[:state]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the country.
|
27
|
+
def country
|
28
|
+
address[:country]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the suggested street.
|
32
|
+
def street1
|
33
|
+
address[:street1]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the suggested street line 2.
|
37
|
+
def street2
|
38
|
+
address[:street2]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the suggested zip code.
|
42
|
+
def zip1
|
43
|
+
address[:zip1].to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the suggested zip code extension.
|
47
|
+
def zip2
|
48
|
+
return nil if address[:zip2].blank?
|
49
|
+
address[:zip2].to_i
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the company.
|
53
|
+
def company
|
54
|
+
address[:company]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the first name.
|
58
|
+
def first_name
|
59
|
+
address[:first_name]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the last name.
|
63
|
+
def last_name
|
64
|
+
address[:last_name]
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the phone.
|
68
|
+
def phone
|
69
|
+
address[:phone]
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the fax.
|
73
|
+
def fax
|
74
|
+
address[:fax]
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the email address.
|
78
|
+
def email
|
79
|
+
address[:email]
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns the date of birth.
|
83
|
+
def date_of_birth
|
84
|
+
address[:date_of_birth]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module ShipCompliant
|
2
|
+
# == ShipCompliant::SuggestedAddress
|
3
|
+
#
|
4
|
+
# This is a value object that wraps the +SuggestedAddress+ node. It inherits
|
5
|
+
# methods from Address, but it also as methods to access suggested address
|
6
|
+
# details and parts.
|
7
|
+
class SuggestedAddress < Address
|
8
|
+
|
9
|
+
# Returns a Hash of the address location details.
|
10
|
+
#
|
11
|
+
# - +city_abbreviation+
|
12
|
+
# - +congressional_district+
|
13
|
+
# - +county_fips+
|
14
|
+
# - +time_zone+
|
15
|
+
# - +time_zone_code+
|
16
|
+
def details
|
17
|
+
address[:details]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a Hash of the address parts.
|
21
|
+
#
|
22
|
+
# - +company+
|
23
|
+
# - +mail_box_name+
|
24
|
+
# - +mail_box_number+
|
25
|
+
# - +post_direction+
|
26
|
+
# - +pre_direction+
|
27
|
+
# - +street_name+
|
28
|
+
# - +street_number+
|
29
|
+
# - +street_suffix+
|
30
|
+
# - +suite_name+
|
31
|
+
# - +suite_number+
|
32
|
+
def parts
|
33
|
+
address[:parts]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ShipCompliant
|
2
|
+
# == ShipCompliant::BaseResult
|
3
|
+
#
|
4
|
+
# This class provides methods to are relevant to every
|
5
|
+
# API request. All requests made through the
|
6
|
+
# ShipCompliant API client include these methods.
|
7
|
+
module BaseResult
|
8
|
+
|
9
|
+
# Returns boolean whether order was successfully voided.
|
10
|
+
#
|
11
|
+
# puts "SUCCESS" if result.success?
|
12
|
+
def success?
|
13
|
+
response[:response_status] == "Success"
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns true if order failed to be voided.
|
17
|
+
#
|
18
|
+
# puts "FAILED" if result.failure?
|
19
|
+
def failure?
|
20
|
+
!success?
|
21
|
+
end
|
22
|
+
|
23
|
+
# An array of +ErrorResult+ items or an empty array if the response was
|
24
|
+
# successful.
|
25
|
+
#
|
26
|
+
# result.errors.each do |error|
|
27
|
+
# puts "#{error.message} [#error.key]"
|
28
|
+
# end
|
29
|
+
def errors
|
30
|
+
return [] if success?
|
31
|
+
@errors ||= Array.wrap(response[:errors]).map do |error|
|
32
|
+
ErrorResult.new(error[:error])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# The number of errors in the response.
|
37
|
+
def errors_count
|
38
|
+
errors.length
|
39
|
+
end
|
40
|
+
alias_method :error_count, :errors_count
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ShipCompliant
|
2
|
+
# == ShipCompliant::ChannelDetails
|
3
|
+
#
|
4
|
+
# A value object that wraps the +OrderChanelDetails+ node.
|
5
|
+
#
|
6
|
+
# channel_details = sales_order.channel_details
|
7
|
+
# puts channel_details.order_channel #=> 'MyOrders'
|
8
|
+
class ChannelDetails < Struct.new(:channel)
|
9
|
+
|
10
|
+
# Returns +OrderChannel+.
|
11
|
+
def order_channel
|
12
|
+
channel[:order_channel]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns +AdvertiserKey+.
|
16
|
+
def advertiser_key
|
17
|
+
channel[:advertiser_key]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns +AdvertiserName+.
|
21
|
+
def advertiser_name
|
22
|
+
channel[:advertiser_name]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns +Meta+.
|
26
|
+
def meta
|
27
|
+
channel[:meta]
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ShipCompliant
|
2
|
+
# == ShipCompliant::CheckCompliance
|
3
|
+
#
|
4
|
+
# The CheckComplianceOfSalesOrderWithAddressValidation API method is used for
|
5
|
+
# real time compliance checks from the order point of entry (eCommerce, POS).
|
6
|
+
#
|
7
|
+
# The method can do three things in one call:
|
8
|
+
#
|
9
|
+
# - Calculate Sales Tax Due for order and return product level tax rates
|
10
|
+
# (IncludeSalesTaxRates = true)
|
11
|
+
# - Validate the ShipTo address and get normalized address result
|
12
|
+
# - Check compliance of the order
|
13
|
+
#
|
14
|
+
# This method takes requires specific order information from the order point
|
15
|
+
# of entry for ShipCompliant to check the order for compliance. The sales
|
16
|
+
# order will not be committed via this method. This API call is usually
|
17
|
+
# paired with CommitSalesOrder() to save the sales order to ShipCompliant.
|
18
|
+
#
|
19
|
+
# Look at the following example request: http://git.io/xMNOvw
|
20
|
+
class CheckCompliance
|
21
|
+
|
22
|
+
# Checks the compliance of a sales order from the data specified.
|
23
|
+
#
|
24
|
+
# An example of all the required fields can be seen here: http://git.io/xMNOvw
|
25
|
+
#
|
26
|
+
# ShipCompliant::CheckCompliance.of_sales_order({
|
27
|
+
# address_option: {
|
28
|
+
# ignore_street_level_errors: true,
|
29
|
+
# reject_if_address_suggested: 'false' # Savon bug? Passes the value as an attribute when a boolean
|
30
|
+
# },
|
31
|
+
# include_sales_tax_rates: true,
|
32
|
+
# # ...
|
33
|
+
# })
|
34
|
+
def self.of_sales_order(data)
|
35
|
+
camel_cased_keys = data.deep_transform_keys { |key| key.to_s.camelize }
|
36
|
+
result = ShipCompliant.client.call(:check_compliance_of_sales_order_with_address_validation, camel_cased_keys)
|
37
|
+
CheckComplianceResult.new(result)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module ShipCompliant
|
2
|
+
# == ShipCompliant::CheckComplianceResult
|
3
|
+
#
|
4
|
+
# CheckComplianceResult wraps the response from the
|
5
|
+
# +CheckComplianceOfSalesOrderWithAddressValidation+ API method.
|
6
|
+
#
|
7
|
+
# It provides methods to access nested objects and easily iterate over taxes
|
8
|
+
# rates for shipments.
|
9
|
+
#
|
10
|
+
# compliant_status = ShipCompliant::CheckCompliance.of_sales_order({
|
11
|
+
# # attributes here
|
12
|
+
# })
|
13
|
+
#
|
14
|
+
# compliant_status.compliant? #=> true
|
15
|
+
class CheckComplianceResult < Struct.new(:response)
|
16
|
+
include BaseResult
|
17
|
+
|
18
|
+
# Returns true if all shipments of a SalesOrder are compliant.
|
19
|
+
def compliant?
|
20
|
+
response[:sales_order][:is_compliant] == true
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns a float of the recommended sales tax due for a SalesOrder.
|
24
|
+
def recommended_tax_due
|
25
|
+
response[:sales_order][:sales_tax_rates][:recommended_sales_tax_due].to_f
|
26
|
+
end
|
27
|
+
|
28
|
+
# Access the tax information for a shipment. Returns an instance of
|
29
|
+
# ShipmentSalesTaxRate.
|
30
|
+
def taxes_for_shipment(shipment_key)
|
31
|
+
shipment = shipment_sales_tax_rates.select { |s| s[:@shipment_key] == shipment_key }.first
|
32
|
+
|
33
|
+
# convert attribute keys to symbols
|
34
|
+
freight = attributes_to_symbols(shipment[:freight_sales_tax_rate])
|
35
|
+
|
36
|
+
# wrap products in ProductSalesTaxRate
|
37
|
+
products = wrap_products(shipment[:product_sales_tax_rates])
|
38
|
+
|
39
|
+
ShipmentSalesTaxRate.new(shipment_key, FreightSalesTaxRate.new(freight), products)
|
40
|
+
end
|
41
|
+
|
42
|
+
# This method returns an Array containing information about each shipment of a
|
43
|
+
# SalesOrder.
|
44
|
+
def shipment_sales_tax_rates
|
45
|
+
Array.wrap(response[:sales_order][:sales_tax_rates][:shipment_sales_tax_rates][:shipment_sales_tax_rate])
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns an array of the +ShipmentComplianceResponse+ node as a Hash.
|
49
|
+
#
|
50
|
+
# compliance_result.shipment_compliance_rules.each do |shipment|
|
51
|
+
# puts "SHIPMENT '#{shipment[:key]}' IS NOT COMPLIANT" unless shipment[:is_compliant]
|
52
|
+
# end
|
53
|
+
def shipment_compliance_rules
|
54
|
+
Array.wrap(response[:sales_order][:shipments][:shipment_compliance_response])
|
55
|
+
end
|
56
|
+
|
57
|
+
# Finds all the compliance rules for a shipment.
|
58
|
+
# Returns an instance of ShipmentCompliance.
|
59
|
+
#
|
60
|
+
# shipment_compliance = compliance_result.compliance_rules_for_shipment('SHIPMENT-KEY')
|
61
|
+
# puts shipment_compliance.compliant? #=> false
|
62
|
+
def compliance_rules_for_shipment(shipment_key)
|
63
|
+
shipment = shipment_compliance_rules.select { |s| s[:key] == shipment_key }.first
|
64
|
+
ShipmentCompliance.new(shipment)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the +AddressValidationResult+.
|
68
|
+
def address_validation_result
|
69
|
+
response[:address_validation_result]
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns an instance of ShipCompliant::SuggestedAddress.
|
73
|
+
def suggested_address
|
74
|
+
SuggestedAddress.new(response[:suggested_address])
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# Nori returns XML attributes as a key beginning with a spiral (@).
|
80
|
+
# This removes the spiral and changes key to a symbol.
|
81
|
+
def attributes_to_symbols(object)
|
82
|
+
object.transform_keys do |key|
|
83
|
+
key.to_s.gsub('@', '').to_sym
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Wraps each +ProductSalesTaxRates+ node with
|
88
|
+
# ShipCompliant::ProductSalesTaxRate
|
89
|
+
def wrap_products(products)
|
90
|
+
Array.wrap(products[:product_sales_tax_rate]).map do |product|
|
91
|
+
ProductSalesTaxRate.new(attributes_to_symbols(product))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|