e_plat 0.5.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +109 -60
- data/lib/e_plat/client/default_request_args.rb +1 -1
- data/lib/e_plat/client.rb +55 -9
- data/lib/e_plat/initializer.rb +26 -0
- data/lib/e_plat/mapping/bigcommerce/v_3/product/option.rb +58 -0
- data/lib/e_plat/mapping/bigcommerce/v_3/product/variant/option_value.rb +42 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/metafield.rb +26 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/order/billing_address.rb +14 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/order/shipping_address.rb +30 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/order.rb +26 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/product/image.rb +52 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/product/option.rb +45 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/product/variant/option_value.rb +58 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/product/variant.rb +180 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/product.rb +100 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/script_tag.rb +26 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/shop.rb +26 -0
- data/lib/e_plat/mapping/shopify/v_2024_07/webhook.rb +29 -0
- data/lib/e_plat/mapping/virtual_collection/shopify/product/variant/option_value.rb +272 -0
- data/lib/e_plat/mapping.rb +39 -15
- data/lib/e_plat/resource/base.rb +39 -5
- data/lib/e_plat/resource/collection.rb +45 -16
- data/lib/e_plat/resource/concerns/aliases.rb +39 -19
- data/lib/e_plat/resource/concerns/dirty.rb +12 -8
- data/lib/e_plat/resource/concerns/graph_q_lable.rb +253 -0
- data/lib/e_plat/resource/concerns/overwrite_instance_methods.rb +4 -4
- data/lib/e_plat/resource/concerns/overwrite_request_methods.rb +64 -21
- data/lib/e_plat/resource/countable.rb +37 -10
- data/lib/e_plat/resource/metafield.rb +2 -2
- data/lib/e_plat/resource/platform_specific/bigcommerce/metafield.rb +4 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/order/Consignment.rb +2 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/order/billing_address.rb +2 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/order/fulfillment.rb +2 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/order/line_item.rb +2 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/order/shipping_address.rb +2 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/order/shipping_line.rb +2 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/order.rb +4 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/product/image.rb +2 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/product/option.rb +2 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/product/variant/option_value.rb +2 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/product/variant.rb +2 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/product.rb +4 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/script_tag.rb +4 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/shop.rb +4 -0
- data/lib/e_plat/resource/platform_specific/bigcommerce/webhook.rb +4 -0
- data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/input/product/variant.rb +47 -0
- data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/input/product/variants_bulk.rb +47 -0
- data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/input/product.rb +23 -0
- data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/input.rb +98 -0
- data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/mutation/product/variant.rb +78 -0
- data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/mutation/product.rb +55 -0
- data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/mutation.rb +5 -0
- data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/query/product/variant.rb +44 -0
- data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/query/product.rb +58 -0
- data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/query.rb +5 -0
- data/lib/e_plat/resource/platform_specific/shopify/metafield.rb +4 -0
- data/lib/e_plat/resource/platform_specific/shopify/order/Consignment.rb +2 -0
- data/lib/e_plat/resource/platform_specific/shopify/order/billing_address.rb +2 -0
- data/lib/e_plat/resource/platform_specific/shopify/order/fulfillment.rb +2 -0
- data/lib/e_plat/resource/platform_specific/shopify/order/line_item.rb +2 -0
- data/lib/e_plat/resource/platform_specific/shopify/order/shipping_address.rb +2 -0
- data/lib/e_plat/resource/platform_specific/shopify/order/shipping_line.rb +2 -0
- data/lib/e_plat/resource/platform_specific/shopify/order.rb +4 -0
- data/lib/e_plat/resource/platform_specific/shopify/product/image.rb +14 -0
- data/lib/e_plat/resource/platform_specific/shopify/product/option.rb +14 -0
- data/lib/e_plat/resource/platform_specific/shopify/product/variant/option_value.rb +14 -0
- data/lib/e_plat/resource/platform_specific/shopify/product/variant.rb +66 -0
- data/lib/e_plat/resource/platform_specific/shopify/product.rb +79 -0
- data/lib/e_plat/resource/platform_specific/shopify/recurring_application_charge/usage_charge.rb +2 -0
- data/lib/e_plat/resource/platform_specific/shopify/recurring_application_charge.rb +4 -0
- data/lib/e_plat/resource/platform_specific/shopify/script_tag.rb +4 -0
- data/lib/e_plat/resource/platform_specific/shopify/shop.rb +4 -0
- data/lib/e_plat/resource/platform_specific/shopify/webhook.rb +4 -0
- data/lib/e_plat/resource/product/image.rb +8 -5
- data/lib/e_plat/resource/product/option.rb +2 -3
- data/lib/e_plat/resource/product/variant/option_value.rb +17 -0
- data/lib/e_plat/resource/product/variant.rb +6 -14
- data/lib/e_plat/resource/product.rb +23 -11
- data/lib/e_plat/session.rb +3 -2
- data/lib/e_plat/type_coercer.rb +4 -2
- data/lib/e_plat/version.rb +1 -1
- data/lib/e_plat.rb +33 -4
- data/lib/hash.rb +39 -0
- metadata +163 -27
@@ -0,0 +1,272 @@
|
|
1
|
+
|
2
|
+
module EPlat
|
3
|
+
class Mapping
|
4
|
+
module VirtualCollection
|
5
|
+
module Shopify
|
6
|
+
module Product
|
7
|
+
module Variant
|
8
|
+
class OptionValue < VirtualCollection::Base
|
9
|
+
attr_accessor :resource
|
10
|
+
|
11
|
+
def initialize(resource:, map_from:)
|
12
|
+
@resource = resource
|
13
|
+
super
|
14
|
+
|
15
|
+
return unless @resource.try :selected_options
|
16
|
+
|
17
|
+
@resource.option_values =
|
18
|
+
@resource.selected_options.map.with_index do |data, i|
|
19
|
+
item = EPlat::Product::Variant::OptionValue.new(variant_id: @resource.id)
|
20
|
+
item.mapping.virtual_collection = self
|
21
|
+
item.add_aliases!(native_attribute_aliases(i), EPlat::Product::Variant::OptionValue.schema)
|
22
|
+
|
23
|
+
item
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def native_attribute_aliases(i)
|
28
|
+
[
|
29
|
+
{
|
30
|
+
alias_attribute: {
|
31
|
+
native_key: "[selected_options][#{i}][option_value][id]",
|
32
|
+
e_plat_key: "id",
|
33
|
+
virtual_collection: true,
|
34
|
+
custom_e_plat_getter: '-> { _1&.split("/")&.last }',
|
35
|
+
custom_native_setter: '-> { "gid://shopify/ProductOptionValue/#{_1}" }'
|
36
|
+
}
|
37
|
+
},
|
38
|
+
{
|
39
|
+
alias_attribute: {
|
40
|
+
native_key: "[selected_options][#{i}][name]",
|
41
|
+
e_plat_key: "name",
|
42
|
+
virtual_collection: true
|
43
|
+
}
|
44
|
+
},
|
45
|
+
{
|
46
|
+
alias_attribute: {
|
47
|
+
native_key: "[selected_options][#{i}][value]",
|
48
|
+
e_plat_key: "value",
|
49
|
+
virtual_collection: true
|
50
|
+
}
|
51
|
+
}
|
52
|
+
]
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
# consignments are deliveries, we're just going to operate within the context on one delivery per order
|
67
|
+
# this should be reasonable to tie us over for now
|
68
|
+
|
69
|
+
# integer :id
|
70
|
+
# string :admin_graphql_api_id
|
71
|
+
# integer :fulfillable_quantity
|
72
|
+
# string :fulfillment_service
|
73
|
+
# string :fulfillment_status
|
74
|
+
# boolean :gift_card
|
75
|
+
# integer :grams
|
76
|
+
# string :name
|
77
|
+
# string :price
|
78
|
+
# hash :price_set
|
79
|
+
# boolean :product_exists
|
80
|
+
# integer :product_id
|
81
|
+
# array :properties
|
82
|
+
# integer :quantity
|
83
|
+
# boolean :requires_shipping
|
84
|
+
# string :sku
|
85
|
+
# boolean :taxable
|
86
|
+
# string :title
|
87
|
+
# string :total_discount
|
88
|
+
# hash :total_discount_set
|
89
|
+
# integer :variant_id
|
90
|
+
# string :variant_inventory_management
|
91
|
+
# string :variant_title
|
92
|
+
# string :vendor
|
93
|
+
# array :tax_lines
|
94
|
+
# array :duties
|
95
|
+
# array :discount_allocations
|
96
|
+
|
97
|
+
|
98
|
+
# BG = {
|
99
|
+
# "consignments": [
|
100
|
+
# {
|
101
|
+
# "pickups": [],
|
102
|
+
# "shipping": [
|
103
|
+
# {
|
104
|
+
# "id": 3,
|
105
|
+
# "first_name": "Jane",
|
106
|
+
# "last_name": "Doe",
|
107
|
+
# "company": "",
|
108
|
+
# "street_1": "123 Main Street",
|
109
|
+
# "street_2": "",
|
110
|
+
# "city": "Austin",
|
111
|
+
# "zip": "78751",
|
112
|
+
# "country": "United States",
|
113
|
+
# "country_iso2": "US",
|
114
|
+
# "state": "Texas",
|
115
|
+
# "email": "oli@example.com",
|
116
|
+
# "phone": "",
|
117
|
+
# "form_fields": [],
|
118
|
+
# "line_items": [
|
119
|
+
# {
|
120
|
+
# "id": 3,
|
121
|
+
# "order_id": 102,
|
122
|
+
# "product_id": 88,
|
123
|
+
# "variant_id": 81,
|
124
|
+
# "order_pickup_method_id": 0,
|
125
|
+
# "order_address_id": 3,
|
126
|
+
# "name": "Chemex Coffeemaker",
|
127
|
+
# "name_customer": "Chemex Coffeemaker",
|
128
|
+
# "name_merchant": "Chemex Coffeemaker",
|
129
|
+
# "sku": "CC3C-SM",
|
130
|
+
# "upc": "",
|
131
|
+
# "type": "physical",
|
132
|
+
# "base_price": "83.3300",
|
133
|
+
# "price_ex_tax": "83.3300",
|
134
|
+
# "price_inc_tax": "83.3300",
|
135
|
+
# "price_tax": "0.0000",
|
136
|
+
# "base_total": "83.3300",
|
137
|
+
# "total_ex_tax": "83.3300",
|
138
|
+
# "total_inc_tax": "83.3300",
|
139
|
+
# "total_tax": "0.0000",
|
140
|
+
# "weight": "1.0000",
|
141
|
+
# "width": "0.0000",
|
142
|
+
# "height": "0.0000",
|
143
|
+
# "depth": "0.0000",
|
144
|
+
# "quantity": 1,
|
145
|
+
# "base_cost_price": "0.0000",
|
146
|
+
# "cost_price_inc_tax": "0.0000",
|
147
|
+
# "cost_price_ex_tax": "0.0000",
|
148
|
+
# "cost_price_tax": "0.0000",
|
149
|
+
# "is_refunded": false,
|
150
|
+
# "quantity_refunded": 0,
|
151
|
+
# "refund_amount": "0.0000",
|
152
|
+
# "return_id": 0,
|
153
|
+
# "wrapping_id": 0,
|
154
|
+
# "wrapping_name": "",
|
155
|
+
# "base_wrapping_cost": "0.0000",
|
156
|
+
# "wrapping_cost_ex_tax": "0.0000",
|
157
|
+
# "wrapping_cost_inc_tax": "0.0000",
|
158
|
+
# "wrapping_cost_tax": "0.0000",
|
159
|
+
# "wrapping_message": "",
|
160
|
+
# "quantity_shipped": 0,
|
161
|
+
# "event_name": null,
|
162
|
+
# "event_date": null,
|
163
|
+
# "fixed_shipping_cost": "0.0000",
|
164
|
+
# "ebay_item_id": "",
|
165
|
+
# "ebay_transaction_id": "",
|
166
|
+
# "option_set_id": 18,
|
167
|
+
# "parent_order_product_id": null,
|
168
|
+
# "is_bundled_product": false,
|
169
|
+
# "bin_picking_number": "0",
|
170
|
+
# "external_id": "",
|
171
|
+
# "fulfillment_source": "",
|
172
|
+
# "brand": "",
|
173
|
+
# "gift_certificate_id": null,
|
174
|
+
# "applied_discounts": [],
|
175
|
+
# "product_options": [
|
176
|
+
# {
|
177
|
+
# "id": 2,
|
178
|
+
# "option_id": 34,
|
179
|
+
# "order_product_id": 3,
|
180
|
+
# "product_option_id": 114,
|
181
|
+
# "display_name": "Size",
|
182
|
+
# "display_name_customer": "Size",
|
183
|
+
# "display_name_merchant": "Size",
|
184
|
+
# "display_value": "Small",
|
185
|
+
# "display_value_customer": "Small",
|
186
|
+
# "display_value_merchant": "Small",
|
187
|
+
# "value": "101",
|
188
|
+
# "type": "Multiple choice",
|
189
|
+
# "name": "Size1699441692-88",
|
190
|
+
# "display_style": "Dropdown"
|
191
|
+
# }
|
192
|
+
# ],
|
193
|
+
# "configurable_fields": [],
|
194
|
+
# "discounted_total_inc_tax": "83.3300"
|
195
|
+
# }
|
196
|
+
# ]
|
197
|
+
# }
|
198
|
+
# ],
|
199
|
+
# "items_total": 1,
|
200
|
+
# "items_shipped": 0,
|
201
|
+
# "shipping_method": "None",
|
202
|
+
# "base_cost": 0,
|
203
|
+
# "cost_ex_tax": 0,
|
204
|
+
# "cost_inc_tax": 0,
|
205
|
+
# "cost_tax": 0,
|
206
|
+
# "cost_tax_class_id": 0,
|
207
|
+
# "base_handling_cost": 0,
|
208
|
+
# "handling_cost_ex_tax": 0,
|
209
|
+
# "handling_cost_inc_tax": 0,
|
210
|
+
# "handling_cost_tax": 0,
|
211
|
+
# "handling_cost_tax_class_id": 0,
|
212
|
+
# "shipping_zone_id": 0,
|
213
|
+
# "shipping_zone_name": "",
|
214
|
+
# "shipping_quotes": {
|
215
|
+
# "url": "https://api.bigcommerce.com/stores/d0kmq3bory/v2/orders/102/consignments/shipping/3/shipping_quotes",
|
216
|
+
# "resource": "/orders/102/consignments/shipping/3/shipping_quotes"
|
217
|
+
# }
|
218
|
+
# }
|
219
|
+
# ]
|
220
|
+
# }
|
221
|
+
|
222
|
+
# Shopify = {
|
223
|
+
# "line_items": [
|
224
|
+
# {
|
225
|
+
# "id": 13120677806211,
|
226
|
+
# "admin_graphql_api_id": "gid://shopify/LineItem/13120677806211",
|
227
|
+
# "fulfillable_quantity": 1,
|
228
|
+
# "fulfillment_service": "manual",
|
229
|
+
# "fulfillment_status": null,
|
230
|
+
# "gift_card": false,
|
231
|
+
# "grams": 0,
|
232
|
+
# "name": "Winter Luggage - Sienna the longest name variant in the world",
|
233
|
+
# "price": "150.00",
|
234
|
+
# "price_set": {
|
235
|
+
# "shop_money": {
|
236
|
+
# "amount": "150.00",
|
237
|
+
# "currency_code": "GBP"
|
238
|
+
# },
|
239
|
+
# "presentment_money": {
|
240
|
+
# "amount": "150.00",
|
241
|
+
# "currency_code": "GBP"
|
242
|
+
# }
|
243
|
+
# },
|
244
|
+
# "product_exists": true,
|
245
|
+
# "product_id": 6610509627523,
|
246
|
+
# "properties": [],
|
247
|
+
# "quantity": 1,
|
248
|
+
# "requires_shipping": true,
|
249
|
+
# "sku": "skusku123",
|
250
|
+
# "taxable": true,
|
251
|
+
# "title": "Winter Luggage",
|
252
|
+
# "total_discount": "0.00",
|
253
|
+
# "total_discount_set": {
|
254
|
+
# "shop_money": {
|
255
|
+
# "amount": "0.00",
|
256
|
+
# "currency_code": "GBP"
|
257
|
+
# },
|
258
|
+
# "presentment_money": {
|
259
|
+
# "amount": "0.00",
|
260
|
+
# "currency_code": "GBP"
|
261
|
+
# }
|
262
|
+
# },
|
263
|
+
# "variant_id": 39428269408387,
|
264
|
+
# "variant_inventory_management": "shopify",
|
265
|
+
# "variant_title": "Sienna the longest name variant in the world",
|
266
|
+
# "vendor": "PreProduct Test",
|
267
|
+
# "tax_lines": [],
|
268
|
+
# "duties": [],
|
269
|
+
# "discount_allocations": []
|
270
|
+
# }
|
271
|
+
# ]
|
272
|
+
# }
|
data/lib/e_plat/mapping.rb
CHANGED
@@ -1,19 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module EPlat
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
4
|
+
class Mapping
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def new_instance(specifc_mapping:, resource: nil)
|
9
|
+
platform = EPlat::Current.e_plat_session.platform.to_s
|
10
|
+
sanitized_mapping = sanitize_mapping(specifc_mapping, platform)
|
11
|
+
|
12
|
+
if Object.const_defined?(sanitized_mapping)
|
13
|
+
sanitized_mapping.constantize.new(resource)
|
14
|
+
elsif Object.const_defined?(specifc_mapping)
|
15
|
+
specifc_mapping.constantize.new(resource)
|
16
|
+
else
|
17
|
+
EPlat::Mapping::Base.new(resource)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def sanitize_mapping(specifc_mapping, platform)
|
24
|
+
# Stripe out all instanced of the platform scope in the mapping
|
25
|
+
# then put platform back in as third scope, as mapping is always platform scoped.
|
26
|
+
# i.e. EPlat::Mapping::Bigcommerce::V3::Product::Variant
|
27
|
+
parts = specifc_mapping.split("::")
|
28
|
+
|
29
|
+
parts.reject! do |part|
|
30
|
+
platform.downcase == part.downcase
|
31
|
+
end
|
32
|
+
|
33
|
+
parts.insert(2, platform.capitalize)
|
34
|
+
|
35
|
+
parts.join("::")
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
19
42
|
end
|
43
|
+
|
data/lib/e_plat/resource/base.rb
CHANGED
@@ -4,11 +4,12 @@ module EPlat
|
|
4
4
|
class Base < ActiveResource::Base
|
5
5
|
include Concerns::OverwriteRequestMethods, Concerns::OverwriteInstanceMethods
|
6
6
|
include Concerns::Aliases, Concerns::Dirty, Concerns::FullJson
|
7
|
+
include Concerns::GraphQLable
|
7
8
|
|
8
9
|
self.connection_class = EPlat::Connection
|
9
10
|
self.collection_parser = EPlat::Collection
|
10
11
|
self.site = "/" # this is overwritten below in initialize_singleton! when EPlat::Session is initialized
|
11
|
-
add_response_method :full_response
|
12
|
+
add_response_method :full_response #full response of the request
|
12
13
|
|
13
14
|
class << self
|
14
15
|
include Countable
|
@@ -18,6 +19,12 @@ module EPlat
|
|
18
19
|
threadsafe_attribute :_headers, :_connection, :_user, :_password, :_bearer_token, :_site, :_proxy, # active resource
|
19
20
|
:mapping, :include_root_in_json, :include_format_in_path # e_plat specific
|
20
21
|
|
22
|
+
def inherited(subclass)
|
23
|
+
super
|
24
|
+
subclass.exclude_from_json(read_only) if read_only
|
25
|
+
subclass.schema ||= schema.dup
|
26
|
+
end
|
27
|
+
|
21
28
|
def initialize_singleton!
|
22
29
|
self.site = client.base_url # .site is an ActiveResource method that uses the threadsafe _site attribute underneath
|
23
30
|
self.prefix = client.url_prefix(klass: self) # this is overwritten below in prefix= for threadsafety
|
@@ -60,6 +67,9 @@ module EPlat
|
|
60
67
|
self.read_only = read_only
|
61
68
|
end
|
62
69
|
|
70
|
+
def platform_specific_class?
|
71
|
+
self.class.to_s.include? client.platform.to_s.capitalize
|
72
|
+
end
|
63
73
|
|
64
74
|
private
|
65
75
|
|
@@ -83,6 +93,7 @@ module EPlat
|
|
83
93
|
|
84
94
|
@mapped_attributes = ensure_e_plat_attributes!
|
85
95
|
ensure_native_attributes!
|
96
|
+
|
86
97
|
add_aliases!(mapping.native_attribute_aliases, type_schema || {})
|
87
98
|
end
|
88
99
|
|
@@ -96,7 +107,7 @@ module EPlat
|
|
96
107
|
|
97
108
|
def native_keys
|
98
109
|
if client.shopify?
|
99
|
-
schema.keys # EPlat uses Shopify's schema,
|
110
|
+
@mapping.native_attributes.presence || schema.keys # EPlat uses Shopify's schema, apar from a couple of Graphql only fields
|
100
111
|
elsif mapping.class.to_s != EPlat::Mapping::Base && @mapping.native_attributes.present?
|
101
112
|
@mapping.native_attributes.presence
|
102
113
|
else
|
@@ -117,7 +128,26 @@ module EPlat
|
|
117
128
|
|
118
129
|
top_level_resource?
|
119
130
|
end
|
120
|
-
|
131
|
+
|
132
|
+
def formatted_id(id)
|
133
|
+
return id unless client.shopify? && client.api_version != "2024_01"
|
134
|
+
return if id.to_s.include?("gid://")
|
135
|
+
|
136
|
+
case element_name
|
137
|
+
when "product"
|
138
|
+
"gid://shopify/Product/#{id}"
|
139
|
+
when "variant"
|
140
|
+
"gid://shopify/ProductVariant/#{id}"
|
141
|
+
when "image"
|
142
|
+
"gid://shopify/ProductImage/#{id}"
|
143
|
+
else
|
144
|
+
raise EPlat::Errors.new("Unsupported element name")
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def graphql_input
|
149
|
+
raise EPlat::Error.new("GraphQL input not supported for this resource and platform")
|
150
|
+
end
|
121
151
|
|
122
152
|
private
|
123
153
|
|
@@ -126,7 +156,7 @@ module EPlat
|
|
126
156
|
end
|
127
157
|
|
128
158
|
def ensure_native_attributes!
|
129
|
-
return if client.shopify?
|
159
|
+
return if client.shopify? && EPlat.config.shopify_api_version == "2024_01"
|
130
160
|
|
131
161
|
AttributeInterface.new(self, keys: native_keys)
|
132
162
|
end
|
@@ -170,7 +200,11 @@ module EPlat
|
|
170
200
|
end
|
171
201
|
|
172
202
|
def top_level_resource?
|
173
|
-
self.class.name.split("::")
|
203
|
+
parts = self.class.name.split("::")
|
204
|
+
# platform scope not included, as top level resources can optionally be platform specific
|
205
|
+
parts.reject!{|part| EPlat::SUPPORTED_PLATFORMS.include? part.downcase }
|
206
|
+
|
207
|
+
parts.count <= 2
|
174
208
|
end
|
175
209
|
|
176
210
|
def element_name
|
@@ -2,41 +2,52 @@
|
|
2
2
|
|
3
3
|
module EPlat
|
4
4
|
class Collection < ActiveResource::Collection
|
5
|
+
SHOPIFY_GRAPHQL_PAGINATABLE_CLASSES = %w(
|
6
|
+
EPlat::Product
|
7
|
+
EPlat::Product::Variant
|
8
|
+
EPlat::Shopify::Product
|
9
|
+
EPlat::Shopify::Product::Variant
|
10
|
+
)
|
5
11
|
|
6
12
|
def initialize(parsed = {})
|
7
13
|
super parsed
|
8
14
|
end
|
9
15
|
|
10
16
|
def next_page?
|
11
|
-
return unless pagination_available?
|
12
|
-
@
|
17
|
+
return false unless pagination_available?
|
18
|
+
@next.present?
|
13
19
|
end
|
14
20
|
|
15
21
|
def previous_page?
|
16
|
-
return unless pagination_available?
|
17
|
-
@
|
22
|
+
return false unless pagination_available?
|
23
|
+
@previous.present?
|
18
24
|
end
|
19
25
|
|
20
26
|
def next_page_info
|
21
27
|
return unless pagination_available?
|
22
|
-
extract_page_info(@
|
28
|
+
extract_page_info(@next)
|
23
29
|
end
|
24
30
|
|
25
31
|
def previous_page_info
|
26
32
|
return unless pagination_available?
|
27
|
-
extract_page_info(@
|
33
|
+
extract_page_info(@previous)
|
28
34
|
end
|
29
35
|
|
30
36
|
def fetch_next_page
|
31
37
|
return unless pagination_available?
|
32
|
-
fetch_page(@
|
38
|
+
fetch_page(@next)
|
33
39
|
end
|
34
40
|
|
35
41
|
def fetch_previous_page
|
36
42
|
return unless pagination_available?
|
37
|
-
fetch_page(@
|
43
|
+
fetch_page(@previous)
|
38
44
|
end
|
45
|
+
|
46
|
+
def paginates_via_graphql?
|
47
|
+
return unless SHOPIFY_GRAPHQL_PAGINATABLE_CLASSES.include? resource_class.to_s
|
39
48
|
|
49
|
+
client.shopify? && client.api_version != "2024_01"
|
50
|
+
end
|
40
51
|
|
41
52
|
private
|
42
53
|
|
@@ -44,10 +55,17 @@ module EPlat
|
|
44
55
|
return [] unless url.present?
|
45
56
|
url = "#{ resource_class.collection_path }#{ url }" if client.bigcommerce?
|
46
57
|
|
47
|
-
|
58
|
+
if paginates_via_graphql?
|
59
|
+
arg_name = (url == @next) ? "after" : "before"
|
60
|
+
resource_class.find(:all, params: {arg_name => url})
|
61
|
+
else
|
62
|
+
resource_class.all(from: url)
|
63
|
+
end
|
48
64
|
end
|
49
65
|
|
50
66
|
def pagination_links
|
67
|
+
return pagination_cursors if paginates_via_graphql?
|
68
|
+
|
51
69
|
case client.platform
|
52
70
|
when :shopify
|
53
71
|
@pagination_links ||= EPlat::Paginated::LinkHeaders.new(
|
@@ -67,17 +85,28 @@ module EPlat
|
|
67
85
|
end
|
68
86
|
end
|
69
87
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
88
|
+
def pagination_cursors
|
89
|
+
response_body = JSON.parse(full_response.body)
|
90
|
+
page_info = response_body.dig("data", resource_class.graphql_collection_name, "pageInfo") || {}
|
91
|
+
|
92
|
+
earliest_cursor = page_info["hasPreviousPage"] ? page_info["startCursor"] : nil
|
93
|
+
latest_cursor = page_info["hasNextPage"] ? page_info["endCursor"] : nil
|
73
94
|
|
74
|
-
|
95
|
+
[earliest_cursor, latest_cursor]
|
96
|
+
end
|
97
|
+
|
98
|
+
def pagination_available?
|
99
|
+
@previous = (paginates_via_graphql?) ? pagination_cursors[0] : pagination_links&.previous_link&.url&.to_s
|
100
|
+
@next = (paginates_via_graphql?) ? pagination_cursors[1] : pagination_links&.next_link&.url&.to_s
|
101
|
+
|
102
|
+
@next.present? or @previous.present?
|
75
103
|
end
|
76
104
|
|
77
|
-
def extract_page_info(
|
78
|
-
return unless
|
105
|
+
def extract_page_info(request_data)
|
106
|
+
return unless request_data.present?
|
107
|
+
return request_data if paginates_via_graphql?
|
79
108
|
|
80
|
-
query_params = URI.decode_www_form(URI(
|
109
|
+
query_params = URI.decode_www_form(URI(request_data).query).to_h
|
81
110
|
query_params[client.pagination_param]
|
82
111
|
end
|
83
112
|
|
@@ -8,33 +8,35 @@ module EPlat
|
|
8
8
|
|
9
9
|
def add_aliases!(aliases, type_schema)
|
10
10
|
@type_coercer = EPlat::TypeCoercer.new(type_schema)
|
11
|
-
processed = []
|
11
|
+
processed = { getter: [], setter: [] }
|
12
12
|
|
13
13
|
aliases.each do |action|
|
14
|
-
action_name = action.keys.first
|
15
|
-
|
16
|
-
|
17
|
-
native_key = args[:native_key]
|
18
|
-
@is_virtual = args[:virtual_collection]
|
14
|
+
action_name, args = action.keys.first, action.values.first
|
15
|
+
e_plat_key, native_key = args[:e_plat_key], args[:native_key]
|
16
|
+
@is_virtual = !!args[:virtual_collection]
|
19
17
|
|
20
18
|
case action_name
|
21
19
|
when :alias_attribute
|
22
20
|
add_to_instance! alias_mapped_getter(e_plat_key, native_key, proc: args[:custom_e_plat_getter])
|
23
21
|
add_to_instance! alias_mapped_setter(e_plat_key, native_key, proc: args[:custom_native_setter])
|
24
|
-
|
25
|
-
processed << e_plat_key
|
22
|
+
processed[:getter] << e_plat_key
|
23
|
+
processed[:setter] << e_plat_key
|
24
|
+
when :existing_entry
|
25
|
+
add_to_instance! mapped_getter(e_plat_key, proc: args[:custom_e_plat_getter])
|
26
|
+
add_to_instance! native_setter(native_key, proc: args[:custom_native_setter])
|
27
|
+
processed[:getter] << e_plat_key
|
28
|
+
processed[:setter] << native_key
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
29
32
|
type_schema.each do |e_plat_key, type|
|
30
|
-
next if processed.include?(e_plat_key)
|
33
|
+
next if processed[:getter].include?(e_plat_key)
|
31
34
|
add_to_instance! mapped_getter(e_plat_key), @is_virtual
|
32
35
|
end
|
33
36
|
|
34
37
|
native_keys.each do |native_key|
|
35
|
-
|
36
|
-
|
37
|
-
add_to_instance! native_setter(native_key), @is_virtual
|
38
|
+
add_to_instance!(mapped_getter(native_key), @is_virtual) unless processed[:getter].include?(native_key)
|
39
|
+
add_to_instance!(native_setter(native_key), @is_virtual) unless processed[:setter].include?(native_key)
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
@@ -42,7 +44,7 @@ module EPlat
|
|
42
44
|
private
|
43
45
|
|
44
46
|
|
45
|
-
def alias_mapped_getter(e_plat_key, native_key, proc:
|
47
|
+
def alias_mapped_getter(e_plat_key, native_key, proc: '->{_1}')
|
46
48
|
proc_line = (proc) ? "current_value = #{ proc.strip }.call(current_value)" : nil
|
47
49
|
|
48
50
|
<<-STRING
|
@@ -54,7 +56,7 @@ module EPlat
|
|
54
56
|
STRING
|
55
57
|
end
|
56
58
|
|
57
|
-
def alias_mapped_setter(e_plat_key, native_key, proc:
|
59
|
+
def alias_mapped_setter(e_plat_key, native_key, proc: '->{_1}')
|
58
60
|
proc_line = (proc) ? "new_value = #{ proc.strip }.call(new_value)" : nil
|
59
61
|
|
60
62
|
<<-STRING
|
@@ -71,19 +73,28 @@ module EPlat
|
|
71
73
|
STRING
|
72
74
|
end
|
73
75
|
|
74
|
-
def mapped_getter(e_plat_key)
|
76
|
+
def mapped_getter(e_plat_key, proc: '->{_1}')
|
77
|
+
proc_line = (proc) ? "value = #{ proc.strip }.call(value)" : nil
|
78
|
+
|
75
79
|
<<-STRING
|
76
80
|
def #{ e_plat_key }
|
77
|
-
|
81
|
+
value = self.attributes['#{ e_plat_key }']
|
82
|
+
#{ proc_line }
|
83
|
+
type_coercer.type_value!('#{ e_plat_key }', value)
|
78
84
|
end
|
79
85
|
STRING
|
80
86
|
end
|
81
87
|
|
82
|
-
|
88
|
+
# we force the native_setter result into changed_attributes, incase the key is the same as the e_plat key
|
89
|
+
# we dont want the eplat version of the value in change_attributes, we want the native version.
|
90
|
+
def native_setter(native_key, proc: '->{_1}')
|
91
|
+
proc_line = (proc) ? "value = #{ proc.strip }.call(value)" : nil
|
92
|
+
|
83
93
|
<<-STRING
|
84
94
|
def #{native_key}=(value)
|
95
|
+
#{proc_line}
|
85
96
|
super
|
86
|
-
attribute_will_change!('#{native_key}')
|
97
|
+
attribute_will_change!('#{native_key}', force_value: value)
|
87
98
|
end
|
88
99
|
STRING
|
89
100
|
end
|
@@ -136,8 +147,17 @@ module EPlat
|
|
136
147
|
change_statements << change_statement
|
137
148
|
end
|
138
149
|
|
150
|
+
method_chain_array = method_chain.split(".").compact_blank
|
151
|
+
will_change_statement =
|
152
|
+
if method_chain_array.one? or @is_virtual
|
153
|
+
"attribute_will_change!('#{method_chain_array.last}')"
|
154
|
+
elsif method_chain_array.many?
|
155
|
+
method_chain_array[-1] = "attribute_will_change!('#{method_chain_array.last}')"
|
156
|
+
"#{method_chain_array.join('.')}"
|
157
|
+
end
|
158
|
+
|
139
159
|
<<-STRING
|
140
|
-
|
160
|
+
#{ will_change_statement }
|
141
161
|
#{change_statements.join("\n")}
|
142
162
|
STRING
|
143
163
|
end
|