veeqo 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 (86) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.hound.yml +3 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +629 -0
  6. data/.sample.pryrc +4 -0
  7. data/.travis.yml +5 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +574 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +10 -0
  13. data/bin/rspec +17 -0
  14. data/bin/setup +8 -0
  15. data/lib/veeqo.rb +16 -0
  16. data/lib/veeqo/actions/base.rb +13 -0
  17. data/lib/veeqo/actions/delete.rb +11 -0
  18. data/lib/veeqo/actions/find.rb +11 -0
  19. data/lib/veeqo/actions/list.rb +11 -0
  20. data/lib/veeqo/allocation.rb +32 -0
  21. data/lib/veeqo/base.rb +26 -0
  22. data/lib/veeqo/company.rb +17 -0
  23. data/lib/veeqo/configuration.rb +17 -0
  24. data/lib/veeqo/customer.rb +24 -0
  25. data/lib/veeqo/delivery_method.rb +19 -0
  26. data/lib/veeqo/errors.rb +30 -0
  27. data/lib/veeqo/errors/forbidden.rb +9 -0
  28. data/lib/veeqo/errors/request_error.rb +15 -0
  29. data/lib/veeqo/errors/server_error.rb +9 -0
  30. data/lib/veeqo/errors/unauthorized.rb +9 -0
  31. data/lib/veeqo/order.rb +25 -0
  32. data/lib/veeqo/product.rb +25 -0
  33. data/lib/veeqo/purchase_order.rb +11 -0
  34. data/lib/veeqo/request.rb +89 -0
  35. data/lib/veeqo/response.rb +27 -0
  36. data/lib/veeqo/shipment.rb +30 -0
  37. data/lib/veeqo/store.rb +19 -0
  38. data/lib/veeqo/supplier.rb +19 -0
  39. data/lib/veeqo/version.rb +3 -0
  40. data/lib/veeqo/warehouse.rb +19 -0
  41. data/spec/fixtures/allocation_created.json +554 -0
  42. data/spec/fixtures/company.json +3 -0
  43. data/spec/fixtures/customer.json +4 -0
  44. data/spec/fixtures/customer_created.json +15 -0
  45. data/spec/fixtures/customers.json +38 -0
  46. data/spec/fixtures/delivery_method.json +3 -0
  47. data/spec/fixtures/delivery_method_created.json +4 -0
  48. data/spec/fixtures/delivery_methods.json +5 -0
  49. data/spec/fixtures/empty.json +0 -0
  50. data/spec/fixtures/order.json +3 -0
  51. data/spec/fixtures/order_created.json +554 -0
  52. data/spec/fixtures/orders.json +5 -0
  53. data/spec/fixtures/ping.json +3 -0
  54. data/spec/fixtures/product.json +4 -0
  55. data/spec/fixtures/product_created.json +137 -0
  56. data/spec/fixtures/products.json +5 -0
  57. data/spec/fixtures/purchase_orders.json +177 -0
  58. data/spec/fixtures/shipment_created.json +19 -0
  59. data/spec/fixtures/store.json +3 -0
  60. data/spec/fixtures/store_created.json +4 -0
  61. data/spec/fixtures/stores.json +5 -0
  62. data/spec/fixtures/supplier.json +3 -0
  63. data/spec/fixtures/supplier_created.json +4 -0
  64. data/spec/fixtures/suppliers.json +5 -0
  65. data/spec/fixtures/warehouse.json +3 -0
  66. data/spec/fixtures/warehouse_created.json +4 -0
  67. data/spec/fixtures/warehouses.json +5 -0
  68. data/spec/spec_helper.rb +15 -0
  69. data/spec/support/fake_veeqo_api.rb +408 -0
  70. data/spec/veeqo/actions/list_spec.rb +38 -0
  71. data/spec/veeqo/allocation_spec.rb +49 -0
  72. data/spec/veeqo/base_spec.rb +23 -0
  73. data/spec/veeqo/company_spec.rb +23 -0
  74. data/spec/veeqo/configuration_spec.rb +24 -0
  75. data/spec/veeqo/customer_spec.rb +77 -0
  76. data/spec/veeqo/delivery_method_spec.rb +65 -0
  77. data/spec/veeqo/order_spec.rb +93 -0
  78. data/spec/veeqo/product_spec.rb +82 -0
  79. data/spec/veeqo/purchase_order_spec.rb +14 -0
  80. data/spec/veeqo/request_spec.rb +40 -0
  81. data/spec/veeqo/shipment_spec.rb +38 -0
  82. data/spec/veeqo/store_spec.rb +61 -0
  83. data/spec/veeqo/supplier_spec.rb +61 -0
  84. data/spec/veeqo/warehouse_spec.rb +61 -0
  85. data/veeqo.gemspec +26 -0
  86. metadata +198 -0
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "veeqo"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ require "pry"
10
+ Pry.start
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'rspec' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("rspec-core", "rspec")
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,16 @@
1
+ require "veeqo/version"
2
+ require "veeqo/base"
3
+ require "veeqo/order"
4
+ require "veeqo/allocation"
5
+ require "veeqo/product"
6
+ require "veeqo/purchase_order"
7
+ require "veeqo/supplier"
8
+ require "veeqo/company"
9
+ require "veeqo/warehouse"
10
+ require "veeqo/customer"
11
+ require "veeqo/store"
12
+ require "veeqo/delivery_method"
13
+ require "veeqo/shipment"
14
+
15
+ module Veeqo
16
+ end
@@ -0,0 +1,13 @@
1
+ require "veeqo/actions/list"
2
+ require "veeqo/actions/find"
3
+ require "veeqo/actions/delete"
4
+
5
+ module Veeqo
6
+ module Actions
7
+ module Base
8
+ include Veeqo::Actions::List
9
+ include Veeqo::Actions::Find
10
+ include Veeqo::Actions::Delete
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ require "veeqo/request"
2
+
3
+ module Veeqo
4
+ module Actions
5
+ module Delete
6
+ def delete(resource_id)
7
+ Veeqo::Request.new(:delete, [end_point, resource_id].join("/")).parse
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require "veeqo/request"
2
+
3
+ module Veeqo
4
+ module Actions
5
+ module Find
6
+ def find(resource_id)
7
+ Veeqo::Request.new(:get, [end_point, resource_id].join("/")).parse
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require "veeqo/request"
2
+
3
+ module Veeqo
4
+ module Actions
5
+ module List
6
+ def list(filters = {})
7
+ Veeqo::Request.new(:get, end_point, filters).parse
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ module Veeqo
2
+ class Allocation < Base
3
+ include Veeqo::Actions::Delete
4
+
5
+ def create(order_id:, warehouse_id:, line_items:)
6
+ @order_id = order_id
7
+ create_resource(
8
+ warehouse_id: warehouse_id,
9
+ line_items_attributes: line_items,
10
+ )
11
+ end
12
+
13
+ def update(allocation_id, order_id:, line_items:, **attributes)
14
+ @order_id = order_id
15
+ update_resource(
16
+ allocation_id,
17
+ attributes.merge(line_items_attributes: line_items),
18
+ )
19
+ end
20
+
21
+ def delete(order_id, allocation_id)
22
+ @order_id = order_id
23
+ super(allocation_id)
24
+ end
25
+
26
+ private
27
+
28
+ def end_point
29
+ ["orders", @order_id, "allocations"].compact.join("/")
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ require "veeqo/request"
2
+ require "veeqo/actions/base"
3
+
4
+ module Veeqo
5
+ class Base
6
+ def self.method_missing(method_name, *arguments, &block)
7
+ if new.respond_to?(method_name, include_private: false)
8
+ new.send(method_name, *arguments, &block)
9
+ else
10
+ super
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def create_resource(attributes)
17
+ Veeqo::Request.new(:post, end_point, attributes).parse
18
+ end
19
+
20
+ def update_resource(resource_id, attributes)
21
+ Veeqo::Request.new(
22
+ :put, [end_point, resource_id].join("/"), attributes
23
+ ).parse
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ module Veeqo
2
+ class Company < Base
3
+ def find
4
+ Veeqo::Request.new(:get, end_point).parse
5
+ end
6
+
7
+ def update(attributes)
8
+ Veeqo::Request.new(:put, end_point, attributes).parse
9
+ end
10
+
11
+ private
12
+
13
+ def end_point
14
+ "current_company"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Veeqo
2
+ class Configuration
3
+ attr_accessor :api_host, :api_key
4
+
5
+ def initialize
6
+ @api_host ||= "api.veeqo.com"
7
+ end
8
+ end
9
+
10
+ def self.configure
11
+ yield configuration
12
+ end
13
+
14
+ def self.configuration
15
+ @configuration ||= Configuration.new
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ module Veeqo
2
+ class Customer < Base
3
+ include Veeqo::Actions::Base
4
+
5
+ def create(email:, **attributes)
6
+ required_attributes = { email: email }
7
+ create_resource(customer: required_attributes.merge(attributes))
8
+ end
9
+
10
+ def update(customer_id, email:, **attributes)
11
+ required_attributes = { email: email }
12
+
13
+ update_resource(
14
+ customer_id, customer: required_attributes.merge(attributes)
15
+ )
16
+ end
17
+
18
+ private
19
+
20
+ def end_point
21
+ "customers"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ module Veeqo
2
+ class DeliveryMethod < Base
3
+ include Veeqo::Actions::Base
4
+
5
+ def create(name:)
6
+ create_resource(name: name)
7
+ end
8
+
9
+ def update(delivery_method_id, name:)
10
+ update_resource(delivery_method_id, name: name)
11
+ end
12
+
13
+ private
14
+
15
+ def end_point
16
+ "delivery_methods"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ require "veeqo/errors/request_error"
2
+ require "veeqo/errors/forbidden"
3
+ require "veeqo/errors/server_error"
4
+ require "veeqo/errors/unauthorized"
5
+
6
+ module Veeqo
7
+ module Errors
8
+ def self.server_errors
9
+ [
10
+ OpenSSL::SSL::SSLError,
11
+ Errno::ETIMEDOUT,
12
+ Errno::EHOSTUNREACH,
13
+ Errno::ENETUNREACH,
14
+ Errno::ECONNRESET,
15
+ Net::OpenTimeout,
16
+ SocketError,
17
+ Net::HTTPServerError,
18
+ ]
19
+ end
20
+
21
+ def self.error_klass_for(response)
22
+ case response
23
+ when *server_errors then Errors::ServerError
24
+ when Net::HTTPUnauthorized then Errors::Unauthorized
25
+ when Net::HTTPForbidden then Errors::Forbidden
26
+ else Errors::RequestError
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ module Veeqo
2
+ module Errors
3
+ class Forbidden < RequestError
4
+ def explanation
5
+ "A request to Veeqo API was considered forbidden by the server"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module Veeqo
2
+ module Errors
3
+ class RequestError < StandardError
4
+ def message
5
+ explanation
6
+ end
7
+
8
+ def explanation
9
+ "A request to Veeqo API failed"
10
+ end
11
+ end
12
+ end
13
+
14
+ Error = Errors::RequestError
15
+ end
@@ -0,0 +1,9 @@
1
+ module Veeqo
2
+ module Errors
3
+ class ServerError < RequestError
4
+ def explanation
5
+ "A request to Veeqo API caused an unexpected server error"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Veeqo
2
+ module Errors
3
+ class Unauthorized < RequestError
4
+ def explanation
5
+ "A request to Veeqo API was sent without a valid authentication"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,25 @@
1
+ module Veeqo
2
+ class Order < Base
3
+ include Veeqo::Actions::Base
4
+
5
+ def create(channel_id:, customer_id:, delivery_method_id:, **attributes)
6
+ required_attributes = {
7
+ channel_id: channel_id,
8
+ customer_id: customer_id,
9
+ delivery_method_id: delivery_method_id,
10
+ }
11
+
12
+ create_resource(order: required_attributes.merge(attributes))
13
+ end
14
+
15
+ def update(order_id, attributes = {})
16
+ update_resource(order_id, attributes)
17
+ end
18
+
19
+ private
20
+
21
+ def end_point
22
+ "orders"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module Veeqo
2
+ class Product < Base
3
+ include Veeqo::Actions::Base
4
+
5
+ def create(title:, variants:, images: [], **attributes)
6
+ required_attributes = {
7
+ title: title,
8
+ product_variants_attributes: variants,
9
+ images_attributes: images,
10
+ }
11
+
12
+ create_resource(product: required_attributes.merge(attributes))
13
+ end
14
+
15
+ def update(product_id, attributes)
16
+ update_resource(product_id, product: attributes)
17
+ end
18
+
19
+ private
20
+
21
+ def end_point
22
+ "products"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module Veeqo
2
+ class PurchaseOrder < Base
3
+ include Veeqo::Actions::List
4
+
5
+ private
6
+
7
+ def end_point
8
+ "purchase_orders"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,89 @@
1
+ require "net/http"
2
+ require "veeqo/errors"
3
+ require "veeqo/response"
4
+ require "veeqo/configuration"
5
+
6
+ module Veeqo
7
+ class Request
8
+ def initialize(http_method, path, attributes = {})
9
+ @path = path
10
+ @http_method = http_method
11
+ @attributes = attributes
12
+ end
13
+
14
+ def run
15
+ valid_response || raise_response_error
16
+ end
17
+
18
+ def parse
19
+ Response.new(run).parse
20
+ end
21
+
22
+ private
23
+
24
+ def valid_response
25
+ if valid_response?
26
+ response
27
+ end
28
+ end
29
+
30
+ def raise_response_error
31
+ raise response_error
32
+ end
33
+
34
+ def valid_response?
35
+ response.is_a?(Net::HTTPSuccess)
36
+ end
37
+
38
+ def response
39
+ @response ||= send_http_request
40
+ rescue *server_errors => error
41
+ @response ||= error
42
+ end
43
+
44
+ def send_http_request
45
+ Net::HTTP.start(*net_http_options) do |http|
46
+ http.request(build_net_http_request)
47
+ end
48
+ end
49
+
50
+ def net_http_options
51
+ [uri.host, uri.port, use_ssl: true]
52
+ end
53
+
54
+ def build_net_http_request
55
+ request = constantize_net_http_class.new(uri)
56
+ set_request_headers!(request)
57
+ set_request_body!(request)
58
+ request
59
+ end
60
+
61
+ def uri
62
+ @uri ||= URI::HTTPS.build(
63
+ host: Veeqo.configuration.api_host,
64
+ path: ["", @path].join("/").squeeze("/"),
65
+ )
66
+ end
67
+
68
+ def constantize_net_http_class
69
+ Object.const_get("Net::HTTP::#{@http_method.to_s.capitalize}")
70
+ end
71
+
72
+ def set_request_body!(request)
73
+ request.body = @attributes.to_json
74
+ end
75
+
76
+ def set_request_headers!(request)
77
+ request.initialize_http_header("Content-Type" => "application/json")
78
+ request.initialize_http_header("x-api-key" => Veeqo.configuration.api_key)
79
+ end
80
+
81
+ def server_errors
82
+ Veeqo::Errors.server_errors
83
+ end
84
+
85
+ def response_error
86
+ Veeqo::Errors.error_klass_for(response)
87
+ end
88
+ end
89
+ end