magento 0.13.0 → 0.16.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77636870e263ab5add82976ce07571f75de8d2e70aa89d7e5a371366868e2400
4
- data.tar.gz: 0ccf949f28c60fd7eefb8e3388429edeab872d18c9855088c5a6183b947dc9f7
3
+ metadata.gz: 54c756e43ba125d24cfd2695f5b3b362acf6a489cb0ccc7b7abd853b8488164c
4
+ data.tar.gz: 103375f7ba57dae9d78e93d19e0cb95d6192365390b4d05005c465eea6737908
5
5
  SHA512:
6
- metadata.gz: b685a13443e7c996a69a5079c29baccc26ff16fb3d6a630b94e07b21efec5f5f35a93ec36de7986f4881c36791d8a0cb59578cc1c7aaa7e29bf1393b5176a863
7
- data.tar.gz: 97ff1f26eef308c00d19c608045eee47c2a43cc254ca3cfd6cc06fc59853aa16a16e23241f45cffe9aaa5cb7625b456c37dcd58d79dd1959ae155a748582c0dd
6
+ metadata.gz: d839bf8cc47b2a7e639de881d2e8505cd8b3bb2d52428a1e8c58438e96e3bbf84392ccf22498b393a5ec60b812afca078e9f2cd33568f2475081501601f0c919
7
+ data.tar.gz: 3192fd700e6356b0a58039b26fe8c5b25ab577328d67cce6a4495465f84c4dc9f6aa48e37cacbaafc7068b61ac91a983fe7b41287ff4316920b09951079a0dcf
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  Add in your Gemfile
6
6
 
7
7
  ```rb
8
- gem 'magento', '~> 0.13.0'
8
+ gem 'magento', '~> 0.15.1'
9
9
  ```
10
10
 
11
11
  or run
