workarea-flow_io 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (272) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintignore +2 -0
  3. data/.eslintrc.json +37 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  5. data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
  6. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  7. data/.github/workflows/ci.yml +90 -0
  8. data/.gitignore +21 -0
  9. data/.rubocop.yml +2 -0
  10. data/.ruby-version +1 -0
  11. data/.stylelintrc.json +12 -0
  12. data/CHANGELOG.md +200 -0
  13. data/Gemfile +19 -0
  14. data/LICENSE +52 -0
  15. data/README.md +200 -0
  16. data/Rakefile +59 -0
  17. data/app/assets/javascripts/workarea/storefront/flow_io/adapters/flow_io_adapter.js +61 -0
  18. data/app/assets/javascripts/workarea/storefront/flow_io/configuration.js.erb +10 -0
  19. data/app/assets/javascripts/workarea/storefront/flow_io/flow.js +91 -0
  20. data/app/assets/stylesheets/flow_io/storefront/country_picker.scss +189 -0
  21. data/app/controllers/workarea/admin/application_controller.decorator +5 -0
  22. data/app/controllers/workarea/admin/catalog_categories_controller.decorator +9 -0
  23. data/app/controllers/workarea/admin/flow_imports_controller.rb +9 -0
  24. data/app/controllers/workarea/admin/orders_controller.decorator +6 -0
  25. data/app/controllers/workarea/admin/pricing_skus_controller.decorator +7 -0
  26. data/app/controllers/workarea/admin/search_settings_controller.decorator +27 -0
  27. data/app/controllers/workarea/storefront/application_controller.decorator +80 -0
  28. data/app/controllers/workarea/storefront/checkouts_controller.decorator +38 -0
  29. data/app/controllers/workarea/storefront/flow_io_webhook_controller.rb +49 -0
  30. data/app/controllers/workarea/storefront/recent_views_controller.decorator +15 -0
  31. data/app/controllers/workarea/storefront/searches_controller.decorator +11 -0
  32. data/app/helpers/workarea/admin/flow_helper.rb +13 -0
  33. data/app/helpers/workarea/storefront/flow_analytics_helper.rb +23 -0
  34. data/app/helpers/workarea/storefront/flow_content_helper.rb +21 -0
  35. data/app/middleware/workarea/flow_io/session_middleware.rb +68 -0
  36. data/app/models/workarea/address.decorator +12 -0
  37. data/app/models/workarea/catalog/category.decorator +8 -0
  38. data/app/models/workarea/checkout.decorator +26 -0
  39. data/app/models/workarea/flow_io/experience_geo.rb +18 -0
  40. data/app/models/workarea/flow_io/experience_summary.rb +15 -0
  41. data/app/models/workarea/flow_io/import.rb +31 -0
  42. data/app/models/workarea/flow_io/imported_item.rb +124 -0
  43. data/app/models/workarea/flow_io/local_item.rb +28 -0
  44. data/app/models/workarea/flow_io/localized_price.rb +30 -0
  45. data/app/models/workarea/flow_io/price.rb +12 -0
  46. data/app/models/workarea/flow_io/price_with_base.rb +7 -0
  47. data/app/models/workarea/flow_io/webhook/shared_secret.rb +12 -0
  48. data/app/models/workarea/flow_price_adjustment_set.rb +80 -0
  49. data/app/models/workarea/fulfillment.decorator +63 -0
  50. data/app/models/workarea/order.decorator +39 -0
  51. data/app/models/workarea/order/item.decorator +43 -0
  52. data/app/models/workarea/payment.decorator +11 -0
  53. data/app/models/workarea/payment/authorize/flow_payment.rb +48 -0
  54. data/app/models/workarea/payment/capture/flow_payment.rb +35 -0
  55. data/app/models/workarea/payment/flow_payment_data.rb +25 -0
  56. data/app/models/workarea/payment/flow_payment_operation.rb +20 -0
  57. data/app/models/workarea/payment/purchase/flow_payment.rb +44 -0
  58. data/app/models/workarea/payment/refund/flow_payment.rb +42 -0
  59. data/app/models/workarea/payment/store_flow_credit_card.rb +34 -0
  60. data/app/models/workarea/payment/tender.decorator +8 -0
  61. data/app/models/workarea/payment/tender/flow_payment.rb +15 -0
  62. data/app/models/workarea/payment/transaction.decorator +12 -0
  63. data/app/models/workarea/pricing/calculators/flow_localization_calculator.rb +30 -0
  64. data/app/models/workarea/pricing/calculators/item_calculator.decorator +39 -0
  65. data/app/models/workarea/pricing/collection.decorator +113 -0
  66. data/app/models/workarea/pricing/order_totals.decorator +53 -0
  67. data/app/models/workarea/pricing/price.decorator +17 -0
  68. data/app/models/workarea/pricing/price_distributor.decorator +51 -0
  69. data/app/models/workarea/pricing/request.decorator +17 -0
  70. data/app/models/workarea/pricing/shipping_totals.decorator +24 -0
  71. data/app/models/workarea/pricing/sku.decorator +46 -0
  72. data/app/models/workarea/search/settings.decorator +8 -0
  73. data/app/models/workarea/search/storefront/product.decorator +25 -0
  74. data/app/models/workarea/shipping.decorator +28 -0
  75. data/app/queries/workarea/order_metrics.decorator +23 -0
  76. data/app/queries/workarea/search/product_search.decorator +14 -0
  77. data/app/queries/workarea/search/storefront_search/response.decorator +40 -0
  78. data/app/services/workarea/flow_io/checkout.rb +242 -0
  79. data/app/services/workarea/flow_io/checkout_token_form.rb +36 -0
  80. data/app/services/workarea/flow_io/countries.rb +14 -0
  81. data/app/services/workarea/flow_io/detailed_shipping_notification_form.rb +84 -0
  82. data/app/services/workarea/flow_io/experiences.rb +24 -0
  83. data/app/services/workarea/flow_io/fulfillment_cancellation_form.rb +40 -0
  84. data/app/services/workarea/flow_io/item.rb +122 -0
  85. data/app/services/workarea/flow_io/item_importer.rb +108 -0
  86. data/app/services/workarea/flow_io/line_item_form.rb +72 -0
  87. data/app/services/workarea/flow_io/order_put_form.rb +62 -0
  88. data/app/services/workarea/flow_io/price_applier.rb +81 -0
  89. data/app/services/workarea/flow_io/price_applier/item_applier.rb +157 -0
  90. data/app/services/workarea/flow_io/routing_contraints.rb +10 -0
  91. data/app/services/workarea/flow_io/session.rb +90 -0
  92. data/app/services/workarea/flow_io/webhook.rb +28 -0
  93. data/app/services/workarea/flow_io/webhook/experience_deleted_v2.rb +9 -0
  94. data/app/services/workarea/flow_io/webhook/experience_upserted_v2.rb +9 -0
  95. data/app/services/workarea/flow_io/webhook/order_upserted_v2.rb +36 -0
  96. data/app/services/workarea/flow_io/webhook_request_signature.rb +19 -0
  97. data/app/view_models/workarea/admin/flow_imports_view_model.rb +36 -0
  98. data/app/view_models/workarea/storefront/cart_view_model.decorator +27 -0
  99. data/app/view_models/workarea/storefront/content_blocks/category_summary_view_model.decorator +11 -0
  100. data/app/view_models/workarea/storefront/content_blocks/product_insights_view_model.decorator +11 -0
  101. data/app/view_models/workarea/storefront/content_blocks/product_list_view_model.decorator +13 -0
  102. data/app/view_models/workarea/storefront/order_item_view_model.decorator +35 -0
  103. data/app/view_models/workarea/storefront/order_view_model.decorator +51 -0
  104. data/app/view_models/workarea/storefront/product_templates/option_set_view_model.decorator +20 -0
  105. data/app/view_models/workarea/storefront/product_templates/package_view_model.decorator +14 -0
  106. data/app/view_models/workarea/storefront/product_view_model.decorator +15 -0
  107. data/app/view_models/workarea/storefront/product_view_model/cache_key.decorator +7 -0
  108. data/app/view_models/workarea/storefront/recommendations_view_model.decorator +20 -0
  109. data/app/view_models/workarea/storefront/user_activity_view_model.decorator +18 -0
  110. data/app/views/workarea/admin/catalog_categories/edit.html.haml +85 -0
  111. data/app/views/workarea/admin/facets/_price_inputs.html.haml +50 -0
  112. data/app/views/workarea/admin/flow_imports/index.html.haml +44 -0
  113. data/app/views/workarea/admin/orders/_flow.html.haml +22 -0
  114. data/app/views/workarea/admin/orders/_flow_aux_navigation.html.haml +2 -0
  115. data/app/views/workarea/admin/orders/flow.html.haml +109 -0
  116. data/app/views/workarea/admin/orders/tenders/_flow_payment.html.haml +3 -0
  117. data/app/views/workarea/admin/pricing_skus/_cards.html.haml +83 -0
  118. data/app/views/workarea/admin/pricing_skus/flow.html.haml +60 -0
  119. data/app/views/workarea/admin/search_settings/show.html.haml +55 -0
  120. data/app/views/workarea/admin/shared/_flow_imports_link.html.haml +1 -0
  121. data/app/views/workarea/storefront/_flow_io_country_picker.html.haml +2 -0
  122. data/app/views/workarea/storefront/_flow_io_country_picker_javascript.html.haml +1 -0
  123. data/app/views/workarea/storefront/order_mailer/tenders/_flow_payment.html.haml +2 -0
  124. data/app/views/workarea/storefront/order_mailer/tenders/_flow_payment.text.erb +1 -0
  125. data/app/views/workarea/storefront/orders/tenders/_flow_payment.html.haml +3 -0
  126. data/app/views/workarea/storefront/products/_pricing.html.haml +41 -0
  127. data/app/workers/workarea/flow_io/delete_items.rb +30 -0
  128. data/app/workers/workarea/flow_io/fetch_import.rb +34 -0
  129. data/app/workers/workarea/flow_io/fulfillment_cancellation.rb +14 -0
  130. data/app/workers/workarea/flow_io/item_exporter.rb +47 -0
  131. data/app/workers/workarea/flow_io/process_import.rb +28 -0
  132. data/app/workers/workarea/flow_io/shipping_notifications.rb +13 -0
  133. data/bin/rails +25 -0
  134. data/config/initializers/appends.rb +39 -0
  135. data/config/initializers/freedom_patches.rb +23 -0
  136. data/config/initializers/middleware.rb +11 -0
  137. data/config/initializers/payment_proxy.rb +5 -0
  138. data/config/initializers/rack_attack.rb +15 -0
  139. data/config/initializers/scheduled_jobs.rb +9 -0
  140. data/config/initializers/workarea.rb +101 -0
  141. data/config/initializers/workarea_i18n.rb +11 -0
  142. data/config/locales/en.yml +72 -0
  143. data/config/routes.rb +21 -0
  144. data/lib/active_merchant/billing/bogus_flow_gateway.rb +16 -0
  145. data/lib/active_merchant/billing/flow_gateway.rb +48 -0
  146. data/lib/tasks/flow_io.rake +117 -0
  147. data/lib/workarea/flow_io.rb +73 -0
  148. data/lib/workarea/flow_io/bogus_client.rb +57 -0
  149. data/lib/workarea/flow_io/bogus_client/checkout_tokens.rb +25 -0
  150. data/lib/workarea/flow_io/bogus_client/experiences.rb +152 -0
  151. data/lib/workarea/flow_io/bogus_client/fulfillments.rb +9 -0
  152. data/lib/workarea/flow_io/bogus_client/items.rb +11 -0
  153. data/lib/workarea/flow_io/bogus_client/orders.rb +499 -0
  154. data/lib/workarea/flow_io/bogus_client/organizations.rb +42 -0
  155. data/lib/workarea/flow_io/bogus_client/proxy_client.rb +29 -0
  156. data/lib/workarea/flow_io/bogus_client/sessions.rb +115 -0
  157. data/lib/workarea/flow_io/bogus_client/shipping_notifications.rb +10 -0
  158. data/lib/workarea/flow_io/bogus_client/webhook_settings.rb +11 -0
  159. data/lib/workarea/flow_io/bogus_client/webhooks.rb +11 -0
  160. data/lib/workarea/flow_io/controller_log_subscriber.rb +21 -0
  161. data/lib/workarea/flow_io/engine.rb +8 -0
  162. data/lib/workarea/flow_io/http_handler.rb +27 -0
  163. data/lib/workarea/flow_io/version.rb +5 -0
  164. data/lib/workarea/freedom_patches/flow_io.rb +53 -0
  165. data/package.json +9 -0
  166. data/script/admin_ci +9 -0
  167. data/script/ci +11 -0
  168. data/script/core_ci +9 -0
  169. data/script/plugins_ci +9 -0
  170. data/script/storefront_ci +9 -0
  171. data/test/dummy/.ruby-version +1 -0
  172. data/test/dummy/Rakefile +6 -0
  173. data/test/dummy/bin/bundle +3 -0
  174. data/test/dummy/bin/rails +4 -0
  175. data/test/dummy/bin/rake +4 -0
  176. data/test/dummy/bin/setup +28 -0
  177. data/test/dummy/bin/update +28 -0
  178. data/test/dummy/bin/yarn +11 -0
  179. data/test/dummy/config.ru +5 -0
  180. data/test/dummy/config/application.rb +32 -0
  181. data/test/dummy/config/boot.rb +5 -0
  182. data/test/dummy/config/cable.yml +10 -0
  183. data/test/dummy/config/environment.rb +5 -0
  184. data/test/dummy/config/environments/development.rb +52 -0
  185. data/test/dummy/config/environments/production.rb +88 -0
  186. data/test/dummy/config/environments/test.rb +45 -0
  187. data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
  188. data/test/dummy/config/initializers/assets.rb +14 -0
  189. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  190. data/test/dummy/config/initializers/content_security_policy.rb +25 -0
  191. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  192. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  193. data/test/dummy/config/initializers/inflections.rb +16 -0
  194. data/test/dummy/config/initializers/mime_types.rb +4 -0
  195. data/test/dummy/config/initializers/workarea.rb +5 -0
  196. data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
  197. data/test/dummy/config/locales/en.yml +33 -0
  198. data/test/dummy/config/puma.rb +34 -0
  199. data/test/dummy/config/routes.rb +5 -0
  200. data/test/dummy/config/secrets.yml +22 -0
  201. data/test/dummy/config/spring.rb +6 -0
  202. data/test/dummy/db/seeds.rb +2 -0
  203. data/test/dummy/log/.keep +0 -0
  204. data/test/dummy/package.json +5 -0
  205. data/test/factories/workarea/flow_io.rb +136 -0
  206. data/test/factories/workarea/flow_io/euro_order_upserted_payload.rb +581 -0
  207. data/test/fixtures/files/example.csv +14 -0
  208. data/test/integration/workarea/admin/flow_imports_integration_test.rb +20 -0
  209. data/test/integration/workarea/admin/flow_order_integration_test.rb +37 -0
  210. data/test/integration/workarea/admin/search_settings_integration_test.decorator +44 -0
  211. data/test/integration/workarea/flow_locale_integration_test.rb +34 -0
  212. data/test/integration/workarea/storefront/copying_guest_order_integration_test.decorator +113 -0
  213. data/test/integration/workarea/storefront/flow_io_order_redirect_test.rb +55 -0
  214. data/test/integration/workarea/storefront/flow_io_session_integration_test.rb +122 -0
  215. data/test/integration/workarea/storefront/flow_io_webhooks/order_integration_test.rb +750 -0
  216. data/test/integration/workarea/storefront/flow_webhook_rack_attack_integration_test.rb +54 -0
  217. data/test/integration/workarea/storefront/search_integration_test.decorator +51 -0
  218. data/test/javascripts/flow_spec.js +39 -0
  219. data/test/javascripts/spec_helper.js +3 -0
  220. data/test/models/workarea/address_test.decorator +20 -0
  221. data/test/models/workarea/checkout_test.decorator +20 -0
  222. data/test/models/workarea/flow_io/imported_item_test.rb +50 -0
  223. data/test/models/workarea/fulfillment_test.decorator +12 -0
  224. data/test/models/workarea/oms_fulfillment_test.decorator +14 -0
  225. data/test/models/workarea/order/item_test.decorator +46 -0
  226. data/test/models/workarea/order_test.decorator +16 -0
  227. data/test/models/workarea/payment/flow_payment_integration_test.rb +163 -0
  228. data/test/models/workarea/price_adjustment_set_flow_test.rb +8 -0
  229. data/test/models/workarea/pricing/calculators/flow_localization_calculator_test.rb +152 -0
  230. data/test/models/workarea/pricing/calculators/item_calculator_test.decorator +59 -0
  231. data/test/models/workarea/pricing/collection_test.decorator +140 -0
  232. data/test/models/workarea/pricing/order_totals_test.rb +247 -0
  233. data/test/models/workarea/pricing/price_distributor_test.decorator +21 -0
  234. data/test/models/workarea/pricing/sku_test.decorator +113 -0
  235. data/test/models/workarea/shipping_test.decorator +70 -0
  236. data/test/queries/workarea/flow_order_metrics_test.rb +104 -0
  237. data/test/services/workarea/commit_shipments_test.decorator +14 -0
  238. data/test/services/workarea/flow_io/checkout_test.rb +43 -0
  239. data/test/services/workarea/flow_io/detailed_shipping_notification_form_test.rb +145 -0
  240. data/test/services/workarea/flow_io/experiences_test.rb +14 -0
  241. data/test/services/workarea/flow_io/fulfillment_cancellation_form_test.rb +46 -0
  242. data/test/services/workarea/flow_io/item_importer_test.rb +357 -0
  243. data/test/services/workarea/flow_io/item_test.rb +72 -0
  244. data/test/services/workarea/flow_io/line_item_form_test.rb +34 -0
  245. data/test/services/workarea/flow_io/order_put_form_test.rb +48 -0
  246. data/test/services/workarea/flow_io/price_applier_test.rb +916 -0
  247. data/test/support/flow_fixtures.rb +1362 -0
  248. data/test/support/webhook_integration_test.rb +43 -0
  249. data/test/support/workarea/flow_bogus_client_support.rb +18 -0
  250. data/test/support/workarea/flow_io_vcr_config.rb +22 -0
  251. data/test/system/workarea/admin/search_fulfillment_system_test.decorator +25 -0
  252. data/test/system/workarea/storefront/analytics_system_test.decorator +28 -0
  253. data/test/system/workarea/storefront/flow_cart_recommendations_system_test.rb +70 -0
  254. data/test/system/workarea/storefront/users_flow_orders_system_test.rb +25 -0
  255. data/test/teaspoon_env.rb +6 -0
  256. data/test/test_helper.rb +27 -0
  257. data/test/vcr_cassettes/payment/flow/auth_capture.yml +188 -0
  258. data/test/vcr_cassettes/payment/flow/auth_capture_refund.yml +249 -0
  259. data/test/vcr_cassettes/payment/flow/auth_void.yml +188 -0
  260. data/test/vcr_cassettes/payment/flow/purchase_refund.yml +249 -0
  261. data/test/vcr_cassettes/payment/flow/store_auth.yml +127 -0
  262. data/test/vcr_cassettes/payment/flow/store_purchase.yml +188 -0
  263. data/test/view_models/workarea/storefront/cart_view_model_test.decorator +19 -0
  264. data/test/view_models/workarea/storefront/order_item_view_model_test.decorator +24 -0
  265. data/test/view_models/workarea/storefront/order_view_model_test.decorator +41 -0
  266. data/test/view_models/workarea/storefront/package_view_model_test.decorator +11 -0
  267. data/test/workers/workarea/flow_io/delete_items_test.rb +37 -0
  268. data/test/workers/workarea/flow_io/fetch_import_test.rb +41 -0
  269. data/test/workers/workarea/flow_io/item_exporter_test.rb +47 -0
  270. data/test/workers/workarea/flow_io/process_import_test.rb +25 -0
  271. data/workarea-flow_io.gemspec +20 -0
  272. metadata +375 -0
