magento 0.12.0 → 0.15.1

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.
@@ -2,10 +2,13 @@
2
2
 
3
3
  require 'time'
4
4
  require 'dry/inflector'
5
+ require 'active_support/core_ext/string/inflections'
6
+ require 'active_support/core_ext/hash/keys'
5
7
 
6
8
  require_relative 'magento/errors'
7
9
  require_relative 'magento/request'
8
10
  require_relative 'magento/model_mapper'
11
+ require_relative 'magento/params'
9
12
  require_relative 'magento/polymorphic_model'
10
13
  require_relative 'magento/model'
11
14
  require_relative 'magento/record_collection'
@@ -20,6 +23,7 @@ require_relative 'magento/guest_cart'
20
23
  require_relative 'magento/sales_rule'
21
24
 
22
25
  Dir[File.expand_path('magento/shared/*.rb', __dir__)].map { |f| require f }
26
+ Dir[File.expand_path('magento/params/*.rb', __dir__)].map { |f| require f }
23
27
 
24
28
  module Magento
25
29
  class << self
@@ -38,12 +42,12 @@ module Magento
38
42
  self.token = ENV['MAGENTO_TOKEN']
39
43
  self.store = ENV['MAGENTO_STORE'] || :all
40
44
 
41
- def self.with_config(utl: Magento.url, token: Magento.token, store: Magento.store)
45
+ def self.with_config(url: Magento.url, token: Magento.token, store: Magento.store)
42
46
  @old_url = self.url
43
47
  @old_token = self.token
44
48
  @old_store = self.store
45
-
46
- self.url = utl
49
+
50
+ self.url = url
47
51
  self.token = token
48
52
  self.store = store
49
53
 
@@ -32,6 +32,29 @@ module Magento
32
32
  self.class.payment_information(attributes)
33
33
  end
34
34
 
35
+ #
36
+ # Add a coupon by code to the current cart.
37
+ #
38
+ # Example
39
+ # cart = Magento::GuestCart.find('gXsepZcgJbY8RCJXgGioKOO9iBCR20r7')
40
+ # cart.add_coupon('COAU4HXE0I')
41
+ #
42
+ # @return Boolean: true on success, false otherwise
43
+ def add_coupon(coupon)
44
+ self.class.add_coupon(cart_id, coupon)
45
+ end
46
+
47
+ # Delete cart's coupon
48
+ #
49
+ # Example:
50
+ # cart = Magento::GuestCart.find('gXsepZcgJbY8RCJXgGioKOO9iBCR20r7')
51
+ # cart.delete_coupon()
52
+ #
53
+ # @return Boolean: true on success, raise exception otherwise
54
+ def delete_coupon
55
+ self.class.delete_coupon(cart_id)
56
+ end
57
+
35
58
  class << self
36
59
  def create(load_cart_info: false)
37
60
  cart = build(cart_id: request.post(api_resource).parse)
@@ -64,6 +87,33 @@ module Magento
64
87
  hash = request.post(url, attributes).parse
65
88
  Magento::ModelMapper.map_hash(Magento::Item, hash)
66
89
  end
90
+
91
+ #
92
+ # Add a coupon by code to a specified cart.
93
+ #
94
+ # Example
95
+ # Magento::GuestCart.add_coupon(
96
+ # 'aj8oUtY1Qi44Fror6UWVN7ftX1idbBKN',
97
+ # 'COAU4HXE0I'
98
+ # )
99
+ #
100
+ # @return Boolean: true on success, false otherwise
101
+ def add_coupon(id, coupon)
102
+ url = "#{api_resource}/#{id}/coupons/#{coupon}"
103
+ request.put(url, nil).parse
104
+ end
105
+
106
+ #
107
+ # Delete a coupon from a specified cart.
108
+ #
109
+ # Example:
110
+ # Magento::GuestCart.delete_coupon('aj8oUtY1Qi44Fror6UWVN7ftX1idbBKN')
111
+ #
112
+ # @return Boolean: true on success, raise exception otherwise
113
+ def delete_coupon(id)
114
+ url = "#{api_resource}/#{id}/coupons"
115
+ request.delete(url).parse
116
+ end
67
117
  end
