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.
Files changed (129) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +50 -0
  7. data/Rakefile +47 -0
  8. data/cucumber.yml +9 -0
  9. data/features/add_update_brand.feature +20 -0
  10. data/features/add_update_product.feature +24 -0
  11. data/features/check_compliance_of_sales_order_with_address_validations.feature +18 -0
  12. data/features/commit_sales_order.feature +6 -0
  13. data/features/get_inventory_details.feature +7 -0
  14. data/features/get_sales_order_extended.feature +15 -0
  15. data/features/search_sales_orders.feature +13 -0
  16. data/features/step_definitions/brand_steps.rb +73 -0
  17. data/features/step_definitions/commit_sales_order/all_shipments.rb +15 -0
  18. data/features/step_definitions/compliance_check/available_product_steps.rb +175 -0
  19. data/features/step_definitions/compliance_check/missing_product_steps.rb +102 -0
  20. data/features/step_definitions/compliance_check/noncompliant_product.rb +102 -0
  21. data/features/step_definitions/credential_steps.rb +8 -0
  22. data/features/step_definitions/inventory_steps.rb +36 -0
  23. data/features/step_definitions/product_steps.rb +140 -0
  24. data/features/step_definitions/sales_order_extended_steps.rb +79 -0
  25. data/features/step_definitions/search_order_steps.rb +87 -0
  26. data/features/step_definitions/void_order_steps.rb +27 -0
  27. data/features/support/env.rb +14 -0
  28. data/features/void_sales_order.feature +11 -0
  29. data/fixtures/vcr_cassettes/brand_already_exists.yml +1038 -0
  30. data/fixtures/vcr_cassettes/brand_ignore_existing.yml +1037 -0
  31. data/fixtures/vcr_cassettes/brand_update_existing.yml +1037 -0
  32. data/fixtures/vcr_cassettes/brand_valid.yml +1037 -0
  33. data/fixtures/vcr_cassettes/commit_salesorder_all_shipments.yml +1034 -0
  34. data/fixtures/vcr_cassettes/compliance_available_product.yml +1075 -0
  35. data/fixtures/vcr_cassettes/compliance_missing_product.yml +1046 -0
  36. data/fixtures/vcr_cassettes/compliance_noncompliant_product.yml +1082 -0
  37. data/fixtures/vcr_cassettes/ignore_existing_product.yml +1035 -0
  38. data/fixtures/vcr_cassettes/invalid_search_sales_orders.yml +1038 -0
  39. data/fixtures/vcr_cassettes/inventory_details_for_everything.yml +1037 -0
  40. data/fixtures/vcr_cassettes/product_already_exists.yml +1036 -0
  41. data/fixtures/vcr_cassettes/product_invalid_brand.yml +1036 -0
  42. data/fixtures/vcr_cassettes/product_valid_brand.yml +1035 -0
  43. data/fixtures/vcr_cassettes/sales_order_extended.yml +1042 -0
  44. data/fixtures/vcr_cassettes/sales_order_missing.yml +1034 -0
  45. data/fixtures/vcr_cassettes/search_sales_orders.yml +1039 -0
  46. data/fixtures/vcr_cassettes/update_product.yml +1035 -0
  47. data/fixtures/vcr_cassettes/void_order.yml +1033 -0
  48. data/fixtures/vcr_cassettes/void_voided_order.yml +1034 -0
  49. data/lib/ship_compliant.rb +62 -0
  50. data/lib/ship_compliant/add_update_brand.rb +50 -0
  51. data/lib/ship_compliant/add_update_brand_result.rb +6 -0
  52. data/lib/ship_compliant/add_update_product.rb +66 -0
  53. data/lib/ship_compliant/add_update_product_result.rb +6 -0
  54. data/lib/ship_compliant/address.rb +87 -0
  55. data/lib/ship_compliant/address/suggested_address.rb +37 -0
  56. data/lib/ship_compliant/base_result.rb +43 -0
  57. data/lib/ship_compliant/channel_details.rb +31 -0
  58. data/lib/ship_compliant/check_compliance.rb +41 -0
  59. data/lib/ship_compliant/check_compliance_result.rb +95 -0
  60. data/lib/ship_compliant/client.rb +54 -0
  61. data/lib/ship_compliant/commit_sales_order.rb +48 -0
  62. data/lib/ship_compliant/commit_sales_order_result.rb +30 -0
  63. data/lib/ship_compliant/compliance_rule.rb +30 -0
  64. data/lib/ship_compliant/configuration.rb +46 -0
  65. data/lib/ship_compliant/error_result.rb +41 -0
  66. data/lib/ship_compliant/freight_sales_tax_rate.rb +8 -0
  67. data/lib/ship_compliant/get_inventory_details.rb +31 -0
  68. data/lib/ship_compliant/get_inventory_details_result.rb +41 -0
  69. data/lib/ship_compliant/get_sales_order_extended.rb +23 -0
  70. data/lib/ship_compliant/get_sales_order_extended_result.rb +65 -0
  71. data/lib/ship_compliant/inventory_product.rb +95 -0
  72. data/lib/ship_compliant/order_search.rb +92 -0
  73. data/lib/ship_compliant/package.rb +13 -0
  74. data/lib/ship_compliant/product_attributes.rb +98 -0
  75. data/lib/ship_compliant/product_sales_tax_rate.rb +23 -0
  76. data/lib/ship_compliant/sales_tax_rate.rb +22 -0
  77. data/lib/ship_compliant/search_sales_order_summary.rb +30 -0
  78. data/lib/ship_compliant/search_sales_orders.rb +53 -0
  79. data/lib/ship_compliant/search_sales_orders_result.rb +106 -0
  80. data/lib/ship_compliant/shipment.rb +59 -0
  81. data/lib/ship_compliant/shipment_compliance.rb +28 -0
  82. data/lib/ship_compliant/shipment_sales_tax_rate.rb +15 -0
  83. data/lib/ship_compliant/version.rb +3 -0
  84. data/lib/ship_compliant/void_sales_order.rb +42 -0
  85. data/lib/ship_compliant/void_sales_order_result.rb +20 -0
  86. data/ship_compliant.gemspec +33 -0
  87. data/spec/fixtures/add_update_product.xml +22 -0
  88. data/spec/fixtures/check_compliance.xml +125 -0
  89. data/spec/fixtures/coreservice.wsdl +1341 -0
  90. data/spec/fixtures/search_sales_orders.xml +52 -0
  91. data/spec/fixtures/void_order_failure.xml +31 -0
  92. data/spec/fixtures/void_order_success.xml +22 -0
  93. data/spec/lib/ship_compliant/add_update_brand_result_spec.rb +7 -0
  94. data/spec/lib/ship_compliant/add_update_brand_spec.rb +58 -0
  95. data/spec/lib/ship_compliant/add_update_product_result_spec.rb +7 -0
  96. data/spec/lib/ship_compliant/add_update_product_spec.rb +52 -0
  97. data/spec/lib/ship_compliant/address/suggested_address_spec.rb +28 -0
  98. data/spec/lib/ship_compliant/address_spec.rb +123 -0
  99. data/spec/lib/ship_compliant/base_result_spec.rb +127 -0
  100. data/spec/lib/ship_compliant/channel_details_spec.rb +40 -0
  101. data/spec/lib/ship_compliant/check_compliance_result_spec.rb +135 -0
  102. data/spec/lib/ship_compliant/check_compliance_spec.rb +43 -0
  103. data/spec/lib/ship_compliant/client_spec.rb +73 -0
  104. data/spec/lib/ship_compliant/commit_sales_order_result_spec.rb +32 -0
  105. data/spec/lib/ship_compliant/commit_sales_order_spec.rb +38 -0
  106. data/spec/lib/ship_compliant/compliance_rule_spec.rb +47 -0
  107. data/spec/lib/ship_compliant/configuration_spec.rb +47 -0
  108. data/spec/lib/ship_compliant/error_result_spec.rb +47 -0
  109. data/spec/lib/ship_compliant/freight_sales_tax_rate_spec.rb +7 -0
  110. data/spec/lib/ship_compliant/get_inventory_details_result_spec.rb +87 -0
  111. data/spec/lib/ship_compliant/get_inventory_details_spec.rb +35 -0
  112. data/spec/lib/ship_compliant/get_sales_order_extended_result_spec.rb +84 -0
  113. data/spec/lib/ship_compliant/get_sales_order_extended_spec.rb +39 -0
  114. data/spec/lib/ship_compliant/inventory_product_spec.rb +116 -0
  115. data/spec/lib/ship_compliant/order_search_spec.rb +21 -0
  116. data/spec/lib/ship_compliant/package_spec.rb +26 -0
  117. data/spec/lib/ship_compliant/product_attributes_spec.rb +36 -0
  118. data/spec/lib/ship_compliant/product_sales_tax_rate_spec.rb +22 -0
  119. data/spec/lib/ship_compliant/sales_tax_rate_spec.rb +21 -0
  120. data/spec/lib/ship_compliant/search_sales_order_summary_spec.rb +56 -0
  121. data/spec/lib/ship_compliant/search_sales_orders_result_spec.rb +121 -0
  122. data/spec/lib/ship_compliant/search_sales_orders_spec.rb +42 -0
  123. data/spec/lib/ship_compliant/shipment_compliance_spec.rb +46 -0
  124. data/spec/lib/ship_compliant/shipment_sales_tax_rate_spec.rb +20 -0
  125. data/spec/lib/ship_compliant/shipment_spec.rb +106 -0
  126. data/spec/lib/ship_compliant/void_sales_order_result_spec.rb +7 -0
  127. data/spec/lib/ship_compliant/void_sales_order_spec.rb +41 -0
  128. data/spec/spec_helper.rb +50 -0
  129. metadata +366 -0