@@ -339,6 +339,28 @@ cart.payment_information(
339
339
  >> "234575" # return the order id
340
340
  ```
341
341
 
342
+ Add coupon to cart
343
+ ```rb
344
+ cart = Magento::GuestCart.find('gXsepZcgJbY8RCJXgGioKOO9iBCR20r7')
345
+
346
+ cart.add_coupon('COAU4HXE0I')
347
+ # You can also use the class method
348
+ Magento::GuestCart.add_coupon('gXsepZcgJbY8RCJXgGioKOO9iBCR20r7', 'COAU4HXE0I')
349
+
350
+ >> true # return true on success
351
+ ```
352
+
353
+ Delete coupon from cart
354
+ ```rb
355
+ cart = Magento::GuestCart.find('gXsepZcgJbY8RCJXgGioKOO9iBCR20r7')
356
+
357
+ cart.delete_coupon()
358
+ # You can also use the class method
359
+ Magento::GuestCart.delete_coupon('gXsepZcgJbY8RCJXgGioKOO9iBCR20r7')
360
+
361
+ >> true # return true on success
362
+ ```
363
+
342
364
  ## Invoice an Order
343
365
 
344
366
  ```rb
@@ -540,7 +562,7 @@ rule = Magento::SalesRule.create(
540
562
  rule.generate_coupon(quantity: 1, length: 10)
541
563
  ```
542
564
 
543
- Renarate by class method
565
+ Generate by class method
544
566
  ```rb
545
567
  Magento::SalesRule.generate_coupon(
546
568
  couponSpec: {
@@ -553,6 +575,8 @@ Magento::SalesRule.generate_coupon(
553
575
  see all params in:
554
576
  - [Magento docs Coupon](https://magento.redoc.ly/2.3.5-admin/tag/couponsgenerate#operation/salesRuleCouponManagementV1GeneratePost)
555
577
  - [Magento docs SalesRules](https://magento.redoc.ly/2.3.5-admin/tag/salesRules#operation/salesRuleRuleRepositoryV1SavePost)
578
+
579
+ See [how to add coupons to cart](#guestcart)
556
580
 
557
581
  ### First result
558
582
  ```rb
@@ -21,6 +21,7 @@ require_relative 'magento/order'
21
21
  require_relative 'magento/invoice'
22
22
  require_relative 'magento/guest_cart'
23
23
  require_relative 'magento/sales_rule'
24
+ require_relative 'magento/import'
24
25
 
25
26
  Dir[File.expand_path('magento/shared/*.rb', __dir__)].map { |f| require f }
26
27
  Dir[File.expand_path('magento/params/*.rb', __dir__)].map { |f| require f }
@@ -42,12 +43,12 @@ module Magento
42
43
  self.token = ENV['MAGENTO_TOKEN']
43
44
  self.store = ENV['MAGENTO_STORE'] || :all
44
45
 
45
- def self.with_config(utl: Magento.url, token: Magento.token, store: Magento.store)
46
+ def self.with_config(url: Magento.url, token: Magento.token, store: Magento.store)
46
47
  @old_url = self.url
47
48
  @old_token = self.token
48
49
  @old_store = self.store
49
-
50
- self.url = utl
50
+
51
+ self.url = url
51
52
  self.token = token
52
53
  self.store = store
53
54
 
@@ -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,13 @@
1
+ require_relative 'import/csv_reader'
2
+ require_relative 'import/category'
3
+ require_relative 'import/product'
4
+
5
+ module Magento
6
+ module Import
7
+ def self.from_csv(file, image_path:, website_ids: [0])
8
+ products = CSVReader.new(file).get_products
9
+ products = Category.new(products).associate
10
+ Product.new(image_path, website_ids).import(products)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,51 @@
1
+ module Magento
2
+ module Import
3
+ class Category
4
+ def initialize(products)
5
+ @products = products
6
+ @category_root = Magento::Category.all
7
+ @cats = @category_root.children_data
8
+ end
9
+
10
+ def associate
11
+ @products.each do |prod|
12
+ cat1 = find_or_create(name: prod.cat1, parent: @category_root) if prod.cat1
13
+ cat2 = find_or_create(name: prod.cat2, parent: cat1) if prod.cat2
14
+ cat3 = find_or_create(name: prod.cat3, parent: cat2) if prod.cat3
15
+
16
+ prod.cat1, prod.cat2, prod.cat3 = cat1&.id, cat2&.id, cat3&.id
17
+
18
+ @cats.push(*[cat1, cat2, cat3].compact)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def find_or_create(name:, parent:)
25
+ find(name, cats: @cats, parent_id: parent.id) || create(name, parent: parent)
26
+ end
27
+
28
+ def find(name, cats:, parent_id:)
29
+ cats.each do |cat|
30
+ return cat if cat.name == name && cat.parent_id == parent_id
31
+
32
+ if cat.respond_to?(:children_data) && cat.children_data&.size.to_i > 0
33
+ result = find(name, cats: cat.children_data, parent_id: parent_id)
34
+ return result if result
35
+ end
36
+ end
37
+ nil
38
+ end
39
+
40
+ def create(name, parent:)
41
+ params = Magento::Params::CreateCategoria.new(
42
+ name: name,
43
+ parent_id: parent.id,
44
+ url: "#{Magento.store}-#{parent.id}-#{name.parameterize}"
45
+ )
46
+
47
+ Magento::Category.create(params.to_h).tap { |c| puts "Create: #{c.id} => #{c.name}" }
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,30 @@
1
+ require 'csv'
2
+ require 'ostruct'
3
+
4
+ module Magento
5
+ module Import
6
+ class CSVReader
7
+ def initialize(csv_file)
8
+ @csv = CSV.read(csv_file, col_sep: ';')
9
+ end
10
+
11
+ def get_products
12
+ @csv[1..].map do |row|
13
+ name, sku, ean, description, price, special_price, quantity, cat1, cat2, cat3 = row
14
+ OpenStruct.new({
15
+ name: name,
16
+ sku: sku,
17
+ ean: ean,
18
+ description: description,
19
+ price: price,
20
+ special_price: special_price,
21
+ quantity: quantity,
22
+ cat1: cat1,
23
+ cat2: cat2,
24
+ cat3: cat3
25
+ })
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,63 @@
1
+ module Magento
2
+ module Import
3
+ class Product
4
+ def initialize(images_path, website_ids)
5
+ @images_path = images_path
6
+ @website_ids = website_ids
7
+ end
8
+
9
+ def import(products)
10
+ products.each do |product|
11
+ params = Magento::Params::CreateProduct.new(
12
+ sku: product.sku,
13
+ name: product.name.gsub(/[ ]+/, ' '),
14
+ description: product.description || product.name,
15
+ brand: product.brand,
16
+ price: product.price.to_f,
17
+ special_price: product.special_price ? product.special_price.to_f : nil,
18
+ quantity: numeric?(product.quantity) ? product.quantity.to_f : 0,
19
+ weight: 0.3,
20
+ manage_stock: numeric?(product.quantity),
21
+ attribute_set_id: 4,
22
+ category_ids: [product.cat1, product.cat2, product.cat3].compact,
23
+ website_ids: @website_ids,
24
+ images: images(product)
25
+ ).to_h
26
+
27
+ product = Magento::Product.create(params)
28
+
29
+ puts "Produto criado: #{product.sku} => #{product.name}"
30
+ rescue => e
31
+ puts "Erro ao criado: #{product.sku} => #{product.name}"
32
+ puts " - Detalhes do erro: #{e}"
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def images(product)
39
+ image = find_image(product)
40
+ return [] unless image
41
+
42
+ Magento::Params::CreateImage.new(
43
+ path: image,
44
+ title: product.name,
45
+ position: 0,
46
+ main: true
47
+ ).variants
48
+ end
49
+
50
+ def find_image(product)
51
+ prefix = "#{@images_path}/#{product.sku}"
52
+
53
+ extensions = %w[jpg jpeg png webp]
54
+ extensions.map { |e| ["#{prefix}.#{e}", "#{prefix}.#{e.upcase}"] }.flatten
55
+ .find { |file| File.exist?(file) }
56
+ end
57
+
58
+ def numeric?(value)
59
+ !!(value.to_s =~ /^[\d]+$/)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -4,17 +4,17 @@ module Magento
4
4
  module Params
5
5
  class CreateCategoria < Dry::Struct
6
6
  attribute :name, Type::String
7
- attribute :parent_id, Type::String.optional
8
- attribute :path, Type::String.optional
7
+ attribute :parent_id, Type::Integer.optional
8
+ attribute :url, Type::String.optional.default(nil)
9
9
  attribute :is_active, Type::Bool.default(true)
10
10
 
11
11
  def to_h
12
12
  {
13
- "name": name,
14
- "parent_id": parent_id,
15
- "is_active": is_active,
16
- "path": path
17
- }
13
+ name: name,
14
+ parent_id: parent_id,
15
+ is_active: is_active,
16
+ custom_attributes: url ? [{attribute_code: 'url_key', value: url }] : nil
17
+ }.compact
18
18
  end
19
19
  end
20
20
  end
@@ -36,7 +36,7 @@ module Magento
36
36
 
37
37
  def variants
38
38
  VARIANTS.keys.map do |size|
39
- CreateImage.new(attributes.merge(size: size, disabled: size != :large))
39
+ CreateImage.new(attributes.merge(size: size, disabled: size != 'large'))
40
40
  end
41
41
  end
42
42
 
@@ -49,6 +49,7 @@ module Magento
49
49
  def file
50
50
  @file ||= MiniMagick::Image.open(path).tap do |b|
51
51
  b.resize VARIANTS[size][:size]
52
+ b.format 'jpg'
52
53
  b.strip
53
54
  end
54
55
  end
@@ -54,7 +54,7 @@ module Magento
54
54
  attribute :sku, Type::String
55
55
  attribute :name, Type::String
56
56
  attribute :description, Type::String
57
- attribute :brand, Type::String
57
+ attribute :brand, Type::String.optional.default(nil)
58
58
  attribute :price, Type::Coercible::Float
59
59
  attribute :special_price, Type::Float.optional.default(nil)
60
60
  attribute :attribute_set_id, Type::Integer
@@ -116,7 +116,7 @@ module Magento
116
116
  qty_increments: 0,
117
117
  use_config_enable_qty_inc: true,
118
118
  enable_qty_increments: true,
119
- use_config_manage_stock: true,
119
+ use_config_manage_stock: manage_stock,
120
120
  manage_stock: manage_stock,
121
121
  low_stock_date: 'string',
122
122
  is_decimal_divided: is_qty_decimal,
@@ -128,10 +128,11 @@ module Magento
128
128
  default_attributes = [
129
129
  CustomAttribute.new(attribute_code: 'description', value: description),
130
130
  CustomAttribute.new(attribute_code: 'url_key', value: name.parameterize ),
131
- CustomAttribute.new(attribute_code: 'product_brand', value: brand ),
132
131
  CustomAttribute.new(attribute_code: 'featured', value: featured)
133
132
  ]
134
133
 
134
+ default_attributes.push(CustomAttribute.new(attribute_code: 'product_brand', value: brand)) if brand
135
+
135
136
  if special_price.to_f > 0
136
137
  default_attributes << CustomAttribute.new(attribute_code: 'special_price', value: special_price.to_s)
137
138
  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
@@ -53,7 +53,7 @@ module Magento
53
53
 
54
54
  begin
55
55
  msg = resp.parse['message']
56
- errors = resp.parse['errors']
56
+ errors = resp.parse['errors'] || resp.parse['parameters']
57
57
  if resp.parse['parameters'].is_a? Hash
58
58
  resp.parse['parameters'].each { |k, v| msg.sub! "%#{k}", v }
59
59
  end
@@ -1,3 +1,3 @@
1
1
  module Magento
2
- VERSION = '0.13.0'
2
+ VERSION = '0.16.0'
3
3
  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.13.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wallas Faria
@@ -96,6 +96,10 @@ files:
96
96
  - lib/magento/customer.rb
97
97
  - lib/magento/errors.rb
98
98
  - lib/magento/guest_cart.rb
99
+ - lib/magento/import.rb
100
+ - lib/magento/import/category.rb
101
+ - lib/magento/import/csv_reader.rb
102
+ - lib/magento/import/product.rb
99
103
  - lib/magento/invoice.rb
100
104
  - lib/magento/model.rb
101
105
  - lib/magento/model_mapper.rb