68
118
  end
69
119
  end
@@ -0,0 +1,9 @@
1
+ require 'dry/struct'
2
+
3
+ module Magento
4
+ module Params
5
+ module Type
6
+ include Dry.Types()
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magento
4
+ module Params
5
+ class CreateCategoria < Dry::Struct
6
+ attribute :name, Type::String
7
+ attribute :parent_id, Type::String.optional
8
+ attribute :path, Type::String.optional
9
+ attribute :is_active, Type::Bool.default(true)
10
+
11
+ def to_h
12
+ {
13
+ "name": name,
14
+ "parent_id": parent_id,
15
+ "is_active": is_active,
16
+ "path": path
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magento
4
+ module Params
5
+ class CreateCustomAttribute < Dry::Struct
6
+ attribute :code, Type::String
7
+ attribute :value, Type::String
8
+
9
+ def to_h
10
+ {
11
+ "attribute_code": code,
12
+ "value": value
13
+ }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open-uri'
4
+ require 'mini_magick'
5
+
6
+ module Magento
7
+ module Params
8
+ class CreateImage < Dry::Struct
9
+ VARIANTS = {
10
+ 'large' => { size: '800x800', type: :image },
11
+ 'medium' => { size: '300x300', type: :small_image },
12
+ 'small' => { size: '100x100', type: :thumbnail }
13
+ }.freeze
14
+
15
+ attribute :title, Type::String
16
+ attribute :path, Type::String
17
+ attribute :position, Type::Integer
18
+ attribute :size, Type::String.default('large').enum(*VARIANTS.keys)
19
+ attribute :disabled, Type::Bool.default(false)
20
+ attribute :main, Type::Bool.default(false)
21
+
22
+ def to_h
23
+ {
24
+ "disabled": disabled,
25
+ "media_type": 'image',
26
+ "label": title,
27
+ "position": position,
28
+ "content": {
29
+ "base64_encoded_data": base64,
30
+ "type": mini_type,
31
+ "name": filename
32
+ },
33
+ "types": main ? [VARIANTS[size][:type]] : []
34
+ }
35
+ end
36
+
37
+ def variants
38
+ VARIANTS.keys.map do |size|
39
+ CreateImage.new(attributes.merge(size: size, disabled: size != 'large'))
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def base64
46
+ Base64.strict_encode64(File.open(file.path).read).to_s
47
+ end
48
+
49
+ def file
50
+ @file ||= MiniMagick::Image.open(path).tap do |b|
51
+ b.resize VARIANTS[size][:size]
52
+ b.strip
53
+ end
54
+ end
55
+
56
+ def filename
57
+ title.parameterize
58
+ end
59
+
60
+ def mini_type
61
+ file.mime_type
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,147 @@
1
+ require_relative 'create_image'
2
+ require_relative 'create_custom_attribute'
3
+
4
+ module Magento
5
+ module Params
6
+ # Example
7
+ #
8
+ # params = Magento::Params::CreateProduct.new(
9
+ # sku: '556-teste-builder',
10
+ # name: 'REFRIGERANTE PET COCA-COLA 1,5L ORIGINAL',
11
+ # description: 'Descrição do produto',
12
+ # brand: 'Coca-Cola',
13
+ # price: 4.99,
14
+ # special_price: 3.49,
15
+ # quantity: 2,
16
+ # weight: 0.3,
17
+ # attribute_set_id: 4,
18
+ # images: [
19
+ # *Magento::Params::CreateImage.new(
20
+ # path: 'https://urltoimage.com/image.jpg',
21
+ # title: 'REFRIGERANTE PET COCA-COLA 1,5L ORIGINAL',
22
+ # position: 0,
23
+ # main: true
24
+ # ).variants, # it's generate all variants thumbnail => '100x100', small_image => '300x300' and image => '800x800'
25
+ # Magento::Params::CreateImage.new(
26
+ # path: '/path/to/image.jpg',
27
+ # title: 'REFRIGERANTE PET COCA-COLA 1,5L ORIGINAL',
28
+ # position: 1
29
+ # )
30
+ # ]
31
+ # )
32
+ #
33
+ # Magento::Product.create(params.to_h)
34
+ #
35
+ class CreateProduct < Dry::Struct
36
+ ProductTypes = Type::String.default('simple'.freeze).enum(
37
+ 'simple',
38
+ 'bundle',
39
+ 'configurable',
40
+ 'downloadable',
41
+ 'grouped',
42
+ 'Virtual'
43
+ )
44
+
45
+ Visibilities = Type::String.default('catalog_and_search'.freeze).enum(
46
+ 'not_visible_individually' => 1,
47
+ 'catalog' => 1,
48
+ 'search' => 3,
49
+ 'catalog_and_search' => 4
50
+ )
51
+
52
+ Statuses = Type::String.default('enabled'.freeze).enum('enabled' => 1, 'disabled' => 2)
53
+
54
+ attribute :sku, Type::String
55
+ attribute :name, Type::String
56
+ attribute :description, Type::String
57
+ attribute :brand, Type::String
58
+ attribute :price, Type::Coercible::Float
59
+ attribute :special_price, Type::Float.optional.default(nil)
60
+ attribute :attribute_set_id, Type::Integer
61
+ attribute :status, Statuses
62
+ attribute :visibility, Visibilities
63
+ attribute :type_id, ProductTypes
64
+ attribute :weight, Type::Coercible::Float
65
+ attribute :quantity, Type::Coercible::Float
66
+ attribute :featured, Type::String.default('0'.freeze).enum('0', '1')
67
+ attribute :is_qty_decimal, Type::Bool.default(false)
68
+ attribute :manage_stock, Type::Bool.default(true)
69
+ attribute :category_ids, Type::Array.of(Type::Integer).default([].freeze)
70
+ attribute :images, Type::Array.of(Type::Instance(CreateImage)).default([].freeze)
71
+ attribute :website_ids, Type::Array.of(Type::Integer).default([0].freeze)
72
+ attribute :custom_attributes, Type::Array.default([], shared: true) do
73
+ attribute :attribute_code, Type::String
74
+ attribute :value, Type::Coercible::String
75
+ end
76
+
77
+ alias orig_custom_attributes custom_attributes
78
+
79
+ def to_h
80
+ {
81
+ sku: sku,
82
+ name: name.titlecase,
83
+ price: price,
84
+ status: Statuses.mapping[status],
85
+ visibility: Visibilities.mapping[visibility],
86
+ type_id: type_id,
87
+ weight: weight,
88
+ attribute_set_id: attribute_set_id,
89
+ extension_attributes: {
90
+ website_ids: website_ids,
91
+ category_links: categories,
92
+ stock_item: stock
93
+ },
94
+ media_gallery_entries: images.map(&:to_h),
95
+ custom_attributes: custom_attributes.map(&:to_h)
96
+ }
97
+ end
98
+
99
+ def stock
100
+ {
101
+ qty: quantity,
102
+ is_in_stock: quantity.to_i > 0,
103
+ is_qty_decimal: is_qty_decimal,
104
+ show_default_notification_message: false,
105
+ use_config_min_qty: true,
106
+ min_qty: 1,
107
+ use_config_min_sale_qty: 0,
108
+ min_sale_qty: 0,
109
+ use_config_max_sale_qty: true,
110
+ max_sale_qty: 0,
111
+ use_config_backorders: true,
112
+ backorders: 0,
113
+ use_config_notify_stock_qty: true,
114
+ notify_stock_qty: 0,
115
+ use_config_qty_increments: true,
116
+ qty_increments: 0,
117
+ use_config_enable_qty_inc: true,
118
+ enable_qty_increments: true,
119
+ use_config_manage_stock: manage_stock,
120
+ manage_stock: manage_stock,
121
+ low_stock_date: 'string',
122
+ is_decimal_divided: is_qty_decimal,
123
+ stock_status_changed_auto: 0
124
+ }
125
+ end
126
+
127
+ def custom_attributes
128
+ default_attributes = [
129
+ CustomAttribute.new(attribute_code: 'description', value: description),
130
+ CustomAttribute.new(attribute_code: 'url_key', value: name.parameterize ),
131
+ CustomAttribute.new(attribute_code: 'product_brand', value: brand ),
132
+ CustomAttribute.new(attribute_code: 'featured', value: featured)
133
+ ]
134
+
135
+ if special_price.to_f > 0
136
+ default_attributes << CustomAttribute.new(attribute_code: 'special_price', value: special_price.to_s)
137
+ end
138
+
139
+ default_attributes + orig_custom_attributes
140
+ end
141
+
142
+ def categories
143
+ category_ids.map { |c| { "category_id": c, "position": 0 } }
144
+ end
145
+ end
146
+ end
147
+ end
@@ -2,6 +2,20 @@ module Magento
2
2
  class Product < Model
3
3
  self.primary_key = :sku
4
4
 
5
+ def method_missing(m)
6
+ attr(m) || super
7
+ end
8
+
9
+ # returns custom_attribute value by custom_attribute code
10
+ # return nil if custom_attribute is not present
11
+ def attr(attribute_code)
12
+ @custom_attributes&.find { |a| a.attribute_code == attribute_code.to_s }&.value
13
+ end
14
+
15
+ def respond_to?(attribute_code)
16
+ super || @custom_attributes&.any? { |a| a.attribute_code == attribute_code.to_s }
17
+ end
18
+
5
19
  class << self
6
20
  alias_method :find_by_sku, :find
7
21
  end
@@ -85,8 +85,11 @@ module Magento
85
85
 
86
86
  def all
87
87
  result = request.get("#{endpoint}?#{query_params}").parse
88
- field = model == Magento::Category ? 'children_data' : 'items'
89
- RecordCollection.from_magento_response(result, model: model, iterable_field: field)
88
+ if model == Magento::Category
89
+ model.build(result)
90
+ else
91
+ RecordCollection.from_magento_response(result, model: model)
92
+ end
90
93
  end
91
94
 
92
95
  def first
@@ -69,7 +69,7 @@ module Magento
69
69
 
70
70
  def save_request(method, url, body = nil)
71
71
  begin
72
- body = body[:product].reject { |e| e == :media_gallery_entries }
72
+ body = body.symbolize_keys[:product].reject { |e| e == :media_gallery_entries }
73
73
  rescue StandardError
74
74
  end
75
75
 
@@ -1,3 +1,3 @@
1
1
  module Magento
2
- VERSION = '0.12.0'
2
+ VERSION = '0.15.1'
3
3
  end
@@ -19,4 +19,7 @@ Gem::Specification.new do |s|
19
19
 
20
20
  s.add_dependency 'dry-inflector', '~> 0.2.0'
21
21
  s.add_dependency 'http', '~> 4.4'
22
+ s.add_dependency 'dry-struct'
23
+ s.add_dependency 'activesupport'
24
+ s.add_dependency 'mini_magick'
22
25
  end
@@ -19,4 +19,7 @@ Gem::Specification.new do |s|
19
19
 
20
20
  s.add_dependency 'http', '~> 4.4'
21
21
  s.add_dependency 'dry-inflector', '~> 0.2.0'
22
+ s.add_dependency 'dry-struct'
23
+ s.add_dependency 'activesupport'
24
+ s.add_dependency 'mini_magick'
22
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magento
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wallas Faria
@@ -38,6 +38,48 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-struct
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mini_magick
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
41
83
  description: Magento Ruby library
42
84
  email: wallasfaria@hotmail.com
43
85
  executables: []
@@ -58,6 +100,11 @@ files:
58
100
  - lib/magento/model.rb
59
101
  - lib/magento/model_mapper.rb
60
102
  - lib/magento/order.rb
103
+ - lib/magento/params.rb
104
+ - lib/magento/params/create_category.rb
105
+ - lib/magento/params/create_custom_attribute.rb
106
+ - lib/magento/params/create_image.rb
107
+ - lib/magento/params/create_product.rb
61
108
  - lib/magento/polymorphic_model.rb
62
109
  - lib/magento/product.rb
63
110
  - lib/magento/query.rb