@@ -0,0 +1,36 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe ProductAttributes do
5
+
6
+ context "to_h" do
7
+ it "converts keys to pascal case" do
8
+ product = ProductAttributes.new(unit_price: 10)
9
+ product.to_h.should == {
10
+ "UnitPrice" => 10
11
+ }
12
+ end
13
+
14
+ it "handles special cases" do
15
+ product = ProductAttributes.new(
16
+ bottle_size_ml: 'value',
17
+ gtin: 'value',
18
+ nabca: 'value',
19
+ scc: 'value',
20
+ unimerc: 'value',
21
+ upc: 'value'
22
+ )
23
+
24
+ product.to_h.should == {
25
+ 'BottleSizeML' => 'value',
26
+ 'GTIN' => 'value',
27
+ 'NABCA' => 'value',
28
+ 'SCC' => 'value',
29
+ 'UNIMERC' => 'value',
30
+ 'UPC' => 'value'
31
+ }
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe ProductSalesTaxRate do
5
+
6
+ it { should be_kind_of(SalesTaxRate) }
7
+ subject { ProductSalesTaxRate.new(brand_key: 'brand-key', product_key: 'the-product') }
8
+
9
+ context "product_key" do
10
+ it "returns the product key" do
11
+ subject.product_key.should == 'the-product'
12
+ end
13
+ end
14
+
15
+ context "brand_key" do
16
+ it "returns the brand key" do
17
+ subject.brand_key.should == 'brand-key'
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe SalesTaxRate do
5
+
6
+ context "sales_tax_due" do
7
+ it "returns sales_tax_due" do
8
+ tax_rate = SalesTaxRate.new(sales_tax_due: '34.43')
9
+ tax_rate.sales_tax_due.should == 34.43
10
+ end
11
+ end
12
+
13
+ context "sales_tax_rate" do
14
+ it "return sales_tax_rate" do
15
+ tax_rate = SalesTaxRate.new(sales_tax_rate: '2.34')
16
+ tax_rate.sales_tax_rate.should == 2.34
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,56 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe SearchSalesOrderSummary do
5
+ let(:response) do
6
+ {
7
+ purchase_date: DateTime.new(2014, 1, 1),
8
+ sales_order_key: 'ORD-1',
9
+ shipments: {
10
+ shipment_summary: {
11
+ compliance: 'Perfect Score',
12
+ requested_ship_date: '2014-01-03T14:30:00',
13
+ ship_date: '2014-01-03T12:23:00',
14
+
15
+ ship_to: {
16
+ first_name: 'Bob',
17
+ last_name: 'Smith',
18
+ zip1: 80234
19
+ }
20
+ }
21
+ }
22
+ }
23
+ end
24
+
25
+ let(:summary) { SearchSalesOrderSummary.new(response) }
26
+
27
+ context "purchase_date" do
28
+ it "returns a DateTime from the purchase date" do
29
+ summary.purchase_date.should == DateTime.new(2014, 1, 1)
30
+ end
31
+ end
32
+
33
+ context "order_key" do
34
+ it "returns the order_key" do
35
+ summary.order_key.should == 'ORD-1'
36
+ summary.sales_order_key.should == 'ORD-1'
37
+ end
38
+ end
39
+
40
+ context "shipment_summary" do
41
+ it "the parsed hash" do
42
+ summary.shipment_summary.should == {
43
+ compliance: 'Perfect Score',
44
+ requested_ship_date: '2014-01-03T14:30:00',
45
+ ship_date: '2014-01-03T12:23:00',
46
+
47
+ ship_to: {
48
+ first_name: 'Bob',
49
+ last_name: 'Smith',
50
+ zip1: 80234
51
+ }
52
+ }
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,121 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe SearchSalesOrdersResult do
5
+
6
+ let(:response) do
7
+ {
8
+ paging_cookie: 'paging-cookie',
9
+ paging_cookie_expires: Date.new(2014, 1, 1),
10
+ sales_orders: {
11
+ sales_order_summary: {
12
+ shipments: {}
13
+ }
14
+ }
15
+ }
16
+ end
17
+
18
+ it_behaves_like "BaseResult"
19
+
20
+ context "length" do
21
+ it "returns the number of returned orders" do
22
+ response[:count_sales_orders_returned] = '5'
23
+ result = SearchSalesOrdersResult.new(response)
24
+
25
+ result.length.should == 5
26
+ end
27
+ end
28
+
29
+ context "remaining_orders_length" do
30
+ it "returns the number of orders left" do
31
+ response[:count_more_sales_orders_available] = '8'
32
+ result = SearchSalesOrdersResult.new(response)
33
+
34
+ result.remaining_orders_length.should == 8
35
+ end
36
+ end
37
+
38
+ context "paging_cookie" do
39
+ it "gets the paging cookie" do
40
+ result = SearchSalesOrdersResult.new(response)
41
+ result.paging_cookie.should == 'paging-cookie'
42
+ end
43
+ end
44
+
45
+ context "paging_cookie_expires" do
46
+ it "gets the expiration date" do
47
+ result = SearchSalesOrdersResult.new(response)
48
+ result.paging_cookie_expires.should == Date.new(2014, 1, 1)
49
+ end
50
+ end
51
+
52
+ context "summaries" do
53
+ it "returns an array of SearchSalesOrderSummary" do
54
+ result = SearchSalesOrdersResult.new(response)
55
+ result.summaries[0].should be_kind_of(SearchSalesOrderSummary)
56
+ end
57
+
58
+ it "returns empty array when blank" do
59
+ result = SearchSalesOrdersResult.new({})
60
+ result.summaries.should == []
61
+ end
62
+ end
63
+
64
+ context "parse!" do
65
+ it "adds missing sales_orders summaries" do
66
+ result = SearchSalesOrdersResult.new({})
67
+ result.raw.should == {
68
+ sales_orders: {
69
+ sales_order_summary: [{}]
70
+ }
71
+ }
72
+ end
73
+
74
+ it "converts single order summary to an array" do
75
+ result = SearchSalesOrdersResult.new(response)
76
+
77
+ result.raw.should == {
78
+ paging_cookie: 'paging-cookie',
79
+ paging_cookie_expires: Date.new(2014, 1, 1),
80
+ sales_orders: {
81
+ sales_order_summary: [
82
+ shipments: {}
83
+ ]
84
+ }
85
+ }
86
+ end
87
+
88
+ it "converts fields to integers" do
89
+ response[:count_more_sales_orders_available] = '10'
90
+ response[:count_sales_orders_returned] = '5'
91
+ response[:sales_orders][:sales_order_summary][:shipments] = {
92
+ shipment_summary: {
93
+ shipment_key: '59',
94
+ ship_to: {
95
+ zip1: '12345'
96
+ }
97
+ }
98
+ }
99
+
100
+ result = SearchSalesOrdersResult.new(response)
101
+
102
+ result.raw.should == {
103
+ paging_cookie: 'paging-cookie',
104
+ paging_cookie_expires: Date.new(2014, 1, 1),
105
+ count_more_sales_orders_available: 10,
106
+ count_sales_orders_returned: 5,
107
+
108
+ sales_orders: {
109
+ sales_order_summary: [
110
+ {
111
+ shipments: {
112
+ shipment_summary: {shipment_key: 59, ship_to: { zip1: 12345 }}
113
+ }
114
+ }
115
+ ]
116
+ }
117
+ }
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe SearchSalesOrders do
5
+
6
+ before { savon.mock! }
7
+ after { savon.unmock! }
8
+
9
+ context "find_by" do
10
+
11
+ let(:message) do
12
+ {
13
+ 'Request' => {
14
+ 'Security' => {
15
+ 'PartnerKey' => 'abc-123',
16
+ 'Username' => 'bob@example.com',
17
+ 'Password' => 'secret'
18
+ },
19
+ 'ComplianceStatus' => 45
20
+ }
21
+ }
22
+ end
23
+ let(:response) { File.read('spec/fixtures/search_sales_orders.xml') }
24
+
25
+ it "queries the client" do
26
+ savon.expects(:search_sales_orders)
27
+ .with(message: message).returns(response)
28
+
29
+ SearchSalesOrders.find_by({
30
+ compliance_status: 45
31
+ })
32
+ end
33
+
34
+ it "returns a SearchSalesOrdersResult" do
35
+ SearchSalesOrders.stub(:search_sales) { {} }
36
+
37
+ result = SearchSalesOrders.find_by({})
38
+ result.should be_kind_of(SearchSalesOrdersResult)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,46 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe ShipmentCompliance do
5
+
6
+ context "compliant?" do
7
+ it "check is a shipment was compliant" do
8
+ subject.compliant?.should be_true
9
+ end
10
+ end
11
+
12
+ context "shipment_key" do
13
+ it "returns the shipment key" do
14
+ subject.shipment_key.should == 'AN-ORDER-KEY'
15
+ end
16
+ end
17
+
18
+ context "rules" do
19
+ it "returns an array of ComplianceRule" do
20
+ subject.rules.should == [
21
+ ComplianceRule.new(compliance_description: "You're clear for take off ghost rider")
22
+ ]
23
+ end
24
+
25
+ it "returns an empty array when none found" do
26
+ shipment = ShipmentCompliance.new({
27
+ rules: nil
28
+ })
29
+
30
+ shipment.rules.should == []
31
+ end
32
+ end
33
+
34
+ subject do
35
+ ShipmentCompliance.new(
36
+ is_compliant: true,
37
+ key: 'AN-ORDER-KEY',
38
+ rules: {
39
+ rule_compliance_response: {
40
+ compliance_description: "You're clear for take off ghost rider"
41
+ }
42
+ }
43
+ )
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,20 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe ShipmentSalesTaxRate do
5
+
6
+ context "taxes_for_product" do
7
+ it "returns product sales tax rate" do
8
+ product_1, product_2, product_3 = [1, 2, 3].map { |p_id| ProductSalesTaxRate.new(product_key: "product-#{p_id}") }
9
+ shipment = ShipmentSalesTaxRate.new(nil, nil, [
10
+ product_1,
11
+ product_2,
12
+ product_3
13
+ ])
14
+
15
+ shipment.taxes_for_product('product-2').should == product_2
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,106 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe Shipment do
5
+
6
+ context "fulfillment_house" do
7
+ it "gets the fulfillment_house" do
8
+ subject.fulfillment_house.should == 'Chucky Cheese'
9
+ end
10
+ end
11
+
12
+ context "fulfillment_exception_reason" do
13
+ it "gets the fulfillment_exception_reason" do
14
+ subject.fulfillment_exception_reason.should == 'Cheese must be aged.'
15
+ end
16
+ end
17
+
18
+ context "fulfillment_exception_type" do
19
+ it "gets the fulfillment_exception_type" do
20
+ subject.fulfillment_exception_type.should == 'None'
21
+ end
22
+ end
23
+
24
+ context "fulfillment_status" do
25
+ it "gets the fulfillment_status" do
26
+ subject.fulfillment_status.should == 'Accepted'
27
+ end
28
+ end
29
+
30
+ context "handling" do
31
+ it "gets the handling" do
32
+ subject.handling.should == 338.33
33
+ end
34
+ end
35
+
36
+ context "insured_amount" do
37
+ it "gets the insured_amount" do
38
+ subject.insured_amount.should == 10000.33
39
+ end
40
+ end
41
+
42
+ context "shipping" do
43
+ it "gets the shipping" do
44
+ subject.shipping.should == 23.44
45
+ end
46
+ end
47
+
48
+ context "ship_date" do
49
+ it "gets the ship_date" do
50
+ subject.ship_date.should == Date.new(2014, 1, 1)
51
+ end
52
+ end
53
+
54
+ context "shipment_status" do
55
+ it "gets the shipment_status" do
56
+ subject.shipment_status.should == 'Delivered'
57
+ end
58
+ end
59
+
60
+ context "shipping_service" do
61
+ it "gets the shipping_service" do
62
+ subject.shipping_service.should == 'Snortn Boar Transport'
63
+ end
64
+ end
65
+
66
+ context "special_instructions" do
67
+ it "gets the special_instructions" do
68
+ subject.special_instructions.should == 'Get autograph'
69
+ end
70
+ end
71
+
72
+ context "packages" do
73
+ it "gets the packages" do
74
+ subject.packages.should == [Package.new(tracking: 'info here')]
75
+ end
76
+ end
77
+
78
+ context "ship_to" do
79
+ it "gets the shipping address" do
80
+ subject.ship_to.should == Address.new(country: 'US')
81
+ end
82
+ end
83
+
84
+ subject do
85
+ Shipment.new({
86
+ fulfillment_house: 'Chucky Cheese',
87
+ fulfillment_exception_reason: 'Cheese must be aged.',
88
+ fulfillment_exception_type: 'None',
89
+ fulfillment_status: 'Accepted',
90
+
91
+ handling: '338.33',
92
+ insured_amount: '10000.33',
93
+ shipping: '23.44',
94
+
95
+ ship_date: Date.new(2014, 1, 1),
96
+ shipment_status: 'Delivered',
97
+ shipping_service: 'Snortn Boar Transport',
98
+ special_instructions: 'Get autograph',
99
+
100
+ packages: [{ package: {tracking: 'info here'} }],
101
+
102
+ ship_to: { country: 'US' }
103
+ })
104
+ end
105
+ end
106
+ end