zaikio-procurement 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f50427e350fe6e3c2a06efb244a9fef456e8ab840acf5c3d49384d0e242413b5
4
+ data.tar.gz: bb0358367208742ff48cd09762dc5187301d45e76a50f43015ba8a4a5606c99d
5
+ SHA512:
6
+ metadata.gz: 5dd46c3947dc8be40214939fd975306ff6578b94a5e22dc4aa93a649a97354d9b4f0939aabd7e0bb15441f44438e8756d05e9e6b4a75404732a57a3c2315693b
7
+ data.tar.gz: e1ec9997f5c0545d6211612b08fa91553369cb73ba792ec0f9318639c1ac569041e5a4464ee721bcc36bd38a92f66592e416ea239e3137828c3d7b362cb0a36f
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2020 Zaikio GmbH
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,140 @@
1
+ # Zaikio::Procurement
2
+
3
+ Ruby API Client for Zaikio's Procurement Platform.
4
+
5
+ ## Installation
6
+
7
+ ### 1. Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'zaikio-procurement'
11
+ ```
12
+
13
+ And then execute:
14
+ ```bash
15
+ $ bundle
16
+ ```
17
+
18
+ Or install it yourself as:
19
+ ```bash
20
+ $ gem install zaikio-procurement
21
+ ```
22
+
23
+ ### 2. Configure the gem:
24
+
25
+ ```rb
26
+ # config/initializers/zaikio_procurement.rb
27
+
28
+ Zaikio::Procurement.configure do |config|
29
+ config.environment = :production # sandbox or production
30
+ end
31
+ ```
32
+
33
+
34
+ ## Usage
35
+
36
+ The Procurement Client has an ORM like design.
37
+
38
+ For the requests to work, a valid JSON Web token with the correct OAuth Scopes must always be provided. Please refer to [zakio-oauth_client](https://github.com/zaikio/zaikio-oauth_client).
39
+
40
+ If you want to know which actions are available and which scopes are required, please refer to the [Procurement Consumer API Reference](https://docs.zaikio.com/api/procurement_consumers/procurement.html).
41
+
42
+ ### As an organization
43
+
44
+ ```rb
45
+ token = "..." # Your valid JWT for an organization
46
+ Zaikio::Procurement.with_token(token) do
47
+
48
+ # Fetch Data
49
+ Zaikio::Procurement::Article.all
50
+ Zaikio::Procurement::Article.find("7cbf51bd-35a8-47a1-84a2-57aa63140234")
51
+ Zaikio::Procurement::Article.list_by_article_type_or_supplier_slug("great_paper_company")
52
+
53
+ # Associations
54
+ article = Zaikio::Procurement::Article.find("7cbf51bd-35a8-47a1-84a2-57aa63140234")
55
+ article.supplier
56
+ article.variants
57
+
58
+ # Search for all variants of a substrate
59
+ search = Zaikio::Procurement::SubstrateSearch.new("Magno", grain: "long", paper_weight: 80)
60
+
61
+ # or by providing a supplier_id to search for all variants of a substrate of from a specific supplier
62
+ search = Zaikio::Procurement::SubstrateSearch.new("Magno", grain: "long", paper_weight: 80, supplier_id: "b5b14aa0-ae84-452b-9719-a38545365902")
63
+
64
+ search.results # Returns a list of matching variants
65
+ search.facets # Returns a list of search facets that can be used to further narrow down the results
66
+
67
+ # https://docs.zaikio.com/api/procurement_consumers/procurement.html#/LineItemSuggestions/post_variants__variant_id__line_item_suggestions
68
+ variant = Zaikio::Procurement::Variant.find("845a4d7e-db5a-46a6-9d30-bf2e884cb393")
69
+ variant.line_item_suggestion(amount: 10, unit: "sheet") # Returns a line item suggestion for a specifc variant
70
+
71
+ # https://docs.zaikio.com/api/procurement_consumers/procurement.html#/LineItemSuggestions/post_suppliers__supplier_id__line_item_suggestions
72
+ supplier = Zaikio::Procurement::Supplier.find("b5b14aa0-ae84-452b-9719-a38545365902")
73
+ supplier.line_item_suggestions(
74
+ variants: [
75
+ {
76
+ id: "0001b94e-4e87-4ee9-8b14-6ff9910b4f26",
77
+ amount: 2000,
78
+ exact_amount: false,
79
+ environmental_certification: "FSC Mix Credit",
80
+ unit: "sheet"
81
+ },
82
+ {
83
+ id: "10236394-ecd4-465b-ab72-0fbd79296e6a",
84
+ amount: 10,
85
+ exact_amount: false,
86
+ environmental_certification: "PEFC 100%",
87
+ unit: "sheet"
88
+ }
89
+ ]
90
+ ) # Returns line item suggestions for multiple variants of a supplier
91
+
92
+
93
+ # Create new resources
94
+ Zaikio::Procurement::Order.create(
95
+ contract_id: "fd677fc7-abd9-460c-b086-34de1a8349e8",
96
+ delivery_mode: "complete",
97
+ exclusive_sales_group_id: "42dcbaf6-e557-4423-96bc-707ebbc223c0",
98
+ references: ["CO/XXXXXX"],
99
+ state_event: "place",
100
+ deliveries_attributes: [
101
+ {
102
+ address_addressee: "Joey’s Print Ltd",
103
+ address_text: "Emmerich-Josef-Straße 1A, 55116 Mainz",
104
+ desired_delivery_date: "2021-01-29",
105
+ references: ["D/XXXXXX"]
106
+ }
107
+ ],
108
+ order_line_items_attributes: [
109
+ {
110
+ sku_id: "26b3aadc-928f-4d1a-ba2d-13ac3c8f523d",
111
+ amount: 108000
112
+ }
113
+ ]
114
+ )
115
+
116
+ order = Zaikio::Procurement::Order.find("86b4a0c5-6d54-4702-a059-da258643f260")
117
+ order.order_line_items.create(sku_id: "6535eeb0-45c2-4c63-8cb9-4814562bb875", amount: 68000)
118
+
119
+ # Update resources
120
+ line_item = Zaikio::Procurement::OrderLineItem.find("058a5513-925e-4d0c-923d-fa1ed4bfb3ce")
121
+ line_item.update(amount: 69000)
122
+
123
+ # Deleting resources
124
+ line_item = Zaikio::Procurement::OrderLineItem.find("2f5a99c2-9734-4aac-9cee-911b061d3a5a")
125
+ line_item.destroy
126
+ end
127
+ ```
128
+
129
+ ### Error Handling
130
+
131
+ If an unexpected error occurs with an API call (i.e. an error that has no status code `2xx`, `404` or `422`) then a `Zaikio::ConnectionError` is thrown automatically (for `404` there will be a `Zaikio::ResourceNotFound`).
132
+
133
+ This can be easily caught using the `with_fallback` method. We recommend to always work with fallbacks.
134
+
135
+ ```rb
136
+ Zaikio::Directory.with_token(token) do
137
+ Zaikio::Procurement::Article.with_fallback.find("7cbf51bd-35a8-47a1-84a2-57aa63140234") # => nil
138
+ Zaikio::Procurement::Article.with_fallback.all # Automatically uses empty array as fallback
139
+ end
140
+ ```
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+ require 'rubocop/rake_task'
9
+
10
+ RDoc::Task.new(:rdoc) do |rdoc|
11
+ rdoc.rdoc_dir = 'rdoc'
12
+ rdoc.title = 'Zaikio::Procurement'
13
+ rdoc.options << '--line-numbers'
14
+ rdoc.rdoc_files.include('README.md')
15
+ rdoc.rdoc_files.include('lib/**/*.rb')
16
+ end
17
+
18
+ require 'bundler/gem_tasks'
19
+
20
+ require 'rake/testtask'
21
+
22
+ Rake::TestTask.new(:test) do |t|
23
+ t.libs << 'test'
24
+ t.pattern = 'test/**/*_test.rb'
25
+ t.verbose = false
26
+ end
27
+
28
+ task default: :test
29
+
30
+ namespace :test do
31
+ desc 'Runs RuboCop on specified directories'
32
+ RuboCop::RakeTask.new(:rubocop) do |task|
33
+ task.fail_on_error = false
34
+ end
35
+ end
36
+
37
+ Rake::Task[:test].enhance ['test:rubocop']
@@ -0,0 +1,35 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class Article < Base
4
+ include_root_in_json :article
5
+
6
+ # Class methods
7
+ class << self
8
+ # Spyke URI override
9
+ def uri
10
+ Zaikio::Procurement.configuration.flavor == :supplier ? "substrate/articles(/:id)" : "articles(/:id)"
11
+ end
12
+
13
+ def list_by_article_type_or_supplier_slug(type_or_slug)
14
+ with("#{type_or_slug}/articles").get
15
+ end
16
+
17
+ def list_by_article_type_and_supplier_slug(type, slug)
18
+ with("#{type}/#{slug}/articles").get
19
+ end
20
+ end
21
+
22
+ # Attributes
23
+ attributes :name, :base_unit, :coated, :description, :finish,
24
+ :kind, :supplier_id, :created_at, :updated_at
25
+
26
+ # Associations
27
+ has_one :supplier, class_name: "Zaikio::Procurement::Supplier",
28
+ uri: nil
29
+ # Manually build variants association to work for consumers and suppliers
30
+ def variants
31
+ self.class.request(:get, "#{uri}/variants").data.collect { |v| Zaikio::Procurement::Variant.new(v) }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ require "faraday"
2
+ require "jwt"
3
+ require "concurrent"
4
+
5
+ module Zaikio
6
+ module Procurement
7
+ class AuthorizationMiddleware < Faraday::Middleware
8
+ def self.token
9
+ @token ||= Concurrent::ThreadLocalVar.new { nil }
10
+ @token.value
11
+ end
12
+
13
+ def self.token=(value)
14
+ @token ||= Concurrent::ThreadLocalVar.new { nil }
15
+ @token.value = value
16
+ end
17
+
18
+ def self.reset_token
19
+ self.token = nil
20
+ end
21
+
22
+ def call(request_env)
23
+ request_env[:request_headers]["Authorization"] = "Bearer #{self.class.token}" if self.class.token
24
+
25
+ @app.call(request_env).on_complete do |response_env|
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,7 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class Base < Zaikio::Client::Model
4
+ self.callback_methods = { create: :post, update: :patch }.freeze
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,49 @@
1
+ require "logger"
2
+
3
+ module Zaikio
4
+ module Procurement
5
+ class Configuration
6
+ HOSTS = {
7
+ development: "https://procurement.zaikio.test",
8
+ test: "https://procurement.zaikio.test",
9
+ staging: "https://procurement.staging.zaikio.com",
10
+ sandbox: "https://procurement.sandbox.zaikio.com",
11
+ production: "https://procurement.zaikio.com"
12
+ }.freeze
13
+
14
+ FLAVORS = %i[consumer supplier].freeze
15
+
16
+ attr_accessor :host
17
+ attr_reader :environment, :flavor
18
+ attr_writer :logger
19
+
20
+ def initialize
21
+ @environment = :sandbox
22
+ @flavor = :consumer
23
+ end
24
+
25
+ def logger
26
+ @logger ||= Logger.new($stdout)
27
+ end
28
+
29
+ def environment=(env)
30
+ @environment = env.to_sym
31
+ @host = host_for(environment)
32
+ end
33
+
34
+ def flavor=(flavor)
35
+ raise StandardError.new, "Invalid Zaikio::Procurement flavor '#{flavor}'" unless FLAVORS.include?(flavor)
36
+
37
+ @flavor = flavor
38
+ end
39
+
40
+ private
41
+
42
+ def host_for(environment)
43
+ HOSTS.fetch(environment) do
44
+ raise StandardError.new, "Invalid Zaikio::Procurement environment '#{environment}'"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,17 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class Contract < Base
4
+ uri "contracts(/:id)"
5
+ include_root_in_json :contract
6
+
7
+ # Attributes
8
+ attributes :currency, :customer_number, :references, :consumer_id,
9
+ :consumer, :supplier_id, :created_at, :updated_at
10
+
11
+ # Associations
12
+ has_one :supplier, class_name: "Zaikio::Procurement::Supplier",
13
+ uri: nil
14
+ has_one :contract_request, uri: nil
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class ContractRequest < Base
4
+ uri "contract_requests(/:id)"
5
+ include_root_in_json :contract_request
6
+
7
+ # Attributes
8
+ attributes :accepted_at, :connectivity_checked_at, :contact_email, :contact_first_name,
9
+ :contact_last_name, :contact_phone, :currency, :customer_number, :declined_at,
10
+ :mapped_at, :references, :state, :vetted_at, :consumer_id, :consumer, :supplier_id,
11
+ :created_at, :updated_at
12
+
13
+ # Associations
14
+ belongs_to :supplier, class_name: "Zaikio::Procurement::Supplier",
15
+ uri: nil
16
+ has_one :contract, uri: nil
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class CurrentSupplier < Base
4
+ self.primary_key = nil
5
+ uri "supplier"
6
+ include_root_in_json :supplier
7
+
8
+ def self.find
9
+ all.find_one
10
+ end
11
+
12
+ def self.find_with_fallback(fallback)
13
+ all.with_fallback(fallback).find_one
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class Delivery < Base
4
+ uri "deliveries(/:id)"
5
+ include_root_in_json :delivery
6
+
7
+ # Attributes
8
+ attributes :confirmed_delivery_date, :desired_delivery_date, :references,
9
+ :address, :order_id, :created_at, :updated_at
10
+
11
+ # Associations
12
+ belongs_to :order, class_name: "Zaikio::Procurement::Order",
13
+ uri: nil
14
+ has_many :delivery_line_items, class_name: "Zaikio::Procurement::DeliveryLineItem",
15
+ uri: "deliveries/:delivery_id/delivery_line_items(/:id)"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class DeliveryLineItem < Base
4
+ uri "delivery_line_items(/:id)"
5
+ include_root_in_json :delivery_line_item
6
+
7
+ # Attributes
8
+ attributes :amount, :created_at, :updated_at
9
+
10
+ # Associations
11
+ belongs_to :delivery, class_name: "Zaikio::Procurement::Delivery",
12
+ uri: nil
13
+ has_one :order_line_item, class_name: "Zaikio::Procurement::OrderLineItem",
14
+ uri: nil
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class Invoice < Base
4
+ uri "invoices(/:id)"
5
+ include_root_in_json :invoice
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class MaterialRequirement < Base
4
+ uri "material_requirements(/:id)"
5
+ include_root_in_json :material_requirement
6
+
7
+ # Attributes
8
+ attributes :amount, :anticipated_costs, :archived_at, :archived_by, :article_category, :canceled_at, :currency,
9
+ :description, :environmental_certification, :expected_at, :fulfilled_at, :material_required_at,
10
+ :ordered_at, :order_number, :person, :price, :purchaser, :price_based_on_quantity, :processed_at,
11
+ :references, :state, :unit, :created_at, :updated_at
12
+
13
+ # Associations
14
+ has_one :supplier, class_name: "Zaikio::Procurement::Supplier", uri: nil
15
+ has_one :variant, class_name: "Zaikio::Procurement::Variant", uri: nil
16
+ has_many :order_line_items, class_name: "Zaikio::Procurement::OrderLineItem", uri: nil
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class Order < Base
4
+ uri "orders(/:id)"
5
+ include_root_in_json :order
6
+
7
+ # Attributes
8
+ attributes :canceled_by_consumer_at, :canceled_by_supplier_at, :cancelation_requested_at, :confirmed_at,
9
+ :currency, :delivery_mode, :gross_total, :net_handling_fee, :net_shipping_fee, :net_total,
10
+ :partially_shipped_at, :partially_shipped_remainder_canceled_at, :placed_at, :producing_at,
11
+ :references, :shipped_at, :state, :state_reason, :taxes, :taxes_on_fees, :transfer_failed_at,
12
+ :transferred_at, :contract_id, :exclusive_sales_group_id, :person_id, :created_at, :updated_at
13
+
14
+ # Associations
15
+ has_one :contract, class_name: "Zaikio::Procurement::Contract",
16
+ uri: "contracts(/:id)"
17
+ has_one :exclusive_sales_group, class_name: "Zaikio::Procurement::SalesGroup",
18
+ uri: "sales_groups(/:id)"
19
+ has_many :order_line_items, class_name: "Zaikio::Procurement::OrderLineItem",
20
+ uri: "orders/:order_id/order_line_items(/:id)"
21
+ has_many :deliveries, class_name: "Zaikio::Procurement::Delivery",
22
+ uri: "orders/:order_id/deliveries(/:id)"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class OrderLineItem < Base
4
+ uri "order_line_items(/:id)"
5
+ include_root_in_json :order_line_item
6
+
7
+ # Attributes
8
+ attributes :amount, :amount_in_base_unit, :base_unit, :catalog_price, :confirmed_price, :description,
9
+ :order_number, :tax_rate, :taxes, :total_gross_price, :total_net_price, :unit, :order_id,
10
+ :sku_id, :created_at, :updated_at
11
+
12
+ # Associations
13
+ belongs_to :order, class_name: "Zaikio::Procurement::Order",
14
+ uri: nil
15
+ has_one :sku, class_name: "Zaikio::Procurement::Sku",
16
+ uri: nil
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class Price < Base
4
+ uri "prices(/:id)"
5
+ include_root_in_json :price
6
+
7
+ # Attributes
8
+ attributes :kind, :minimum_order_quantity, :order_number, :price, :valid_from,
9
+ :valid_until, :sales_group_id, :sku_id, :created_at, :updated_at
10
+
11
+ # Associations
12
+ has_one :sku, class_name: "Zaikio::Procurement::Sku",
13
+ uri: nil
14
+ has_one :sales_group, class_name: "Zaikio::Procurement::SalesGroup",
15
+ uri: nil
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class SalesGroup < Base
4
+ uri "sales_groups(/:id)"
5
+ include_root_in_json :sales_group
6
+
7
+ # Attributes
8
+ attributes :currency, :exclusive, :name, :created_at, :updated_at
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class SalesGroupMembership < Base
4
+ uri "sales_group_memberships(/:id)"
5
+ include_root_in_json :sales_group_membership
6
+
7
+ # Attributes
8
+ attributes :contract, :sales_group, :created_at, :updated_at
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class Sku < Base
4
+ uri "skus(/:id)"
5
+ include_root_in_json :sku
6
+
7
+ # Attributes
8
+ attributes :amount, :amount_in_base_unit, :availability_in_days, :dimension_unit,
9
+ :environmental_certification, :gross_weight, :height, :length, :net_weight,
10
+ :order_number, :unit, :weight_unit, :width, :variant_id, :created_at, :updated_at
11
+
12
+ # Associations
13
+ has_many :prices, class_name: "Zaikio::Procurement::Price",
14
+ uri: "skus/:sku_id/prices"
15
+
16
+ # Manually build variant association to work for consumers and suppliers
17
+ def variant
18
+ path = if Zaikio::Procurement.configuration.flavor == :supplier
19
+ "substrate/variants/#{variant_id}"
20
+ else
21
+ "variants/#{variant_id}"
22
+ end
23
+
24
+ Zaikio::Procurement::Variant.new(self.class.request(:get, path).data)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,38 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class SubstrateSearch
4
+ def initialize(query = nil, options = {})
5
+ @query = query
6
+ @supplier = options.delete(:supplier_id)
7
+ @options = options
8
+ @article_type = "substrate"
9
+
10
+ unless @options.respond_to?(:stringify_keys)
11
+ raise ArgumentError, "When using additional search parameters, you must pass a hash as an argument."
12
+ end
13
+
14
+ @response = Zaikio::Procurement::Base.with(path).get
15
+ end
16
+
17
+ def results
18
+ @response.results.collect { |variant| Zaikio::Procurement::Variant.new(variant) }
19
+ end
20
+
21
+ def facets
22
+ @response.facets
23
+ end
24
+
25
+ private
26
+
27
+ def path
28
+ String.new(@article_type).tap do |qp|
29
+ qp << "/#{@supplier}" if @supplier
30
+ qp << "/variants/search?"
31
+ qp << "query=#{@query}" if @query
32
+ qp << "&" if @query && @options.any?
33
+ qp << @options.to_query if @options
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,54 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class Supplier < Base
4
+ uri "suppliers(/:id)"
5
+
6
+ # Attributes
7
+ attributes :automatically_accept_contract_requests, :brand_color, :cancelation_policy, :display_name,
8
+ :slug, :supports_split_delivery, :created_at, :updated_at
9
+
10
+ # Associations
11
+ has_many :contract_requests, class_name: "Zaikio::Procurement::ContractRequest",
12
+ uri: "suppliers/:supplier_id/contract_requests(/:id)"
13
+
14
+ def line_item_suggestions(**attributes)
15
+ variants = attributes.delete(:variants)
16
+
17
+ unless variants.is_a?(Array) && variants.all?(Hash)
18
+ raise ArgumentError, "For variants, you must pass an Array of Hashes"
19
+ end
20
+
21
+ self.class.request(
22
+ :post, line_item_suggestions_path, payload(attributes, variants)
23
+ ).data.deep_symbolize_keys
24
+ end
25
+
26
+ private
27
+
28
+ def payload(attributes, variants)
29
+ MultiJson.dump(
30
+ line_item_suggestions: {
31
+ exclusive_sales_group_id: attributes[:exclusive_sales_group_id],
32
+ variants: variant_payload(variants)
33
+ }.reject { |_k, v| v.blank? }
34
+ )
35
+ end
36
+
37
+ def variant_payload(variants)
38
+ variants.collect do |variant|
39
+ {
40
+ id: variant[:id],
41
+ amount: variant[:amount],
42
+ exact_amount: variant[:exact_amount] || false,
43
+ environmental_certification: variant[:environmental_certification],
44
+ unit: variant[:unit] || "sheet"
45
+ }
46
+ end
47
+ end
48
+
49
+ def line_item_suggestions_path
50
+ "suppliers/#{id}/line_item_suggestions"
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,47 @@
1
+ module Zaikio
2
+ module Procurement
3
+ class Variant < Base
4
+ include_root_in_json :variant
5
+
6
+ # Spyke URI override
7
+ def self.uri
8
+ Zaikio::Procurement.configuration.flavor == :supplier ? "substrate/variants(/:id)" : "variants(/:id)"
9
+ end
10
+
11
+ # Attributes
12
+ attributes :brightness, :category, :color, :dimensions_unit, :form, :grain, :height, :paper_weight,
13
+ :paper_weight_unit, :roughness, :thickness, :transparency, :unit_system, :whiteness,
14
+ :width, :article_id, :created_at, :updated_at
15
+
16
+ # Associations
17
+ has_one :article, class_name: "Zaikio::Procurement::Article",
18
+ uri: nil
19
+ has_many :skus, class_name: "Zaikio::Procurement::Sku",
20
+ uri: "variants/:variant_id/skus"
21
+
22
+ def line_item_suggestion(**attributes)
23
+ self.class.request(
24
+ :post, line_item_suggestions_path, payload(attributes)
25
+ ).data.map(&:deep_symbolize_keys)
26
+ end
27
+
28
+ private
29
+
30
+ def line_item_suggestions_path
31
+ "variants/#{id}/line_item_suggestions"
32
+ end
33
+
34
+ def payload(attributes)
35
+ MultiJson.dump(
36
+ line_item_suggestion: {
37
+ amount: attributes[:amount] || 1,
38
+ unit: attributes[:unit],
39
+ exact_amount: attributes[:exact_amount],
40
+ environmental_certification: attributes[:environmental_certification],
41
+ exclusive_sales_group_id: attributes[:exclusive_sales_group_id]
42
+ }
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,5 @@
1
+ module Zaikio
2
+ module Procurement
3
+ VERSION = "0.1.0".freeze
4
+ end
5
+ end
@@ -0,0 +1,64 @@
1
+ require "faraday"
2
+ require "spyke"
3
+ require "zaikio-client-helpers"
4
+ require "zaikio/procurement/configuration"
5
+ require "zaikio/procurement/authorization_middleware"
6
+
7
+ # Models
8
+ require "zaikio/procurement/base"
9
+ require "zaikio/procurement/article"
10
+ require "zaikio/procurement/variant"
11
+ require "zaikio/procurement/substrate_search"
12
+ require "zaikio/procurement/sku"
13
+ require "zaikio/procurement/price"
14
+ require "zaikio/procurement/supplier"
15
+ require "zaikio/procurement/contract"
16
+ require "zaikio/procurement/contract_request"
17
+ require "zaikio/procurement/sales_group"
18
+ require "zaikio/procurement/sales_group_membership"
19
+ require "zaikio/procurement/order"
20
+ require "zaikio/procurement/order_line_item"
21
+ require "zaikio/procurement/delivery"
22
+ require "zaikio/procurement/delivery_line_item"
23
+ require "zaikio/procurement/current_supplier"
24
+ require "zaikio/procurement/material_requirement"
25
+ module Zaikio
26
+ module Procurement
27
+ class << self
28
+ attr_accessor :configuration
29
+
30
+ class_attribute :connection
31
+
32
+ def configure
33
+ self.connection = nil
34
+ self.configuration ||= Configuration.new
35
+ yield(configuration)
36
+
37
+ Base.connection = create_connection
38
+ end
39
+
40
+ def with_token(token)
41
+ AuthorizationMiddleware.token = token
42
+ yield
43
+ ensure
44
+ AuthorizationMiddleware.reset_token
45
+ end
46
+
47
+ def connection_path
48
+ "#{configuration.host}/#{configuration.flavor.to_s.pluralize}/api/v1/"
49
+ end
50
+
51
+ def create_connection
52
+ self.connection = Faraday.new(url: connection_path,
53
+ ssl: { verify: configuration.environment != :test }) do |c|
54
+ c.request :json
55
+ c.response :logger, configuration&.logger, headers: false
56
+ c.use Zaikio::Client::Helpers::Pagination::FaradayMiddleware
57
+ c.use Zaikio::Client::Helpers::JSONParser
58
+ c.use AuthorizationMiddleware
59
+ c.adapter Faraday.default_adapter
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zaikio-procurement
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Zaikio GmbH
8
+ - Sascha Weidlich
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2021-10-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: concurrent-ruby
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: jwt
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: multi_json
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: oj
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: spyke
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: zaikio-client-helpers
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '0.2'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '0.2'
98
+ description: Ruby API Client for Zaikio's Procurement Platform
99
+ email:
100
+ - sw@zaikio.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - MIT-LICENSE
106
+ - README.md
107
+ - Rakefile
108
+ - lib/zaikio/procurement.rb
109
+ - lib/zaikio/procurement/article.rb
110
+ - lib/zaikio/procurement/authorization_middleware.rb
111
+ - lib/zaikio/procurement/base.rb
112
+ - lib/zaikio/procurement/configuration.rb
113
+ - lib/zaikio/procurement/contract.rb
114
+ - lib/zaikio/procurement/contract_request.rb
115
+ - lib/zaikio/procurement/current_supplier.rb
116
+ - lib/zaikio/procurement/delivery.rb
117
+ - lib/zaikio/procurement/delivery_line_item.rb
118
+ - lib/zaikio/procurement/invoice.rb
119
+ - lib/zaikio/procurement/material_requirement.rb
120
+ - lib/zaikio/procurement/order.rb
121
+ - lib/zaikio/procurement/order_line_item.rb
122
+ - lib/zaikio/procurement/price.rb
123
+ - lib/zaikio/procurement/sales_group.rb
124
+ - lib/zaikio/procurement/sales_group_membership.rb
125
+ - lib/zaikio/procurement/sku.rb
126
+ - lib/zaikio/procurement/substrate_search.rb
127
+ - lib/zaikio/procurement/supplier.rb
128
+ - lib/zaikio/procurement/variant.rb
129
+ - lib/zaikio/procurement/version.rb
130
+ homepage: https://www.zaikio.com/
131
+ licenses:
132
+ - MIT
133
+ metadata:
134
+ changelog_uri: https://github.com/zaikio/zaikio-procurement-ruby/blob/master/CHANGELOG.md
135
+ source_code_uri: https://github.com/zaikio/zaikio-procurement-ruby
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: 2.7.1
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubygems_version: 3.1.4
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: Ruby API Client for Zaikio's Procurement Platform
155
+ test_files: []