magento 0.25.0 → 0.28.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +5 -3
- data/README.md +636 -226
- data/lib/magento.rb +7 -1
- data/lib/magento/cart.rb +65 -0
- data/lib/magento/order.rb +47 -2
- data/lib/magento/params/create_image.rb +43 -0
- data/lib/magento/product.rb +88 -0
- data/lib/magento/query.rb +11 -9
- data/lib/magento/request.rb +6 -1
- data/lib/magento/version.rb +1 -1
- data/spec/magento/core/model_mapper_spec.rb +74 -0
- data/spec/magento/core/model_spec.rb +71 -0
- data/spec/magento/core/query_spec.rb +207 -0
- data/spec/magento/core/record_collection_spec.rb +116 -0
- data/spec/magento/core/request_spec.rb +141 -0
- data/spec/magento/order_spec.rb +37 -0
- data/spec/{product_spec.rb → magento/product_spec.rb} +21 -0
- data/spec/spec_helper.rb +17 -3
- data/spec/vcr_cassettes/order/send_email.yml +65 -0
- data/spec/vcr_cassettes/product/find.yml +72 -0
- metadata +12 -3
data/lib/magento.rb
CHANGED
@@ -25,9 +25,15 @@ require_relative 'magento/guest_cart'
|
|
25
25
|
require_relative 'magento/sales_rule'
|
26
26
|
require_relative 'magento/inventory'
|
27
27
|
require_relative 'magento/import'
|
28
|
+
require_relative 'magento/cart'
|
29
|
+
|
30
|
+
require_relative 'magento/params/create_custom_attribute'
|
31
|
+
require_relative 'magento/params/create_image'
|
32
|
+
require_relative 'magento/params/create_category'
|
33
|
+
require_relative 'magento/params/create_product'
|
34
|
+
require_relative 'magento/params/create_product_link'
|
28
35
|
|
29
36
|
Dir[File.expand_path('magento/shared/*.rb', __dir__)].map { |f| require f }
|
30
|
-
Dir[File.expand_path('magento/params/*.rb', __dir__)].map { |f| require f }
|
31
37
|
|
32
38
|
module Magento
|
33
39
|
class << self
|
data/lib/magento/cart.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Magento
|
4
|
+
class Cart < Model
|
5
|
+
self.endpoint = 'carts'
|
6
|
+
self.primary_key = :id
|
7
|
+
|
8
|
+
#
|
9
|
+
# Add a coupon by code to the current cart.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# cart = Magento::Cart.find(1)
|
14
|
+
# cart.add_coupon('COAU4HXE0I')
|
15
|
+
#
|
16
|
+
# @return Boolean: true on success, false otherwise
|
17
|
+
def add_coupon(coupon)
|
18
|
+
self.class.add_coupon(id, coupon)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Delete cart's coupon
|
23
|
+
#
|
24
|
+
# Example:
|
25
|
+
#
|
26
|
+
# cart = Magento::Cart.find(1)
|
27
|
+
# cart.delete_coupon()
|
28
|
+
#
|
29
|
+
# @return Boolean: true on success, raise exception otherwise
|
30
|
+
def delete_coupon
|
31
|
+
self.class.delete_coupon(id)
|
32
|
+
end
|
33
|
+
|
34
|
+
class << self
|
35
|
+
#
|
36
|
+
# Add a coupon by code to a specified cart.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
#
|
40
|
+
# Magento::Cart.add_coupon(
|
41
|
+
# 1,
|
42
|
+
# 'COAU4HXE0I'
|
43
|
+
# )
|
44
|
+
#
|
45
|
+
# @return Boolean: true on success, false otherwise
|
46
|
+
def add_coupon(id, coupon)
|
47
|
+
url = "#{api_resource}/#{id}/coupons/#{coupon}"
|
48
|
+
request.put(url, nil).parse
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Delete a coupon from a specified cart.
|
53
|
+
#
|
54
|
+
# Example:
|
55
|
+
#
|
56
|
+
# Magento::Cart.delete_coupon(1)
|
57
|
+
#
|
58
|
+
# @return Boolean: true on success, raise exception otherwise
|
59
|
+
def delete_coupon(id)
|
60
|
+
url = "#{api_resource}/#{id}/coupons"
|
61
|
+
request.delete(url).parse
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/magento/order.rb
CHANGED
@@ -34,7 +34,6 @@ module Magento
|
|
34
34
|
self.class.invoice(id, params)
|
35
35
|
end
|
36
36
|
|
37
|
-
|
38
37
|
#
|
39
38
|
# Create offline refund for order
|
40
39
|
#
|
@@ -61,6 +60,26 @@ module Magento
|
|
61
60
|
self.class.ship(id, params)
|
62
61
|
end
|
63
62
|
|
63
|
+
def send_email
|
64
|
+
self.class.send_email(id)
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Creates a comment on the given Order
|
69
|
+
#
|
70
|
+
# order = Magento::Order.find(order_id)
|
71
|
+
#
|
72
|
+
# order.add_comment(
|
73
|
+
# 'comment',
|
74
|
+
# is_customer_notified: 0,
|
75
|
+
# is_visible_on_front: 1
|
76
|
+
# )
|
77
|
+
#
|
78
|
+
# Return true on success
|
79
|
+
def add_comment(comment, comment_params = nil)
|
80
|
+
self.class.add_comment(id, comment, comment_params)
|
81
|
+
end
|
82
|
+
|
64
83
|
class << self
|
65
84
|
def update(entity_id, attributes)
|
66
85
|
attributes[:entity_id] = entity_id
|
@@ -100,7 +119,6 @@ module Magento
|
|
100
119
|
request.post("order/#{order_id}/invoice", invoice_params).parse
|
101
120
|
end
|
102
121
|
|
103
|
-
|
104
122
|
#
|
105
123
|
# Create offline refund for order
|
106
124
|
#
|
@@ -172,6 +190,33 @@ module Magento
|
|
172
190
|
def ship(order_id, shipment_params = nil)
|
173
191
|
request.post("order/#{order_id}/ship", shipment_params).parse
|
174
192
|
end
|
193
|
+
|
194
|
+
def send_email(order_id)
|
195
|
+
request.post("orders/#{order_id}/emails").parse
|
196
|
+
end
|
197
|
+
|
198
|
+
#
|
199
|
+
# Creates a comment on the given Order
|
200
|
+
#
|
201
|
+
# Magento::Order.add_comment(
|
202
|
+
# order_id,
|
203
|
+
# 'comment',
|
204
|
+
# is_customer_notified: 0,
|
205
|
+
# is_visible_on_front: 1
|
206
|
+
# )
|
207
|
+
#
|
208
|
+
# to complete [documentation](https://magento.redoc.ly/2.4.2-admin/tag/ordersidcomments#operation/salesOrderManagementV1AddCommentPost)
|
209
|
+
#
|
210
|
+
# @return {Boolean}: return true on success
|
211
|
+
def add_comment(order_id, comment, comment_params = nil)
|
212
|
+
request.post(
|
213
|
+
"orders/#{order_id}/comments",
|
214
|
+
statusHistory: {
|
215
|
+
comment: comment,
|
216
|
+
**comment_params
|
217
|
+
}
|
218
|
+
).parse
|
219
|
+
end
|
175
220
|
end
|
176
221
|
end
|
177
222
|
end
|
@@ -5,6 +5,35 @@ require 'mini_magick'
|
|
5
5
|
|
6
6
|
module Magento
|
7
7
|
module Params
|
8
|
+
|
9
|
+
# Helper class to create product image params.
|
10
|
+
# before generating the hash, the following image treatments are performed:
|
11
|
+
# - resize image
|
12
|
+
# - remove alpha
|
13
|
+
# - leaves square
|
14
|
+
# - convert image to jpg
|
15
|
+
#
|
16
|
+
# Example:
|
17
|
+
#
|
18
|
+
# params = Magento::Params::CreateImage.new(
|
19
|
+
# title: 'Image title',
|
20
|
+
# path: '/path/to/image.jpg', # or url
|
21
|
+
# position: 1,
|
22
|
+
# size: 'small', # options: 'large'(defaut), 'medium' and 'small',
|
23
|
+
# disabled: true, # default is false,
|
24
|
+
# main: true, # default is false,
|
25
|
+
# ).to_h
|
26
|
+
#
|
27
|
+
# Magento::Product.add_media('sku', params)
|
28
|
+
#
|
29
|
+
# The resize defaut confiruration is:
|
30
|
+
#
|
31
|
+
# Magento.configure do |config|
|
32
|
+
# config.product_image.small_size = '200x200>'
|
33
|
+
# config.product_image.medium_size = '400x400>'
|
34
|
+
# config.product_image.large_size = '800x800>'
|
35
|
+
# end
|
36
|
+
#
|
8
37
|
class CreateImage < Dry::Struct
|
9
38
|
VARIANTS = {
|
10
39
|
'large' => :image,
|
@@ -34,6 +63,20 @@ module Magento
|
|
34
63
|
}
|
35
64
|
end
|
36
65
|
|
66
|
+
# Generates a list containing an Magento::Params::CreateImage
|
67
|
+
# instance for each size of the same image.
|
68
|
+
#
|
69
|
+
# Example:
|
70
|
+
#
|
71
|
+
# params = Magento::Params::CreateImage.new(
|
72
|
+
# title: 'Image title',
|
73
|
+
# path: '/path/to/image.jpg', # or url
|
74
|
+
# position: 1,
|
75
|
+
# ).variants
|
76
|
+
#
|
77
|
+
# params.map(&:size)
|
78
|
+
# => ['large', 'medium', 'small']
|
79
|
+
#
|
37
80
|
def variants
|
38
81
|
VARIANTS.keys.map do |size|
|
39
82
|
CreateImage.new(attributes.merge(size: size, disabled: size != 'large'))
|
data/lib/magento/product.rb
CHANGED
@@ -38,6 +38,34 @@ module Magento
|
|
38
38
|
super || @custom_attributes&.any? { |a| a.attribute_code == attribute_code.to_s }
|
39
39
|
end
|
40
40
|
|
41
|
+
# Create new gallery entry
|
42
|
+
#
|
43
|
+
# Example:
|
44
|
+
#
|
45
|
+
# product = Magento::Product.find('sku')
|
46
|
+
#
|
47
|
+
# product.add_media(
|
48
|
+
# media_type: 'image',
|
49
|
+
# label: 'Image label',
|
50
|
+
# position: 1,
|
51
|
+
# content: {
|
52
|
+
# base64_encoded_data: 'image-string-base64',
|
53
|
+
# type: 'image/jpg',
|
54
|
+
# name: 'filename.jpg'
|
55
|
+
# },
|
56
|
+
# types: ['image']
|
57
|
+
# )
|
58
|
+
#
|
59
|
+
# Or you can use the Magento::Params::CreateImage helper class
|
60
|
+
#
|
61
|
+
# params = Magento::Params::CreateImage.new(
|
62
|
+
# title: 'Image title',
|
63
|
+
# path: '/path/to/image.jpg', # or url
|
64
|
+
# position: 1,
|
65
|
+
# ).to_h
|
66
|
+
#
|
67
|
+
# product.add_media(params)
|
68
|
+
#
|
41
69
|
def add_media(attributes)
|
42
70
|
self.class.add_media(sku, attributes)
|
43
71
|
end
|
@@ -88,9 +116,57 @@ module Magento
|
|
88
116
|
self.class.update_stock(sku, id, attributes)
|
89
117
|
end
|
90
118
|
|
119
|
+
# Assign a product link to another product
|
120
|
+
#
|
121
|
+
# product = Magento::Product.find('sku')
|
122
|
+
#
|
123
|
+
# product.create_links([
|
124
|
+
# {
|
125
|
+
# link_type: 'upsell',
|
126
|
+
# linked_product_sku: 'linked_product_sku',
|
127
|
+
# linked_product_type: 'simple',
|
128
|
+
# position: position,
|
129
|
+
# sku: 'product-sku'
|
130
|
+
# }
|
131
|
+
# ])
|
132
|
+
#
|
133
|
+
def create_links(product_links)
|
134
|
+
self.class.create_links(sku, product_links)
|
135
|
+
end
|
136
|
+
|
137
|
+
def remove_link(link_type:, linked_product_sku:)
|
138
|
+
self.class.remove_link(sku, link_type: link_type, linked_product_sku: linked_product_sku)
|
139
|
+
end
|
140
|
+
|
91
141
|
class << self
|
92
142
|
alias_method :find_by_sku, :find
|
93
143
|
|
144
|
+
# Create new gallery entry
|
145
|
+
#
|
146
|
+
# Example:
|
147
|
+
#
|
148
|
+
# Magento::Product.add_media('sku', {
|
149
|
+
# media_type: 'image',
|
150
|
+
# label: 'Image title',
|
151
|
+
# position: 1,
|
152
|
+
# content: {
|
153
|
+
# base64_encoded_data: 'image-string-base64',
|
154
|
+
# type: 'image/jpg',
|
155
|
+
# name: 'filename.jpg'
|
156
|
+
# },
|
157
|
+
# types: ['image']
|
158
|
+
# })
|
159
|
+
#
|
160
|
+
# Or you can use the Magento::Params::CreateImage helper class
|
161
|
+
#
|
162
|
+
# params = Magento::Params::CreateImage.new(
|
163
|
+
# title: 'Image title',
|
164
|
+
# path: '/path/to/image.jpg', # or url
|
165
|
+
# position: 1,
|
166
|
+
# ).to_h
|
167
|
+
#
|
168
|
+
# Magento::Product.add_media('sku', params)
|
169
|
+
#
|
94
170
|
def add_media(sku, attributes)
|
95
171
|
request.post("products/#{sku}/media", { entry: attributes }).parse
|
96
172
|
end
|
@@ -134,6 +210,18 @@ module Magento
|
|
134
210
|
request.put("products/#{sku}/stockItems/#{id}", stockItem: attributes).parse
|
135
211
|
end
|
136
212
|
|
213
|
+
# Assign a product link to another product
|
214
|
+
#
|
215
|
+
# Product.create_links('product-sku', [
|
216
|
+
# {
|
217
|
+
# link_type: 'upsell',
|
218
|
+
# linked_product_sku: 'linked_product_sku',
|
219
|
+
# linked_product_type: 'simple',
|
220
|
+
# position: position,
|
221
|
+
# sku: 'product-sku'
|
222
|
+
# }
|
223
|
+
# ])
|
224
|
+
#
|
137
225
|
def create_links(sku, product_links)
|
138
226
|
request.post("products/#{sku}/links", { items: product_links })
|
139
227
|
end
|
data/lib/magento/query.rb
CHANGED
@@ -70,15 +70,17 @@ module Magento
|
|
70
70
|
self
|
71
71
|
end
|
72
72
|
|
73
|
-
def order(attributes)
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
73
|
+
def order(*attributes)
|
74
|
+
self.sort_orders = []
|
75
|
+
attributes.each do |sort_order|
|
76
|
+
if sort_order.is_a?(String) || sort_order.is_a?(Symbol)
|
77
|
+
sort_orders << { field: verify_id(sort_order), direction: :asc }
|
78
|
+
elsif sort_order.is_a?(Hash)
|
79
|
+
sort_order.each do |field, direction|
|
80
|
+
raise "Invalid sort order direction '#{direction}'" unless %w[asc desc].include?(direction.to_s)
|
81
|
+
|
82
|
+
sort_orders << { field: verify_id(field), direction: direction }
|
83
|
+
end
|
82
84
|
end
|
83
85
|
end
|
84
86
|
self
|
data/lib/magento/request.rb
CHANGED
@@ -54,7 +54,12 @@ module Magento
|
|
54
54
|
begin
|
55
55
|
msg = resp.parse['message']
|
56
56
|
errors = resp.parse['errors'] || resp.parse['parameters']
|
57
|
-
|
57
|
+
case errors
|
58
|
+
when Hash
|
59
|
+
errors.each { |k, v| msg.sub! "%#{k}", v }
|
60
|
+
when Array
|
61
|
+
errors.each_with_index { |v, i| msg.sub! "%#{i + 1}", v.to_s }
|
62
|
+
end
|
58
63
|
rescue StandardError
|
59
64
|
msg = 'Failed access to the magento server'
|
60
65
|
errors = []
|
data/lib/magento/version.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
1
|
+
RSpec.describe Magento::ModelMapper do
|
2
|
+
describe '.to_hash' do
|
3
|
+
it 'serializes object to hash' do
|
4
|
+
class Magento::SameClass
|
5
|
+
attr_accessor :name, :description, :items
|
6
|
+
end
|
7
|
+
|
8
|
+
object = Magento::SameClass.new
|
9
|
+
object.name = 'Some name'
|
10
|
+
object.description = 'Some description'
|
11
|
+
object.items = [object.dup]
|
12
|
+
|
13
|
+
expect(Magento::ModelMapper.to_hash(object)).to eql({
|
14
|
+
'name' => 'Some name',
|
15
|
+
'description' => 'Some description',
|
16
|
+
'items' => [{ 'name' => 'Some name', 'description' => 'Some description' }]
|
17
|
+
})
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.map_hash' do
|
22
|
+
it 'returns magento object from hash' do
|
23
|
+
class Magento::SameClass; end
|
24
|
+
hash = { name: 'Some name', price: 10.99 }
|
25
|
+
|
26
|
+
object = Magento::ModelMapper.map_hash(Magento::SameClass, hash)
|
27
|
+
|
28
|
+
expect(object).to be_instance_of(Magento::SameClass)
|
29
|
+
expect(object.name).to eql hash[:name]
|
30
|
+
expect(object.price).to eql hash[:price]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.map_array' do
|
35
|
+
it 'returns magento object list from array of hash' do
|
36
|
+
class Magento::SameClass; end
|
37
|
+
array = [{ name: 'Some name', price: 10.99 }]
|
38
|
+
|
39
|
+
object = Magento::ModelMapper.map_array('same_class', array)
|
40
|
+
|
41
|
+
expect(object).to be_a(Array)
|
42
|
+
expect(object).to all be_instance_of(Magento::SameClass)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'include ModelParser' do
|
47
|
+
before do
|
48
|
+
class Magento::SameClass
|
49
|
+
include Magento::ModelParser
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
let(:hash) { { name: 'Same name' } }
|
54
|
+
|
55
|
+
describe '.build' do
|
56
|
+
it 'calls Magento::ModelMapper.map_hash' do
|
57
|
+
expect(Magento::ModelMapper).to receive(:map_hash)
|
58
|
+
.with(Magento::SameClass, hash)
|
59
|
+
|
60
|
+
Magento::SameClass.build(hash)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#to_h' do
|
65
|
+
it 'calls Magento::ModelMapper.to_hash' do
|
66
|
+
object = Magento::SameClass.build(hash)
|
67
|
+
|
68
|
+
expect(Magento::ModelMapper).to receive(:to_hash).with(object)
|
69
|
+
|
70
|
+
object.to_h
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|