workarea-global_e 1.2.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.
Files changed (232) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintrc.json +37 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  4. data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  6. data/.github/workflows/ci.yml +77 -0
  7. data/.gitignore +20 -0
  8. data/.rubocop.yml +2 -0
  9. data/.ruby-version +1 -0
  10. data/CHANGELOG.md +261 -0
  11. data/Gemfile +16 -0
  12. data/README.md +39 -0
  13. data/Rakefile +59 -0
  14. data/app/assets/javascripts/workarea/storefront/global_e/modules/checkout_info_validator.js +122 -0
  15. data/app/assets/javascripts/workarea/storefront/global_e/modules/suppress_price_ranges.js +19 -0
  16. data/app/controllers/workarea/admin/country_exceptions_controller.rb +67 -0
  17. data/app/controllers/workarea/admin/fixed_prices_controller.rb +89 -0
  18. data/app/controllers/workarea/admin/orders_controller.decorator +6 -0
  19. data/app/controllers/workarea/storefront/application_controller.decorator +30 -0
  20. data/app/controllers/workarea/storefront/checkouts_controller.decorator +22 -0
  21. data/app/controllers/workarea/storefront/ge_checkouts_controller.rb +10 -0
  22. data/app/controllers/workarea/storefront/global_e_controller.rb +42 -0
  23. data/app/controllers/workarea/storefront/globale/api_controller.rb +108 -0
  24. data/app/controllers/workarea/storefront/globale/refund_controller.rb +65 -0
  25. data/app/controllers/workarea/storefront/users/logins_controller.decorator +13 -0
  26. data/app/helpers/workarea/admin/global_e_helpers.rb +28 -0
  27. data/app/models/workarea/address.decorator +11 -0
  28. data/app/models/workarea/catalog/product.decorator +14 -0
  29. data/app/models/workarea/fulfillment/status/partially_refunded.rb +13 -0
  30. data/app/models/workarea/fulfillment/status/refunded.rb +15 -0
  31. data/app/models/workarea/fulfillment.decorator +55 -0
  32. data/app/models/workarea/global_e/country_exception.rb +37 -0
  33. data/app/models/workarea/global_e/fixed_price.rb +93 -0
  34. data/app/models/workarea/global_e/order_api_events.rb +29 -0
  35. data/app/models/workarea/order/item.decorator +46 -0
  36. data/app/models/workarea/order/status/pending_global_e_fraud_check.rb +12 -0
  37. data/app/models/workarea/order.decorator +64 -0
  38. data/app/models/workarea/payment/status/global_e_appoved.rb +9 -0
  39. data/app/models/workarea/payment/status/pending_global_e_fraud_check.rb +9 -0
  40. data/app/models/workarea/payment/tender/global_e_payment.rb +16 -0
  41. data/app/models/workarea/payment.decorator +10 -0
  42. data/app/models/workarea/price_adjustment.decorator +13 -0
  43. data/app/models/workarea/price_adjustment_set.decorator +25 -0
  44. data/app/models/workarea/pricing/calculators/item_calculator.decorator +48 -0
  45. data/app/models/workarea/pricing/collection.decorator +90 -0
  46. data/app/models/workarea/pricing/discount/appliation_group.decorator +16 -0
  47. data/app/models/workarea/pricing/discount/international_item_proxy.rb +27 -0
  48. data/app/models/workarea/pricing/discount/international_order.rb +29 -0
  49. data/app/models/workarea/pricing/discount.decorator +65 -0
  50. data/app/models/workarea/pricing/price_distributor.decorator +37 -0
  51. data/app/models/workarea/pricing/request.decorator +17 -0
  52. data/app/models/workarea/pricing/sku.decorator +17 -0
  53. data/app/models/workarea/search/admin/order.decorator +11 -0
  54. data/app/models/workarea/shipping/sku.decorator +23 -0
  55. data/app/models/workarea/shipping.decorator +11 -0
  56. data/app/models/workarea/user.decorator +10 -0
  57. data/app/seeds/workarea/global_e_seeds.rb +66 -0
  58. data/app/services/workarea/create_fulfillment.decorator +12 -0
  59. data/app/services/workarea/global_e/address_details.rb +218 -0
  60. data/app/services/workarea/global_e/api/notify_order_refunded.rb +45 -0
  61. data/app/services/workarea/global_e/api/perform_order_payment.rb +46 -0
  62. data/app/services/workarea/global_e/api/remove_restricted_products.rb +28 -0
  63. data/app/services/workarea/global_e/api/send_order_to_merchant/item_pricer.rb +147 -0
  64. data/app/services/workarea/global_e/api/send_order_to_merchant/save_user.rb +59 -0
  65. data/app/services/workarea/global_e/api/send_order_to_merchant.rb +359 -0
  66. data/app/services/workarea/global_e/api/update_order_shipping_info.rb +38 -0
  67. data/app/services/workarea/global_e/api/update_order_status/canceled.rb +42 -0
  68. data/app/services/workarea/global_e/api/update_order_status.rb +28 -0
  69. data/app/services/workarea/global_e/attribute.rb +44 -0
  70. data/app/services/workarea/global_e/brand.rb +19 -0
  71. data/app/services/workarea/global_e/cart_user_details.rb +34 -0
  72. data/app/services/workarea/global_e/category.rb +19 -0
  73. data/app/services/workarea/global_e/checkout_cart_info.rb +358 -0
  74. data/app/services/workarea/global_e/custom_product_attribute.rb +19 -0
  75. data/app/services/workarea/global_e/discount.rb +215 -0
  76. data/app/services/workarea/global_e/merchant/brand.rb +21 -0
  77. data/app/services/workarea/global_e/merchant/category.rb +21 -0
  78. data/app/services/workarea/global_e/merchant/customer.rb +36 -0
  79. data/app/services/workarea/global_e/merchant/customer_details.rb +201 -0
  80. data/app/services/workarea/global_e/merchant/discount.rb +127 -0
  81. data/app/services/workarea/global_e/merchant/international_details.rb +296 -0
  82. data/app/services/workarea/global_e/merchant/order.rb +425 -0
  83. data/app/services/workarea/global_e/merchant/order_refund.rb +103 -0
  84. data/app/services/workarea/global_e/merchant/original_order.rb +28 -0
  85. data/app/services/workarea/global_e/merchant/parcel_tracking.rb +31 -0
  86. data/app/services/workarea/global_e/merchant/payment_details.rb +161 -0
  87. data/app/services/workarea/global_e/merchant/product.rb +222 -0
  88. data/app/services/workarea/global_e/merchant/refund_product.rb +69 -0
  89. data/app/services/workarea/global_e/merchant/response_info.rb +115 -0
  90. data/app/services/workarea/global_e/merchant_cart_product_attribute.rb +21 -0
  91. data/app/services/workarea/global_e/order_status.rb +20 -0
  92. data/app/services/workarea/global_e/order_status_details.rb +79 -0
  93. data/app/services/workarea/global_e/order_status_reason.rb +20 -0
  94. data/app/services/workarea/global_e/parcel.rb +53 -0
  95. data/app/services/workarea/global_e/product.rb +612 -0
  96. data/app/services/workarea/global_e/product_meta_data.rb +13 -0
  97. data/app/services/workarea/global_e/tracking_details.rb +23 -0
  98. data/app/services/workarea/global_e/update_order_dispatch_exception.rb +46 -0
  99. data/app/services/workarea/global_e/update_order_dispatch_request.rb +108 -0
  100. data/app/services/workarea/global_e/user_id_number_type.rb +21 -0
  101. data/app/services/workarea/global_e/users_details.rb +151 -0
  102. data/app/services/workarea/global_e/vat_category.rb +20 -0
  103. data/app/services/workarea/global_e/vat_rate_type.rb +27 -0
  104. data/app/services/workarea/save_order_analytics.decorator +18 -0
  105. data/app/view_models/workarea/admin/order_view_model.decorator +13 -0
  106. data/app/view_models/workarea/storefront/cart_view_model.decorator +7 -0
  107. data/app/view_models/workarea/storefront/order_item_view_model.decorator +16 -0
  108. data/app/view_models/workarea/storefront/order_view_model.decorator +45 -0
  109. data/app/view_models/workarea/storefront/product_view_model.decorator +35 -0
  110. data/app/views/workarea/admin/catalog_products/_country_exceptions_card.html.haml +31 -0
  111. data/app/views/workarea/admin/catalog_products/_global_e_attributes.html.haml +3 -0
  112. data/app/views/workarea/admin/catalog_products/_global_e_fields.html.haml +4 -0
  113. data/app/views/workarea/admin/country_exceptions/edit.html.haml +48 -0
  114. data/app/views/workarea/admin/country_exceptions/index.html.haml +47 -0
  115. data/app/views/workarea/admin/country_exceptions/new.html.haml +44 -0
  116. data/app/views/workarea/admin/fixed_prices/edit.html.haml +73 -0
  117. data/app/views/workarea/admin/fixed_prices/index.html.haml +55 -0
  118. data/app/views/workarea/admin/fixed_prices/new.html.haml +70 -0
  119. data/app/views/workarea/admin/orders/_global_e.html.haml +27 -0
  120. data/app/views/workarea/admin/orders/attributes.html.haml +131 -0
  121. data/app/views/workarea/admin/orders/global_e.html.haml +110 -0
  122. data/app/views/workarea/admin/orders/show.html.haml +27 -0
  123. data/app/views/workarea/admin/orders/tenders/_global_e_payment.html.haml +3 -0
  124. data/app/views/workarea/admin/pricing_skus/_cards.html.haml +98 -0
  125. data/app/views/workarea/storefront/cart_items/create.html.haml +71 -0
  126. data/app/views/workarea/storefront/carts/_pricing.html.haml +14 -0
  127. data/app/views/workarea/storefront/carts/show.html.haml +187 -0
  128. data/app/views/workarea/storefront/ge_checkouts/show.html.haml +1 -0
  129. data/app/views/workarea/storefront/global_e/_country_picker.html.haml +1 -0
  130. data/app/views/workarea/storefront/global_e/_head.html.haml +10 -0
  131. data/app/views/workarea/storefront/orders/_summary.html.haml +275 -0
  132. data/app/views/workarea/storefront/orders/tenders/_global_e_payment.html.haml +3 -0
  133. data/app/views/workarea/storefront/products/_pricing.html.haml +49 -0
  134. data/app/views/workarea/storefront/products/_restricted_item_text.html.haml +1 -0
  135. data/app/views/workarea/storefront/users/orders/_summary.html.haml +22 -0
  136. data/app/workers/workarea/global_e/update_order_dispatch.rb +28 -0
  137. data/app/workers/workarea/save_user_order_details.decorator +9 -0
  138. data/bin/rails +25 -0
  139. data/config/initializers/appends.rb +46 -0
  140. data/config/initializers/seeds.rb +1 -0
  141. data/config/initializers/workarea.rb +64 -0
  142. data/config/locales/en.yml +105 -0
  143. data/config/routes.rb +31 -0
  144. data/lib/workarea/global_e/engine.rb +10 -0
  145. data/lib/workarea/global_e/error.rb +8 -0
  146. data/lib/workarea/global_e/version.rb +5 -0
  147. data/lib/workarea/global_e.rb +58 -0
  148. data/script/admin_ci +5 -0
  149. data/script/ci +8 -0
  150. data/script/core_ci +5 -0
  151. data/script/plugins_ci +5 -0
  152. data/script/storefront_ci +5 -0
  153. data/test/dummy/.ruby-version +1 -0
  154. data/test/dummy/Rakefile +6 -0
  155. data/test/dummy/app/assets/config/manifest.js +3 -0
  156. data/test/dummy/app/assets/images/.keep +0 -0
  157. data/test/dummy/app/assets/javascripts/application.js +14 -0
  158. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  159. data/test/dummy/app/controllers/application_controller.rb +2 -0
  160. data/test/dummy/app/controllers/concerns/.keep +0 -0
  161. data/test/dummy/app/helpers/application_helper.rb +2 -0
  162. data/test/dummy/app/jobs/application_job.rb +2 -0
  163. data/test/dummy/app/mailers/application_mailer.rb +4 -0
  164. data/test/dummy/app/models/concerns/.keep +0 -0
  165. data/test/dummy/app/views/layouts/application.html.erb +15 -0
  166. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  167. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  168. data/test/dummy/bin/bundle +3 -0
  169. data/test/dummy/bin/rails +4 -0
  170. data/test/dummy/bin/rake +4 -0
  171. data/test/dummy/bin/setup +28 -0
  172. data/test/dummy/bin/update +28 -0
  173. data/test/dummy/bin/yarn +11 -0
  174. data/test/dummy/config/application.rb +23 -0
  175. data/test/dummy/config/boot.rb +5 -0
  176. data/test/dummy/config/environment.rb +5 -0
  177. data/test/dummy/config/environments/development.rb +52 -0
  178. data/test/dummy/config/environments/production.rb +83 -0
  179. data/test/dummy/config/environments/test.rb +45 -0
  180. data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
  181. data/test/dummy/config/initializers/assets.rb +14 -0
  182. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  183. data/test/dummy/config/initializers/content_security_policy.rb +25 -0
  184. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  185. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  186. data/test/dummy/config/initializers/inflections.rb +16 -0
  187. data/test/dummy/config/initializers/mime_types.rb +4 -0
  188. data/test/dummy/config/initializers/workarea.rb +5 -0
  189. data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
  190. data/test/dummy/config/locales/en.yml +33 -0
  191. data/test/dummy/config/puma.rb +34 -0
  192. data/test/dummy/config/routes.rb +5 -0
  193. data/test/dummy/config/secrets.yml +18 -0
  194. data/test/dummy/config/spring.rb +6 -0
  195. data/test/dummy/config.ru +5 -0
  196. data/test/dummy/db/seeds.rb +2 -0
  197. data/test/dummy/lib/assets/.keep +0 -0
  198. data/test/dummy/log/.keep +0 -0
  199. data/test/factories/workarea/global_e_factories.rb +836 -0
  200. data/test/integration/workarea/admin/catalog_product_country_exceptions_integration_test.rb +81 -0
  201. data/test/integration/workarea/admin/global_e_jump_to_integration_test.rb +20 -0
  202. data/test/integration/workarea/admin/pricing_sku_fixed_prices_integration_test.rb +83 -0
  203. data/test/integration/workarea/storefront/global_e_api/receive_order_integration_test.rb +278 -0
  204. data/test/integration/workarea/storefront/global_e_api/receive_order_refund_integration_test.rb +25 -0
  205. data/test/integration/workarea/storefront/global_e_api/receive_payment_integration_test.rb +34 -0
  206. data/test/integration/workarea/storefront/global_e_api/receive_shipping_info_integration_test.rb +29 -0
  207. data/test/integration/workarea/storefront/global_e_api/remove_restricted_products_integration_test.rb +27 -0
  208. data/test/integration/workarea/storefront/global_e_api/update_order_status_integration_test.rb +29 -0
  209. data/test/integration/workarea/storefront/global_e_checkout_cart_info/fixed_pricing_test.rb +438 -0
  210. data/test/integration/workarea/storefront/global_e_checkout_cart_info/gift_card_test.rb +63 -0
  211. data/test/integration/workarea/storefront/global_e_checkout_cart_info_integration_test.rb +660 -0
  212. data/test/integration/workarea/storefront/global_e_checkouts_integration_test.rb +71 -0
  213. data/test/integration/workarea/storefront/users/global_e_logins_integration_test.rb +20 -0
  214. data/test/models/workarea/catalog/product_global_e_test.rb +13 -0
  215. data/test/models/workarea/fixed_pricing_test.rb +117 -0
  216. data/test/models/workarea/global_e/country_exception_test.rb +36 -0
  217. data/test/models/workarea/payment_test.decorator +31 -0
  218. data/test/models/workarea/pricing/calculators/item_calculator_fixed_prices_test.rb +83 -0
  219. data/test/models/workarea/pricing/collection_fixed_prices_test.rb +83 -0
  220. data/test/models/workarea/pricing/price_distributor_test.decorator +21 -0
  221. data/test/models/workarea/pricing/sku_fixed_price_test.rb +133 -0
  222. data/test/support/workarea/global_e_support.rb +18 -0
  223. data/test/system/workarea/admin/global_e_system_test.rb +21 -0
  224. data/test/system/workarea/storefront/global_e_cart_system_test.rb +48 -0
  225. data/test/system/workarea/storefront/global_e_order_history_system_test.rb +43 -0
  226. data/test/teaspoon_env.rb +6 -0
  227. data/test/test_helper.rb +9 -0
  228. data/test/view_models/workarea/admin/global_e_order_view_model_test.rb +22 -0
  229. data/test/workers/workarea/global_e/update_order_dispatch_test.rb +64 -0
  230. data/test/workers/workarea/global_e_save_user_order_details_test.rb +41 -0
  231. data/workarea-global_e.gemspec +16 -0
  232. metadata +293 -0