@@ -0,0 +1,34 @@
1
+ # Puma can serve each request in a thread from an internal thread pool.
2
+ # The `threads` method setting takes two numbers: a minimum and maximum.
3
+ # Any libraries that use thread pools should be configured to match
4
+ # the maximum value specified for Puma. Default is set to 5 threads for minimum
5
+ # and maximum; this matches the default thread size of Active Record.
6
+ #
7
+ threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
8
+ threads threads_count, threads_count
9
+
10
+ # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
11
+ #
12
+ port ENV.fetch("PORT") { 3000 }
13
+
14
+ # Specifies the `environment` that Puma will run in.
15
+ #
16
+ environment ENV.fetch("RAILS_ENV") { "development" }
17
+
18
+ # Specifies the number of `workers` to boot in clustered mode.
19
+ # Workers are forked webserver processes. If using threads and workers together
20
+ # the concurrency of the application would be max `threads` * `workers`.
21
+ # Workers do not work on JRuby or Windows (both of which do not support
22
+ # processes).
23
+ #
24
+ # workers ENV.fetch("WEB_CONCURRENCY") { 2 }
25
+
26
+ # Use the `preload_app!` method when specifying a `workers` number.
27
+ # This directive tells Puma to first boot the application and load code
28
+ # before forking the application. This takes advantage of Copy On Write
29
+ # process behavior so workers use less memory.
30
+ #
31
+ # preload_app!
32
+
33
+ # Allow puma to be restarted by `rails restart` command.
34
+ plugin :tmp_restart
@@ -0,0 +1,5 @@
1
+ Rails.application.routes.draw do
2
+ mount Workarea::Core::Engine => '/'
3
+ mount Workarea::Admin::Engine => '/admin', as: 'admin'
4
+ mount Workarea::Storefront::Engine => '/', as: 'storefront'
5
+ end
@@ -0,0 +1,22 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key is used for verifying the integrity of signed cookies.
4
+ # If you change this key, all old signed cookies will become invalid!
5
+
6
+ # Make sure the secret is at least 30 characters and all random,
7
+ # no regular words or you'll be exposed to dictionary attacks.
8
+ # You can use `rails secret` to generate a secure secret key.
9
+
10
+ # Make sure the secrets in this file are kept private
11
+ # if you're sharing your code publicly.
12
+
13
+ development:
14
+ secret_key_base: 5477b920cb5290af0948b7dcb36a9e56d7e45a016414241603d9f6712a1cfdbded28266776ebed413f169b065c83f1cb95a2946b288b9fd85fcab5e31147498d
15
+
16
+ test:
17
+ secret_key_base: b8f48175807453fb16a5bfabae293ddbdfb35ef89ff153e13bbd8f8f0868c874a2ff8a4b0b4e7c66a9ac922dcd8ca7df53b651042d8916f9e945de733a7908a7
18
+
19
+ # Do not keep production secrets in the repository,
20
+ # instead read values from the environment.
21
+ production:
22
+ secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
@@ -0,0 +1,6 @@
1
+ %w[
2
+ .ruby-version
3
+ .rbenv-vars
4
+ tmp/restart.txt
5
+ tmp/caching-dev.txt
6
+ ].each { |path| Spring.watch(path) }
@@ -0,0 +1,2 @@
1
+ require 'workarea/seeds'
2
+ Workarea::Seeds.run
File without changes
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "dummy",
3
+ "private": true,
4
+ "dependencies": {}
5
+ }
@@ -0,0 +1,136 @@
1
+ module Workarea
2
+ module Factories
3
+ module FlowIo
4
+ Factories.add self
5
+
6
+ def build_flow_io_experience_summary(overrides = {})
7
+ attributes = {
8
+ _id: "exp-31b66afd8ac44a71a0669b2ad81a794d",
9
+ key: "canada",
10
+ name: "Canada",
11
+ country: "CA",
12
+ currency: "CAD",
13
+ language: "en"
14
+ }.merge(overrides)
15
+
16
+ Workarea::FlowIo::ExperienceSummary.new(attributes)
17
+ end
18
+
19
+ def build_flow_io_experience_geo(overrides = {})
20
+ attributes = {
21
+ key: "canada",
22
+ name: "Canada",
23
+ region: { id: "can" },
24
+ country: "CAN",
25
+ currency: "CAD",
26
+ language: "en",
27
+ measurement_system: "metric"
28
+ }.merge(overrides)
29
+
30
+ Workarea::FlowIo::ExperienceGeo.new(attributes)
31
+ end
32
+
33
+ def create_pricing_sku_with_flow(overrides = {})
34
+ attributes = {
35
+ id: "004056270-0",
36
+ msrp: { cents: 9241.0, currency_iso: "USD" },
37
+ tax_code: "001",
38
+ on_sale: false,
39
+ prices: [
40
+ {
41
+ min_quantity: 1,
42
+ regular: { cents: 8241.0, currency_iso: "USD" },
43
+ sale: { cents: 8141.0, currency_iso: "USD" }
44
+ }
45
+ ],
46
+ flow_io_local_items: overrides[:flow_io_local_items] || [build_flow_io_local_item]
47
+ }.merge(overrides)
48
+
49
+ Workarea::Pricing::Sku.new(attributes).tap(&:save!)
50
+ end
51
+
52
+ def build_flow_io_local_item(regular: 120.to_m("CAD"), sale: 110.to_m("CAD"), **overrides)
53
+ price = { regular: { price: regular, label: regular.format } }.tap do |p|
54
+ if sale.present?
55
+ p[:sale] = { price: sale, label: sale.format }
56
+ end
57
+ end
58
+
59
+ attributes = {
60
+ id: "mit-86beca991a514dac9a5fd48443f00b6b",
61
+ experience: build_flow_io_experience_summary,
62
+ msrp: { price: 140.to_m("CAD"), label: "CA$140.00" },
63
+ prices: [price]
64
+ }.merge(overrides)
65
+
66
+ Workarea::FlowIo::LocalItem.new(attributes)
67
+ end
68
+
69
+ def create_shipping_service(overrides = {})
70
+ attributes = {
71
+ name: "Test #{shipping_service_count}",
72
+ service_code: shipping_service_count,
73
+ rates: [{ price: 1.to_m }]
74
+ }.merge(overrides)
75
+
76
+ Shipping::Service.new(attributes.except(:rates)).tap do |service|
77
+ if attributes[:rates].present?
78
+ attributes[:rates].each do |attrs|
79
+ service.rates.build(attrs)
80
+ end
81
+ end
82
+
83
+ service.save!
84
+ Factories.shipping_service_count += 1
85
+ end
86
+ end
87
+
88
+ # @param order [Workarea::Order]
89
+ #
90
+ def euro_order_placed_payload(order:)
91
+ EuroOrderUpsertedPayload.new(order: order).to_json
92
+ end
93
+
94
+ # Creates cart
95
+ #
96
+ # @param order [Workarea::Order] order to use as base
97
+ # @param items [Array<Hash>] array of hashes with keys
98
+ # * product - Catalog::Product
99
+ # * sku - String
100
+ # * quantity - Integer
101
+ # @param user [Workarea::User] optional user for order
102
+ #
103
+ def create_cart(order: nil, items: nil, user: nil)
104
+ order ||= create_order(
105
+ email: user&.email,
106
+ checkout_started_at: Time.current,
107
+ user_id: user&.id&.to_s
108
+ )
109
+ items = items ||
110
+ begin
111
+ product = create_product
112
+ [
113
+ {
114
+ product: product,
115
+ sku: product.skus.first,
116
+ quantity: 2
117
+ }
118
+ ]
119
+ end
120
+
121
+ items.each do |item|
122
+ item_details = OrderItemDetails
123
+ .find!(item[:sku])
124
+ .to_h
125
+ .merge(product_id: item[:product].id, sku: item[:sku], quantity: item[:quantity])
126
+
127
+ order.add_item(item_details)
128
+ end
129
+
130
+ Workarea::Pricing.perform(order)
131
+
132
+ order.tap(&:save!)
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,581 @@
1
+ module Workarea
2
+ module Factories
3
+ module FlowIo
4
+ class EuroOrderUpsertedPayload
5
+ attr_reader :order
6
+
7
+ def initialize(order:, shipping: nil, payment: nil)
8
+ @order = order
9
+ end
10
+
11
+ def to_json
12
+ {
13
+ "event_id" => "evt-37ba2577b4e54d55b8847891a1ec3a1f",
14
+ "timestamp" => "2018-08-09T17:16:54.542Z",
15
+ "organization" => "workarea-sandbox",
16
+ "order" => {
17
+ "id" => "ord-7d170417473c43c99d7ea88f938bfebb",
18
+ "number" => "ord-7d170417473c43c99d7ea88f938bfebb",
19
+ "customer" => customer,
20
+ "delivered_duty" => "paid",
21
+ "destination" => destination,
22
+ "expires_at" => "2018-08-09T18:16:53.063Z",
23
+ "items" => localized_line_items,
24
+ "deliveries" => [
25
+ {
26
+ "id" => "del-2270eea7d85b4ee386137cf8018a37a2",
27
+ "items" => delivery_items,
28
+ "options" => [
29
+ {
30
+ "id" => "opt-447ba414cf9448ca995464e88241fb8f",
31
+ "cost" => {
32
+ "currency" => "EUR",
33
+ "amount" => 9.29,
34
+ "label" => "CA$9.29",
35
+ "base" => {
36
+ "amount" => 6.86,
37
+ "currency" => "USD",
38
+ "label" => "US$6.86"
39
+ }
40
+ },
41
+ "delivered_duty" => "unpaid",
42
+ "price" => {
43
+ "currency" => "EUR",
44
+ "amount" => 9.29,
45
+ "label" => "CA$9.29",
46
+ "base" => {
47
+ "amount" => 6.86,
48
+ "currency" => "USD",
49
+ "label" => "US$6.86"
50
+ }
51
+ },
52
+ "service" => {
53
+ "id" => "landmark-global",
54
+ "carrier" => {
55
+ "id" => "landmark"
56
+ },
57
+ "name" => "Global"
58
+ },
59
+ "tier" => {
60
+ "id" => "tie-fc0ec702c4384dc8805ae645ef6156e8",
61
+ "experience" => { "id" => "europe", "currency" => "EUR" },
62
+ "integration" => "information",
63
+ "name" => "Standard Shipping",
64
+ "services" => [
65
+ "landmark-global",
66
+ "dhl-express-worldwide"
67
+ ],
68
+ "strategy" => "lowest_cost",
69
+ "visibility" => "public",
70
+ "currency" => "EUR",
71
+ "display" => {
72
+ "estimate" => {
73
+ "type" => "calculated",
74
+ "label" => "2-5 Business Days"
75
+ }
76
+ }
77
+ },
78
+ "window" => {
79
+ "from" => "2018-08-13T00:00:00.000Z",
80
+ "to" => "2018-08-16T00:00:00.000Z",
81
+ "timezone" => "America/Toronto",
82
+ "label" => "2-5 Business Days"
83
+ },
84
+ "cost_details" => [
85
+ {
86
+ "source" => "ratecard",
87
+ "currency" => "EUR",
88
+ "amount" => 9.29,
89
+ "label" => "CA$9.29",
90
+ "components" => [
91
+ {
92
+ "key" => "ratecard_base_cost",
93
+ "currency" => "EUR",
94
+ "amount" => 9.29,
95
+ "label" => "CA$9.29",
96
+ "base" => {
97
+ "amount" => 6.86,
98
+ "currency" => "USD",
99
+ "label" => "US$6.86"
100
+ }
101
+ }
102
+ ],
103
+ "base" => {
104
+ "amount" => 6.86,
105
+ "currency" => "USD",
106
+ "label" => "US$6.86"
107
+ }
108
+ }
109
+ ],
110
+ "rule_outcome" => {
111
+ "discriminator" => "at_cost"
112
+ },
113
+ "weight" => {
114
+ "gravitational" => {
115
+ "value" => "2.5",
116
+ "units" => "pound"
117
+ },
118
+ "dimensional" => {
119
+ "value" => "2.12",
120
+ "units" => "inch"
121
+ }
122
+ }
123
+ },
124
+ {
125
+ "id" => "opt-806563c2f4b448e8a4d36bb037de0a21",
126
+ "cost" => {
127
+ "currency" => "EUR",
128
+ "amount" => 9.29,
129
+ "label" => "CA$9.29",
130
+ "base" => {
131
+ "amount" => 6.86,
132
+ "currency" => "USD",
133
+ "label" => "US$6.86"
134
+ }
135
+ },
136
+ "delivered_duty" => "paid",
137
+ "price" => {
138
+ "currency" => "EUR",
139
+ "amount" => 9.29,
140
+ "label" => "CA$9.29",
141
+ "base" => {
142
+ "amount" => 6.86,
143
+ "currency" => "USD",
144
+ "label" => "US$6.86"
145
+ }
146
+ },
147
+ "service" => {
148
+ "id" => "landmark-global",
149
+ "carrier" => {
150
+ "id" => "landmark"
151
+ },
152
+ "name" => "Global"
153
+ },
154
+ "tier" => {
155
+ "id" => "tie-fc0ec702c4384dc8805ae645ef6156e8",
156
+ "experience" => { "id" => "europe", "currency" => "EUR" },
157
+ "integration" => "information",
158
+ "name" => "Standard Shipping",
159
+ "services" => [
160
+ "landmark-global",
161
+ "dhl-express-worldwide"
162
+ ],
163
+ "strategy" => "lowest_cost",
164
+ "visibility" => "public",
165
+ "currency" => "EUR",
166
+ "display" => {
167
+ "estimate" => {
168
+ "type" => "calculated",
169
+ "label" => "2-5 Business Days"
170
+ }
171
+ }
172
+ },
173
+ "window" => {
174
+ "from" => "2018-08-13T00:00:00.000Z",
175
+ "to" => "2018-08-16T00:00:00.000Z",
176
+ "timezone" => "America/Toronto",
177
+ "label" => "2-5 Business Days"
178
+ },
179
+ "cost_details" => [
180
+ {
181
+ "source" => "ratecard",
182
+ "currency" => "EUR",
183
+ "amount" => 9.29,
184
+ "label" => "CA$9.29",
185
+ "components" => [
186
+ {
187
+ "key" => "ratecard_base_cost",
188
+ "currency" => "EUR",
189
+ "amount" => 9.29,
190
+ "label" => "CA$9.29",
191
+ "base" => {
192
+ "amount" => 6.86,
193
+ "currency" => "USD",
194
+ "label" => "US$6.86"
195
+ }
196
+ }
197
+ ],
198
+ "base" => {
199
+ "amount" => 6.86,
200
+ "currency" => "USD",
201
+ "label" => "US$6.86"
202
+ }
203
+ }
204
+ ],
205
+ "rule_outcome" => {
206
+ "discriminator" => "at_cost"
207
+ },
208
+ "weight" => {
209
+ "gravitational" => {
210
+ "value" => "2.5",
211
+ "units" => "pound"
212
+ },
213
+ "dimensional" => {
214
+ "value" => "2.12",
215
+ "units" => "inch"
216
+ }
217
+ }
218
+ }
219
+ ],
220
+ "center" => {
221
+ "id" => "cen-394b1db3c61a495c964dd1fe60969160",
222
+ "key" => "center-workarea"
223
+ },
224
+ "discriminator" => "physical_delivery"
225
+ }
226
+ ],
227
+ "selections" => [
228
+ "opt-806563c2f4b448e8a4d36bb037de0a21"
229
+ ],
230
+ "prices" => prices,
231
+ "total" => {
232
+ "currency" => "EUR",
233
+ "amount" => 232.31,
234
+ "label" => "CA$232.31",
235
+ "base" => {
236
+ "amount" => 171.55,
237
+ "currency" => "USD",
238
+ "label" => "US$171.55"
239
+ }
240
+ },
241
+ "attributes" => { "number" => "#{order.id}" },
242
+ "merchant_of_record" => "flow",
243
+ "experience" => { "key" => "europe", "discriminator" => "experience_reference" },
244
+ "submitted_at" => "2018-08-09T17:16:54.534Z",
245
+ "lines" => lines,
246
+ "promotions" => {
247
+ "applied" => [],
248
+ "available" => []
249
+ },
250
+ "payments" => [
251
+ {
252
+ "id" => "opm-009ef64e13b84baa805d07570072895b",
253
+ "type" => "card",
254
+ "merchant_of_record" => "flow",
255
+ "reference" => "aut-kYDowZbpSrUEqggeDWW9D0phXQrpDybj",
256
+ "description" => "VISA ending with 1111",
257
+ "total" => {
258
+ "currency" => "EUR",
259
+ "amount" => 232.31,
260
+ "label" => "CA$232.31",
261
+ "base" => {
262
+ "amount" => 171.55,
263
+ "currency" => "USD",
264
+ "label" => "US$171.55"
265
+ }
266
+ },
267
+ "attributes" => {},
268
+ "address" => billing_address,
269
+ "date" => "2018-08-09T17:16:54.061Z"
270
+ }
271
+ ],
272
+ "balance" => {
273
+ "currency" => "EUR",
274
+ "amount" => 0,
275
+ "label" => "CA$0.00",
276
+ "base" => {
277
+ "amount" => 0,
278
+ "currency" => "USD",
279
+ "label" => "US$0.00"
280
+ }
281
+ }
282
+ },
283
+ "discriminator" => "order_upserted_v2"
284
+ }.to_json
285
+ end
286
+
287
+ private
288
+
289
+ # Fake price conversions
290
+ #
291
+ # @param money [Money] the amount to convert
292
+ # @param rate [Float] conversion rate between currencies
293
+ # @param currency_code [String] currency to convert into
294
+ #
295
+ def convert_price(money, rate: 1.2, currency_code: "EUR")
296
+ return unless money.present?
297
+
298
+ fractional = (money.dup * rate).fractional
299
+ remainder = fractional % 500
300
+
301
+ Money.from_amount((fractional + 500 - remainder) / 100, currency_code)
302
+ end
303
+
304
+ def customer_name
305
+ { "first" => "Worarea", "last" => "Customer" }
306
+ end
307
+
308
+ def billing_address
309
+ {
310
+ "name" => customer_name,
311
+ "streets" => ["35 Letitia Ln"],
312
+ "city" => "Media",
313
+ "province" => "Alberta",
314
+ "postal" => "19063",
315
+ "country" => "CAN",
316
+ "company" => "Weblinc"
317
+ }
318
+ end
319
+
320
+ def customer
321
+ {
322
+ "name" => customer_name,
323
+ "phone" => "3027507743",
324
+ "email" => "flow-test@weblinc.com",
325
+ "address" => billing_address
326
+ }
327
+ end
328
+
329
+ def destination
330
+ {
331
+ "streets" => ["35 Letitia Ln"],
332
+ "city" => "Media",
333
+ "province" => "Alberta",
334
+ "postal" => "19063",
335
+ "country" => "CAN",
336
+ "contact" => {
337
+ "name" => customer_name,
338
+ "company" => "Weblinc",
339
+ "email" => "jyucis-relate-new@weblinc.com",
340
+ "phone" => "3027507743"
341
+ }
342
+ }
343
+ end
344
+
345
+ def experience_key
346
+ "europe"
347
+ end
348
+
349
+ def experience_name
350
+ "Europe"
351
+ end
352
+
353
+ def localized_line_items
354
+ order.items.map do |order_item|
355
+ catalog_product =
356
+ if order_item.product_attributes.present?
357
+ Mongoid::Factory.from_db(Workarea::Catalog::Product, order_item.product_attributes)
358
+ else
359
+ Workarea::Catalog::Product.find_by_sku(order_item.sku)
360
+ end
361
+
362
+ converted_price = convert_price order_item.total_price
363
+ {
364
+ "number" => order_item.sku,
365
+ "name" => catalog_product.name,
366
+ "quantity" => order_item.quantity,
367
+ "local" => {
368
+ "experience" => {
369
+ "id" => "exp-95889ba1ff4b449f8a3c0e0a7a4fb23b",
370
+ "key" => experience_key,
371
+ "name" => experience_name
372
+ },
373
+ "prices" => [
374
+ {
375
+ "currency" => "EUR",
376
+ "amount" => converted_price.to_f,
377
+ "label" => "EUR€#{converted_price}",
378
+ "base" => {
379
+ "amount" => order_item.total_price.to_f,
380
+ "currency" => "USD",
381
+ "label" => "US$#{order_item.total_price.to_f}"
382
+ },
383
+ "key" => "localized_item_price"
384
+ }
385
+ ],
386
+ "rates" => [],
387
+ "spot_rates" => [],
388
+ "status" => "included"
389
+ }
390
+ }
391
+ end
392
+ end
393
+
394
+ def delivery_items
395
+ order.items.map do |order_item|
396
+
397
+ converted_price = convert_price order_item.total_price
398
+ {
399
+ "number" => order_item.sku,
400
+ "quantity" => order_item.quantity,
401
+ "price" => {
402
+ "currency" => "EUR",
403
+ "amount" => converted_price.to_f,
404
+ "base" => {
405
+ "amount" => order_item.total_price.to_f,
406
+ "currency" => "USD"
407
+ }
408
+ }
409
+ }
410
+ end
411
+ end
412
+
413
+ def lines
414
+ order.items.map do |order_item|
415
+
416
+ converted_price = convert_price order_item.total_price
417
+ {
418
+ "item_number" => order_item.sku,
419
+ "quantity" => order_item.quantity,
420
+ "price" => {
421
+ "currency" => "EUR",
422
+ "amount" => converted_price.to_f,
423
+ "label" => "EUR€#{converted_price}",
424
+ "base" => {
425
+ "amount" => order_item.total_price.to_f,
426
+ "currency" => "USD",
427
+ "label" => "US$#{order_item.total_price.to_f}"
428
+ }
429
+ },
430
+ "total" => {
431
+ "currency" => "EUR",
432
+ "amount" => converted_price.to_f,
433
+ "label" => "EUR€#{converted_price}",
434
+ "base" => {
435
+ "amount" => order_item.total_price.to_f,
436
+ "currency" => "USD",
437
+ "label" => "US$#{order_item.total_price.to_f}"
438
+ }
439
+ }
440
+ }
441
+ end
442
+ end
443
+
444
+ # TODO better prices for items
445
+ #
446
+ def prices
447
+ [
448
+ {
449
+ "key" => "subtotal",
450
+ "currency" => "EUR",
451
+ "amount" => 180,
452
+ "label" => "CA$180.00",
453
+ "base" => {
454
+ "amount" => 132.91,
455
+ "currency" => "USD",
456
+ "label" => "US$132.91"
457
+ },
458
+ "components" => [
459
+ {
460
+ "key" => "item_price",
461
+ "currency" => "EUR",
462
+ "amount" => 165.94,
463
+ "label" => "CA$165.94",
464
+ "base" => {
465
+ "amount" => 122.53,
466
+ "currency" => "USD",
467
+ "label" => "US$122.53"
468
+ },
469
+ "name" => "Item price"
470
+ },
471
+ {
472
+ "key" => "rounding",
473
+ "currency" => "EUR",
474
+ "amount" => 14.06,
475
+ "label" => "CA$14.06",
476
+ "base" => {
477
+ "amount" => 10.38,
478
+ "currency" => "USD",
479
+ "label" => "US$10.38"
480
+ },
481
+ "name" => "Rounding"
482
+ }
483
+ ],
484
+ "name" => "Item subtotal"
485
+ },
486
+ {
487
+ "key" => "vat",
488
+ "currency" => "EUR",
489
+ "amount" => 10.62,
490
+ "label" => "CA$10.62",
491
+ "base" => {
492
+ "amount" => 7.85,
493
+ "currency" => "USD",
494
+ "label" => "US$7.85"
495
+ },
496
+ "components" => [
497
+ {
498
+ "key" => "vat_item_price",
499
+ "currency" => "EUR",
500
+ "amount" => 9,
501
+ "label" => "CA$9.00",
502
+ "base" => {
503
+ "amount" => 6.65,
504
+ "currency" => "USD",
505
+ "label" => "US$6.65"
506
+ },
507
+ "name" => "GST on item price"
508
+ },
509
+ {
510
+ "key" => "vat_duties_item_price",
511
+ "currency" => "EUR",
512
+ "amount" => 1.62,
513
+ "label" => "CA$1.62",
514
+ "base" => {
515
+ "amount" => 1.2,
516
+ "currency" => "USD",
517
+ "label" => "US$1.20"
518
+ },
519
+ "name" => "GST on duties on item price"
520
+ }
521
+ ],
522
+ "name" => "GST"
523
+ },
524
+ {
525
+ "key" => "duty",
526
+ "currency" => "EUR",
527
+ "amount" => 32.4,
528
+ "label" => "CA$32.40",
529
+ "base" => {
530
+ "amount" => 23.93,
531
+ "currency" => "USD",
532
+ "label" => "US$23.93"
533
+ },
534
+ "components" => [
535
+ {
536
+ "key" => "duties_item_price",
537
+ "currency" => "EUR",
538
+ "amount" => 32.4,
539
+ "label" => "CA$32.40",
540
+ "base" => {
541
+ "amount" => 23.93,
542
+ "currency" => "USD",
543
+ "label" => "US$23.93"
544
+ },
545
+ "name" => "Duties on item price"
546
+ }
547
+ ],
548
+ "name" => "Duties"
549
+ },
550
+ {
551
+ "key" => "shipping",
552
+ "currency" => "EUR",
553
+ "amount" => 9.29,
554
+ "label" => "CA$9.29",
555
+ "base" => {
556
+ "amount" => 6.86,
557
+ "currency" => "USD",
558
+ "label" => "US$6.86"
559
+ },
560
+ "components" => [
561
+ {
562
+ "key" => "shipping",
563
+ "currency" => "EUR",
564
+ "amount" => 9.29,
565
+ "label" => "CA$9.29",
566
+ "base" => {
567
+ "amount" => 6.86,
568
+ "currency" => "USD",
569
+ "label" => "US$6.86"
570
+ },
571
+ "name" => "Shipping"
572
+ }
573
+ ],
574
+ "name" => "Shipping"
575
+ }
576
+ ]
577
+ end
578
+ end
579
+ end
580
+ end
581
+ end