workarea-global_e 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
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