@@ -0,0 +1,53 @@
1
+ module Workarea
2
+ module GlobalE
3
+ class Parcel
4
+ attr_reader :fulfillment, :package
5
+
6
+ def initialize(fulfillment, package)
7
+ @fulfillment = fulfillment
8
+ @package = package
9
+ end
10
+
11
+ def as_json(*)
12
+ {
13
+ ParcelCode: parcel_code,
14
+ Products: products,
15
+ TrackingDetails: tracking_details
16
+ }
17
+ end
18
+
19
+ # Code used to identify the Parcel on the Merchant’s site
20
+ #
21
+ # @return [String]
22
+ #
23
+ def parcel_code
24
+ package.tracking_number
25
+ end
26
+
27
+ # List of products contained in the parcel (for each Product object the
28
+ # following fields are relevant when used in Parcel class: ProductCode,
29
+ # CartItemId, DeliveryQuantity). Products list is applicable only when
30
+ # including the list of products in each parcel is mandatory (such as in
31
+ # UpdateParcelDispatch method).
32
+ #
33
+ # @return [Hash]
34
+ #
35
+ def products
36
+ @products ||= package.items.map do |fulfillment_item|
37
+ GlobalE::Product.from_order_item(
38
+ fulfillment_item,
39
+ delivery_quantity: fulfillment_item.quantity
40
+ ).as_json.slice(:CartItemId, :DeliveryQuantity, :ProductCode)
41
+ end
42
+ end
43
+
44
+ # Tracking information about the order/parcel.
45
+ #
46
+ # @return [Workarea::GlobalE::TrackingDetails]
47
+ #
48
+ def tracking_details
49
+ TrackingDetails.new(tracking_number: package.tracking_number)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,612 @@
1
+ module Workarea
2
+ module GlobalE
3
+ class Product
4
+ module ProductUrl
5
+ include Workarea::I18n::DefaultUrlOptions
6
+ include Storefront::Engine.routes.url_helpers
7
+ extend self
8
+ end
9
+ module ProductImageUrl
10
+ include Workarea::ApplicationHelper
11
+ include Workarea::I18n::DefaultUrlOptions
12
+ include ActionView::Helpers::AssetUrlHelper
13
+ include Core::Engine.routes.url_helpers
14
+ extend self
15
+
16
+ def mounted_core
17
+ self
18
+ end
19
+ end
20
+
21
+ attr_reader :product, :sku, :order_item, :delivery_quantity
22
+
23
+ def self.from_order_item(order_item, delivery_quantity: nil)
24
+ product = if order_item.product_attributes.present?
25
+ Mongoid::Factory.from_db(Catalog::Product, order_item.product_attributes)
26
+ else
27
+ Catalog::Product.find_by_sku(order_item.sku)
28
+ end
29
+ new(product, order_item.sku, order_item: order_item, delivery_quantity: delivery_quantity)
30
+ end
31
+
32
+ def initialize(product, sku, order_item: nil, delivery_quantity: nil)
33
+ @product = product
34
+ @sku = sku
35
+ @order_item = order_item
36
+ @delivery_quantity = delivery_quantity
37
+ end
38
+
39
+ def as_json(*args)
40
+ {
41
+ ProductCode: product_code,
42
+ ProductGroupCode: product_group_code,
43
+ CartItemId: cart_item_id,
44
+ Name: name,
45
+ Description: description,
46
+ URL: url,
47
+ Weight: weight,
48
+ Height: height,
49
+ Width: width,
50
+ Length: length,
51
+ ImageURL: catalog_product_image_url,
52
+ ImageHeight: image_height,
53
+ ImageWidth: image_width,
54
+ ListPrice: list_price,
55
+ OriginalListPrice: original_list_price,
56
+ IsFixedPrice: is_fixed_price,
57
+ OrderedQuantity: ordered_quantity,
58
+ DeliveryQuantity: delivery_quantity,
59
+ IsVirtual: is_virtual,
60
+ IsBlockedForGlobalE: is_blocked_for_global_e,
61
+ Attributes: attributes,
62
+ SalePrice: sale_price,
63
+ OriginalSalePrice: original_sale_price
64
+ }.compact
65
+ end
66
+
67
+ # SKU code used to identify the product on the Merchant’s site (to be
68
+ # mapped on Global-e side)
69
+ #
70
+ # @return [String]
71
+ #
72
+ def product_code
73
+ sku
74
+ end
75
+
76
+ # Product’s group code on the Merchant’s site (to be mapped on
77
+ # Global-e side). Usually this value is a part of product SKU code
78
+ # denoting a group of similar products (such as "the same product in
79
+ # different colors").
80
+ #
81
+ # optional
82
+ #
83
+ # @return [String]
84
+ #
85
+ def product_group_code
86
+ product.id
87
+ end
88
+
89
+ # Secondary code that may be used to refer to the product on the
90
+ # Merchant’s site. This code may be used in addition to the ProductCode
91
+ # and is not guaranteed to be unique (may be reused for other products
92
+ # as long as the old product is not available on the merchant’s
93
+ # site anymore).
94
+ #
95
+ # @return [String]
96
+ #
97
+ def product_code_secondary
98
+ end
99
+
100
+ # Secondary code that may be used to refer to the group of products
101
+ # on the Merchant’s site. This code may be used in addition to the
102
+ # ProductGroupCode and is not guaranteed to be unique (may be reused
103
+ # for other groups as long as the old group is not available on the
104
+ # merchant’s site anymore).
105
+ #
106
+ # optional
107
+ #
108
+ # @return [String]
109
+ #
110
+ def product_group_code_secondary
111
+ end
112
+
113
+ # Identifier of the cart item on the Merchant’s site. This property may
114
+ # be optionally specified in SendCart method only, so that the same
115
+ # value could be posted back when creating the order on the Merchant’s
116
+ # site with SendOrderToMerchant method.
117
+ #
118
+ # @return [nil, String]
119
+ #
120
+ def cart_item_id
121
+ return unless order_item.present?
122
+
123
+ order_item.id.to_s
124
+ end
125
+
126
+ # Identifier of the current item’s parent cart item on the Merchant’s
127
+ # site. This value must be specified if the current cart item is
128
+ # related to a parent item (CartItemId must not be specified for this
129
+ # item because this attribute is applicable only to the “parent” item
130
+ # itself). For example, this item might indicate a custom option (such
131
+ # as product package) for the parent item in the same cart. This property
132
+ # may be optionally specified in SendCart method only, so that the
133
+ # same value could be posted back when creating the order on the
134
+ # Merchant’s site with SendOrderToMerchant method.
135
+ #
136
+ # @return [String]
137
+ #
138
+ def parent_cart_item_id
139
+ end
140
+
141
+ # Identifier of the child cart item “option” on the Merchant’s site.
142
+ # This value must be specified if the current cart item is related to a
143
+ # parent item (CartItemId must not be specified for this item because
144
+ # this attribute is applicable only to the “parent” item itself).
145
+ # For example, this item might indicate a package for the parent item
146
+ # in the same cart. This property may be optionally specified in
147
+ # SendCart method only, so that the same value could be posted back
148
+ # when creating the order on the Merchant’s site with
149
+ # SendOrderToMerchant method.
150
+ #
151
+ # @return [String]
152
+ #
153
+ def cart_item_option_id
154
+ end
155
+
156
+ # Name of the Product
157
+ #
158
+ # @return [String]
159
+ #
160
+ def name
161
+ product.name
162
+ end
163
+
164
+ # Name of the Product in English
165
+ #
166
+ # @return [String]
167
+ #
168
+ def name_english
169
+ end
170
+
171
+ # Description of the Product
172
+ #
173
+ # @return [String]
174
+ #
175
+ def description
176
+ product.description
177
+ end
178
+
179
+ # Description of the Product in English
180
+ #
181
+ # @return [String]
182
+ #
183
+ def description_english
184
+ end
185
+
186
+ # Product’s keywords
187
+ #
188
+ # @return [String]
189
+ #
190
+ def keywords
191
+ end
192
+
193
+ # Product’s information page URL
194
+ #
195
+ # @return [String]
196
+ #
197
+ def url
198
+ ProductUrl.product_url(product, host: Workarea.config.host)
199
+ end
200
+
201
+ # Optional “gift message” text defined by the end customer that
202
+ # should be printed on the product.
203
+ #
204
+ # @return [String]
205
+ #
206
+ def gift_message
207
+ end
208
+
209
+ # Product’s generic (not country-specific) HS Code. If specified
210
+ # this property may assist in mapping the product for duties and
211
+ # taxes calculation purposes.
212
+ #
213
+ # @return [String]
214
+ #
215
+ def generic_hs_code
216
+ end
217
+
218
+ # 2-char ISO country code of the product’s country of Origin.
219
+ # The Merchant’s country will be assumed if not specified.
220
+ #
221
+ # @return [String]
222
+ #
223
+ def origin_country_code
224
+ end
225
+
226
+ # Product’s weight in Merchant’s default unit of weight
227
+ # measure (will be converted to grams).
228
+ # Merchant’s default product weight will be used if not specified.
229
+ #
230
+ # @return [Float]
231
+ #
232
+ def weight
233
+ shipping_sku&.weight
234
+ end
235
+
236
+ # Product’s net weight in Merchant’s default unit of weight
237
+ # measure (will be converted to grams). If specified, this property
238
+ # indicates net weight of the product, excluding any packaging.
239
+ #
240
+ # @return [Float]
241
+ #
242
+ def net_weight
243
+ end
244
+
245
+ # Product’s height in Merchant’s default unit of length measure
246
+ # (will be converted to CM).
247
+ #
248
+ # @return [Float]
249
+ #
250
+ def height
251
+ shipping_sku&.height
252
+ end
253
+
254
+ # Product’s width in Merchant’s default unit of length measure
255
+ # (will be converted to CM).
256
+ #
257
+ # @return [Float]
258
+ #
259
+ def width
260
+ shipping_sku&.width
261
+ end
262
+
263
+ # Product’s length in Merchant’s default unit of length measure
264
+ # (will be converted to CM).
265
+ #
266
+ # @return [Float[
267
+ #
268
+ def length
269
+ shipping_sku&.length
270
+ end
271
+
272
+ # Product’s volume in Merchant’s default unit of volume measure
273
+ # (will be converted to cubic CM).
274
+ # (optional, and alternative for specifying all 3 dimensions above)
275
+ #
276
+ # @return [Float]
277
+ #
278
+ def volume
279
+ end
280
+
281
+ # Product’s net volume in Merchant’s default unit of volume measure
282
+ # (will be converted to cubic CM). If specified, this property
283
+ # indicates net volume of the product, excluding any packaging.
284
+ #
285
+ # @return [Float]
286
+ #
287
+ def net_volume
288
+ end
289
+
290
+ # Product’s image URL
291
+ #
292
+ # @return [String]
293
+ #
294
+ def catalog_product_image_url
295
+ return unless image = variant_image || product.images.first
296
+ @catalog_product_image_url ||= ProductImageUrl.product_image_url(image, :detail)
297
+ end
298
+
299
+ # Product’s image height in pixels
300
+ #
301
+ # @return [Integer]
302
+ #
303
+ def image_height
304
+ return unless image = variant_image || product.images.first
305
+ image.image_height
306
+ end
307
+
308
+ # Product’s image width in pixels
309
+ #
310
+ # @return [Integer]
311
+ #
312
+ def image_width
313
+ return unless image = variant_image || product.images.first
314
+ image.image_width
315
+ end
316
+
317
+ # Product list price (before any discounts) as displayed to the
318
+ # customer, after applying country coefficient, FX conversion,
319
+ # rounding rule (if applicable) and IncludingVAT handling.
320
+ # (optional in SendCart, SaveProductsBulk)
321
+ #
322
+ # @return [Float]
323
+ #
324
+ def list_price
325
+ return 0 unless is_fixed_price
326
+
327
+ order_item.international_price_adjustments.first.data['original_price'].to_f
328
+ end
329
+
330
+ # Product list price (before any discounts) in original Merchant’s
331
+ # currency including the local VAT, before applying any price
332
+ # modifications. This property always denotes the product’s price in
333
+ # the default Merchant’s country, regardless of UseCountryVAT
334
+ # for the end customer’s current country.
335
+ # (optional in SendCart, SaveProductsBulk)
336
+ #
337
+ # @return [Float]
338
+ #
339
+ def original_list_price
340
+ return 0 if is_fixed_price
341
+
342
+ order_item.price_adjustments&.first&.data['original_price']&.to_f ||
343
+ pricing_sku.find_price(quantity: ordered_quantity).regular.to_f
344
+ end
345
+
346
+ # Product sale price as displayed to the customer, after applying
347
+ # country coefficient, FX conversion, rounding rule
348
+ # (if applicable) and IncludeVAT handling.
349
+ # (optionalinSaveProductsList,SaveProductsBulk,GetCheckoutCartInfo)
350
+ #
351
+ # @return [Float]
352
+ #
353
+ def sale_price
354
+ return 0 unless is_fixed_price
355
+
356
+ order_item.international_price_adjustments.first.unit.to_f
357
+ end
358
+
359
+ # Product sale price as displayed to the customer, after applying
360
+ # country coefficient, FX conversion and IncludeVAT handling, before
361
+ # rounding rules have been applied. If not specified, will be deemed
362
+ # equal to SalePrice.
363
+ #
364
+ # @return [Float]
365
+ #
366
+ def sale_price_before_rounding
367
+ end
368
+
369
+ # Line item (product in ordered quantity) sale price as displayed to
370
+ # the customer, after applying country coefficient, FX conversion and
371
+ # IncludeVAT handling, before rounding rules have been applied. If not
372
+ # specified, will be deemed equal to “SalePrice * OrderedQuantity”. If
373
+ # specified, will take preference over SalePrice.
374
+ #
375
+ # @return [Float]
376
+ #
377
+ def line_item_sale_price
378
+ end
379
+
380
+ # Product sale price in original Merchant’s currency including the
381
+ # local VAT, before applying any price modifications. This property
382
+ # always denotes the product’s price in the default Merchant’s country,
383
+ # regardless of UseCountryVAT for the end customer’s current country.
384
+ # (optional in SaveProductsList, SaveProductsBulk)
385
+ #
386
+ # @return [Float]
387
+ #
388
+ #
389
+ def original_sale_price
390
+ return 0 if is_fixed_price
391
+
392
+ order_item.price_adjustments.first.unit.to_f
393
+ end
394
+
395
+ # Line item (product in ordered quantity) sale price in original
396
+ # Merchant’s currency including the local VAT, before applying any
397
+ # price modifications. This property always denotes the price in the
398
+ # default Merchant’s country, regardless of UseCountryVAT for the end
399
+ # customer’s current country. If not specified, will be deemed equal to
400
+ # “OriginalSalePrice * OrderedQuantity”. If specified, will take
401
+ # preference over OriginalSalePrice.
402
+ #
403
+ # @return [Float]
404
+ #
405
+ def line_item_original_sale_price
406
+ end
407
+
408
+ # Reason for the sale price. This property may optionally contain the
409
+ # text definition of the promo that has resulted in the price deduction
410
+ # for this product (such as “10% discount on all shoes”).
411
+ #
412
+ # @return [String]
413
+ #
414
+ def sale_price_reason
415
+ end
416
+
417
+ # Setting this to TRUE indicates that the product’s price is fixed by
418
+ # the Merchant, in the default currency for the country. In this case,
419
+ # all price modifications are disabled for this product. Setting fixed
420
+ # prices is only allowed for the Countries where SupportsFixedPrices
421
+ # flag is set to TRUE.
422
+ #
423
+ # @return [Boolean]
424
+ #
425
+ def is_fixed_price
426
+ order_item.order.fixed_pricing
427
+ end
428
+
429
+ # Ordered quantity for the product (to be used in Checkout / Order
430
+ # methods described below, as needed)
431
+ #
432
+ # @return [Integer]
433
+ #
434
+ def ordered_quantity
435
+ order_item.quantity
436
+ end
437
+
438
+ # Quantity actually set for delivery for the product (to be used in
439
+ # Order methods described below, as needed)
440
+ #
441
+ # @return [Integer, nil]
442
+ #
443
+ def delivery_quantity
444
+ @delivery_quantity.presence
445
+ end
446
+
447
+ # Setting this to TRUE indicates that the product represents a set of
448
+ # other products. If a bundled product has non-zero prices specified
449
+ # (i.e. OriginalListPrice, ListPrice, etc.), then all the contained
450
+ # products must have zero prices, and vice versa, to avoid double
451
+ # charging for the same products.
452
+ #
453
+ # @return [Boolean]
454
+ #
455
+ #
456
+ def is_bundle
457
+ end
458
+
459
+ # Setting this to TRUE indicates that the product represents a virtual
460
+ # product that does not have weight or volume and doesn’t affect
461
+ # shipping calculation in Global-e checkout.
462
+ #
463
+ # @return [Boolean]
464
+ #
465
+ def is_virtual
466
+ product.digital?
467
+ end
468
+
469
+ # Setting this to TRUE indicates that the product is not available
470
+ # for international shipping
471
+ #
472
+ # @return [Boolean]
473
+ #
474
+ def is_blocked_for_global_e
475
+ return true if product.try(:gift_card?)
476
+
477
+ product.global_e_forbidden?
478
+ end
479
+
480
+ # Code applicable to the product on the Merchant’s site. This code may
481
+ # be optionally used by the Merchant to trigger a certain business logic
482
+ # when this product is included in the order posted back to the
483
+ # Merchant’s site with SendOrderToMerchant method.
484
+ #
485
+ # @return [String]
486
+ #
487
+ def handling_code
488
+ end
489
+
490
+ # Product’s VAT rate type or class
491
+ #
492
+ # @return [Workarea::GlobalE::VATRateType]
493
+ #
494
+ def vat_rate_type
495
+ end
496
+
497
+ # VAT rate type or class that would be applied to this product if the
498
+ # order was placed by the local customer. This value must be specified
499
+ # if UseCountryVAT for the current Country is TRUE, and therefore
500
+ # VATRateType property actually denotes the VAT for the target country.
501
+ #
502
+ # @return [Workarea::GlobalE::VATRateType]
503
+ #
504
+ def local_vat_rate_type
505
+ end
506
+
507
+ # Product’s VAT category. A product may be assigned to a single VAT
508
+ # category on the merchant’s site. If available, the respective
509
+ # product’s HS Code should be used as VAT category for a product.
510
+ #
511
+ # @return [Workarea::GlobalE::VatCategory]
512
+ #
513
+ def vat_category
514
+ end
515
+
516
+ # Product's brand
517
+ #
518
+ # @return [Workarea::GlobalE::Brand]
519
+ #
520
+ def brand
521
+ end
522
+
523
+ # Product's categories
524
+ #
525
+ # @return [Array<Workarea::GlobalE::Category>]
526
+ #
527
+ def categories
528
+ end
529
+
530
+ # Product’s custom attributes (such as Color, Size, etc.)
531
+ #
532
+ # @return [Array<Workarea::GlobalE::Attribute>]
533
+ #
534
+ def attributes
535
+ variant.details.map do |key, values|
536
+ GlobalE::Attribute.new(type_code: key, name: values.join(", "), code: key)
537
+ end
538
+ end
539
+
540
+ # Product’s custom attributes (such as Color, Size, etc.) in English
541
+ #
542
+ # @return [Array<Workarea::GlobalE::Attribute>]
543
+ #
544
+ def attributes_english
545
+ end
546
+
547
+ # Boolean specifying if the product was ordered as a backed ordered item
548
+ #
549
+ # @return [Boolean[
550
+ #
551
+ def is_back_ordered
552
+ end
553
+
554
+ # Estimated date for the backordered item to be in stock
555
+ #
556
+ # @return [String]
557
+ #
558
+ def back_order_date
559
+ end
560
+
561
+ # Product class code used by the merchant to classify products for
562
+ # using different country coefficient rates.
563
+ #
564
+ # @return [String]
565
+ #
566
+ def product_class_code
567
+ end
568
+
569
+ # Rate applicable to this Product’s ProductClassCode if returned from
570
+ # CountryCoefficients method.
571
+ #
572
+ # @return [Float]
573
+ #
574
+ def price_coefficient_rate
575
+ end
576
+
577
+ # Used to hold additional product data such as customer-defined product attributes.
578
+ #
579
+ # @return [Workarea::GlobalE::ProductMetaData]
580
+ #
581
+ def product_meta_data
582
+ end
583
+
584
+ private
585
+
586
+ def variant
587
+ @variant ||= product.variants.find_by(sku: sku)
588
+ end
589
+
590
+ def pricing_sku
591
+ @pricing_sku ||= Pricing::Sku.find(sku)
592
+ end
593
+
594
+ def shipping_sku
595
+ @shipping_sku ||= Shipping::Sku.find(sku) rescue nil
596
+ end
597
+
598
+ def variant_image
599
+ @variant_image ||=
600
+ begin
601
+ sku_options = variant.details.values.flat_map { |options| options.map(&:optionize) }
602
+
603
+ product.images.detect do |image|
604
+ next unless image.option.present?
605
+
606
+ sku_options.include?(image.option.optionize)
607
+ end
608
+ end
609
+ end
610
+ end
611
+ end
612
+ end
@@ -0,0 +1,13 @@
1
+ module Workarea
2
+ module GlobalE
3
+ class ProductMetaData
4
+ # Customer-defined product attributes that allow to personalize the
5
+ # product if supported by the merchant’s site (e.g. engraving).
6
+ #
7
+ # @return [Array<Workarea::GlobalE::CustomProductAttribute>]
8
+ #
9
+ def attributes
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ module Workarea
2
+ module GlobalE
3
+ class TrackingDetails
4
+ attr_reader :tracking_number
5
+
6
+ def initialize(tracking_number:)
7
+ @tracking_number = tracking_number
8
+ end
9
+
10
+ def as_json(*)
11
+ { TrackingNumber: tracking_number }
12
+ end
13
+
14
+ # The tracking number as the shipper has specified.
15
+ #
16
+ # @return [String]
17
+ #
18
+ def tracking_number
19
+ @tracking_number
20
+ end
21
+ end
22
+ end
23
+ end