workarea-flow_io 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 (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,36 @@
1
+ module Workarea
2
+ module FlowIo
3
+ class Webhook::OrderUpsertedV2 < Webhook
4
+ def process
5
+ return unless flow_order.submitted_at.present?
6
+
7
+ order_id = flow_order.attributes["number"]
8
+
9
+ workarea_order = Order.find(order_id)
10
+ workarea_order.lock!
11
+
12
+ workarea_order.flow = true
13
+ workarea_order.save!
14
+
15
+ # Service class to build a valid workarea checkout
16
+ checkout = Workarea::FlowIo::Checkout.new(flow_order, workarea_order)
17
+
18
+ # builds the orders shipping and payment details
19
+ checkout.build
20
+
21
+ unless checkout.place_order
22
+ raise Webhook::Error, "failed to place order #{order_id}"
23
+ end
24
+
25
+ ensure
26
+ workarea_order&.unlock!
27
+ end
28
+
29
+ private
30
+
31
+ def flow_order
32
+ event.order
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ module Workarea
2
+ module FlowIo
3
+ module WebhookRequestSignature
4
+ # @param[String] request_signature
5
+ # @param[String] request_body
6
+ #
7
+ # @return Boolean
8
+ def self.valid?(request_signature:, request_body:)
9
+ return false unless request_signature.present? && request_body.present?
10
+
11
+ digest = OpenSSL::Digest.new('sha256')
12
+
13
+ expected_signature = 'sha256=' + OpenSSL::HMAC.hexdigest(digest, Workarea::FlowIo.webhook_shared_secret, request_body)
14
+
15
+ Rack::Utils.secure_compare request_signature, expected_signature
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,36 @@
1
+ module Workarea
2
+ module Admin
3
+ class FlowImportsViewModel < ApplicationViewModel
4
+ def results
5
+ @results ||= PagedArray.from(
6
+ models,
7
+ page,
8
+ per_page,
9
+ models.total_count
10
+ )
11
+ end
12
+
13
+ def models
14
+ @models ||= FlowIo::Import
15
+ .all
16
+ .page(page)
17
+ .per(per_page)
18
+ .order(created_at: :desc)
19
+ end
20
+
21
+ def ttl
22
+ Workarea.config.data_file_operation_ttl
23
+ end
24
+
25
+ private
26
+
27
+ def per_page
28
+ Workarea.config.per_page
29
+ end
30
+
31
+ def page
32
+ options[:page] || 1
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ module Workarea
2
+ decorate Storefront::CartViewModel, with: :flow_io do
3
+ def subtotal_price
4
+ return super unless model.experience.present?
5
+
6
+ model.flow_subtotal_price
7
+ end
8
+
9
+ def total_price
10
+ return super unless model.experience.present?
11
+
12
+ model.flow_total_price
13
+ end
14
+
15
+ def total_adjustments
16
+ return super unless model.experience.present?
17
+
18
+ @total_adjustments ||= flow_price_adjustments.reduce_by_description('order')
19
+ end
20
+
21
+ # TODO base bug, product isn't passing options into product view models
22
+ def recommendations
23
+ return [] unless model.quantity > 0
24
+ @recommendations ||= Storefront::CartRecommendationsViewModel.new(model, options)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ module Workarea
2
+ decorate Storefront::ContentBlocks::CategorySummaryViewModel, with: :flow_io do
3
+ # TODO base bug, product isn't passing options into product view models
4
+ def products
5
+ return [] unless category.present?
6
+ @products ||= search.results.take(product_count).map do |result|
7
+ Storefront::ProductViewModel.wrap(result[:model], options)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Workarea
2
+ decorate Storefront::ContentBlocks::ProductInsightsViewModel, with: :flow_io do
3
+ # TODO base bug options ins't being passed into the view model
4
+ def products
5
+ @products ||= Storefront::ProductViewModel.wrap(
6
+ add_fallbacks(find_insight_products(data[:type])),
7
+ options
8
+ )
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Workarea
2
+ decorate Storefront::ContentBlocks::ProductListViewModel, with: :flow_io do
3
+ # TODO base bug, product isn't passing options into product view models
4
+ def products
5
+ return [] unless data['products'].present?
6
+
7
+ @products ||=
8
+ Catalog::Product
9
+ .find_ordered_for_display(data['products'])
10
+ .map { |product| Storefront::ProductViewModel.wrap(product, options) }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module Workarea
2
+ decorate Storefront::OrderItemViewModel, with: :flow_io do
3
+ def original_unit_price
4
+ return super unless order.experience.present?
5
+
6
+ return 0.to_m(order.currency) if flow_price_adjustments.blank?
7
+ flow_price_adjustments.first.unit.to_m
8
+ end
9
+
10
+ def total_price
11
+ return super unless order.experience.present?
12
+
13
+ model.flow_total_price
14
+ end
15
+
16
+ def flow_price_adjustments
17
+ @flow_price_adjustments ||= FlowPriceAdjustmentSet.new(
18
+ model.flow_price_adjustments,
19
+ order.experience
20
+ )
21
+ end
22
+
23
+ def total_adjustments
24
+ return super unless order.experience.present?
25
+
26
+ @total_adjustments ||= flow_price_adjustments.reduce_by_description('item')
27
+ end
28
+
29
+ def original_price
30
+ return super unless order.experience.present?
31
+
32
+ flow_price_adjustments.first.data['original_price'].to_m(order.currency)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,51 @@
1
+ module Workarea
2
+ decorate Storefront::OrderViewModel, with: :flow_io do
3
+ def subtotal_price
4
+ return super unless model.experience.present?
5
+
6
+ model.flow_subtotal_price
7
+ end
8
+
9
+ def total_price
10
+ return super unless model.experience.present?
11
+
12
+ model.flow_total_price
13
+ end
14
+
15
+ def shipping_total
16
+ return super unless model.experience.present?
17
+
18
+ model.flow_shipping_total
19
+ end
20
+
21
+ def tax_total
22
+ return super unless model.experience.present?
23
+
24
+ model.flow_tax_total
25
+ end
26
+
27
+ def total_adjustments
28
+ return super unless model.experience.present?
29
+
30
+ @total_adjustments ||= flow_price_adjustments.reduce_by_description('order')
31
+ end
32
+
33
+ def store_credit_amount
34
+ if store_credit.present?
35
+ store_credit.amount
36
+ else
37
+ 0.to_m(order.currency)
38
+ end
39
+ end
40
+
41
+ if Plugin.installed?(:gift_cards)
42
+ def gift_card_tender_amount
43
+ if gift_card?
44
+ gift_card_tender.amount
45
+ else
46
+ 0.to_m(order.currency)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,20 @@
1
+ module Workarea
2
+ targets = [
3
+ Storefront::ProductTemplates::OptionThumbnailsViewModel,
4
+ Storefront::ProductTemplates::OptionSelectsViewModel
5
+ ]
6
+
7
+ if Plugin.installed?("Workarea::Swatches")
8
+ targets << Storefront::ProductTemplates::SwatchesViewModel
9
+ end
10
+
11
+ decorate(*targets, with: :flow_io) do
12
+ def pricing
13
+ super.tap do |pricing_collection|
14
+ if options[:flow_experience]
15
+ pricing_collection.flow_experience = options[:flow_experience]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ module Workarea
2
+ if Plugin.installed?("Workarea::PackageProducts")
3
+ decorate Storefront::ProductTemplates::PackageViewModel, with: :flow_io do
4
+ private
5
+ def pricing
6
+ super.tap do |pricing_collection|
7
+ if options[:flow_experience]
8
+ pricing_collection.flow_experience = options[:flow_experience]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ module Workarea
2
+ decorate Storefront::ProductViewModel, with: :flow_io do
3
+ def flow_item_number
4
+ current_sku || id
5
+ end
6
+
7
+ def pricing
8
+ super.tap do |pricing_collection|
9
+ if options[:flow_experience]
10
+ pricing_collection.flow_experience = options[:flow_experience]
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Workarea
2
+ decorate Storefront::ProductViewModel::CacheKey, with: :flow_io do
3
+ def option_parts
4
+ super + [@options[:flow_experience]&.key]
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ module Workarea
2
+ decorate Storefront::RecommendationsViewModel, with: :flow_io do
3
+ # TODO base bug, product isn't passing options into product view models
4
+ def products
5
+ @products ||=
6
+ begin
7
+ results = Catalog::Product.active.purchasable.find_ordered(product_ids)
8
+
9
+ if results.size < result_count
10
+ results.push(
11
+ *Catalog::Product.active.purchasable.find_ordered(popular_product_ids)
12
+ )
13
+ end
14
+
15
+ Storefront::ProductViewModel.wrap(results.uniq, options.except(:sku)).take(result_count)
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ module Workarea
2
+ decorate Storefront::UserActivityViewModel, with: :flow_io do
3
+ # TODO base bug, product isn't passing options into product view models
4
+ def products
5
+ @products ||=
6
+ begin
7
+ product_ids = model.product_ids.uniq.first(display_count)
8
+ models = Catalog::Product.any_in(_id: product_ids).to_a
9
+ models = models.select(&:active?)
10
+
11
+ product_ids.map do |id|
12
+ product = models.detect { |p| p.id == id }
13
+ Storefront::ProductViewModel.wrap(product, options) if product
14
+ end.compact
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,85 @@
1
+ - @page_title = t('workarea.admin.catalog_categories.edit.page_title', category: @category.name)
2
+
3
+ .view
4
+ .view__header
5
+ .grid
6
+ .grid__cell.grid__cell--25
7
+ = render 'workarea/admin/releases/select'
8
+ .grid__cell.grid__cell--50
9
+ .view__heading
10
+ = link_to_index_for(@category)
11
+ %h1= link_to @category.name, url_for(@category)
12
+ .grid__cell.grid__cell--25
13
+ = render_aux_navigation_for(@category)
14
+
15
+ .view__container
16
+ = render_cards_for(@category, :attributes)
17
+
18
+ .view__container.view__container--narrow
19
+ - if @category.errors.present?
20
+ - @category.errors.full_messages.each do |message|
21
+ = render_message 'error', message
22
+
23
+ = form_tag catalog_category_path(@category), method: :patch, id: 'category_form', data: { unsaved_changes: '' } do
24
+
25
+ .section
26
+
27
+ .property.property--required
28
+ = label_tag 'category_name', t('workarea.admin.fields.name'), class: 'property__name'
29
+ = text_field_tag 'category[name]', @category.name, class: 'text-box text-box--i18n', required: true
30
+
31
+ .property
32
+ %span.property__name
33
+ = t('workarea.admin.fields.active')
34
+ = inline_svg('workarea/admin/i18n.svg', class: 'svg-icon svg-icon--small') if locale_options.many? && Workarea.config.localized_active_fields
35
+ = toggle_button_for 'category[active]', @category.active?
36
+
37
+ .property
38
+ = label_tag 'category[slug]', nil, class: 'property__name' do
39
+ %span.property__text= t('workarea.admin.fields.slug')
40
+ %span= storefront.category_url('')
41
+ = text_field_tag 'category[slug]', @category.slug, class: 'text-box text-box--medium', placeholder: @category.slug || t('workarea.admin.catalog_categories.edit.slug_placeholder')
42
+
43
+ .property
44
+ = label_tag 'category_tag_list', t('workarea.admin.fields.tags'), class: 'property__name'
45
+ = text_field_tag 'category[tag_list]', @category.tag_list, class: 'text-box'
46
+ %span.property__note= t('workarea.admin.catalog_categories.edit.tags_note')
47
+
48
+ .property
49
+ = label_tag 'category[client_id]', t('workarea.admin.fields.client_id'), class: 'property__name'
50
+ = text_field_tag 'category[client_id]', @category.client_id, class: 'text-box'
51
+ %span.property__note= t('workarea.admin.catalog_categories.edit.client_id_note')
52
+
53
+ .grid
54
+ .grid__cell.grid__cell--50
55
+ .property
56
+ %span.property__name= t('workarea.admin.fields.show_navigation')
57
+ = toggle_button_for 'category[show_navigation]', @category.show_navigation?, title_true: t('workarea.admin.catalog_categories.edit.show_navigation_true'), title_false: t('workarea.admin.catalog_categories.edit.show_navigation_false')
58
+
59
+ .grid__cell.grid__cell--50
60
+ .property
61
+ = label_tag 'category_default_sort', t('workarea.admin.fields.default_sort'), class: 'property__name'
62
+ = select_tag 'category[default_sort]', options_for_select(@category.sort_options, selected: @category.default_sort)
63
+
64
+ .property
65
+ = label_tag 'category_terms_facets_list', t('workarea.admin.fields.terms_facets_list'), class: 'property__name'
66
+ = text_field_tag 'category[terms_facets_list]', @category.terms_facets_list, class: 'text-box'
67
+ %span.property__note
68
+ = t('workarea.admin.catalog_categories.edit.filters_note_html', search_settings_link: link_to(t('workarea.admin.catalog_categories.edit.search_settings'), search_settings_path(anchor: 'filters-tab-panel')))
69
+
70
+ = render 'workarea/admin/facets/price_inputs', facet: @category.price_facet, currency_localized_facets: @category.currency_localized_facets
71
+
72
+ .grid.grid--huge
73
+ .grid__cell.grid__cell--50.grid__cell--25-at-medium
74
+ .property
75
+ = label_tag 'category_updated_at', t('workarea.admin.fields.updated_at'), class: 'property__name'
76
+ = local_time(@category.updated_at)
77
+ .grid__cell.grid__cell--50.grid__cell--25-at-medium
78
+ .property
79
+ = label_tag 'category_created_at', t('workarea.admin.fields.created_at'), class: 'property__name'
80
+ = local_time(@category.created_at)
81
+
82
+ .workflow-bar
83
+ .grid.grid--auto.grid--right.grid--middle
84
+ .grid__cell= render 'workarea/admin/shared/publishing_select'
85
+ .grid__cell= button_tag t('workarea.admin.form.save_changes'), value: 'save_category', class: 'workflow-bar__button workflow-bar__button--update'
@@ -0,0 +1,50 @@
1
+ %h3= label_tag 'range_facets', t('workarea.admin.facets.price_inputs.price_ranges_label')
2
+
3
+ .property
4
+ = label_tag 'range_facets', default_currency.name, class: 'property__name'
5
+ %table
6
+ %thead
7
+ %tr
8
+ %th= t('workarea.admin.facets.price_inputs.from')
9
+ %th= t('workarea.admin.facets.price_inputs.to')
10
+ %tbody
11
+ - facet.each_with_index do |range, index|
12
+ %tr
13
+ %td
14
+ = currency_symbol
15
+ = text_field_tag 'range_facets[price][][from]', range['from'], title: t('workarea.admin.facets.price_inputs.from'), class: 'text-box text-box--small', id: "range_facets[price][][from][#{index}]"
16
+ %td
17
+ = currency_symbol
18
+ = text_field_tag 'range_facets[price][][to]', range['to'], title: t('workarea.admin.facets.price_inputs.to'), class: 'text-box text-box--small', id: "range_facets[price][][to][#{index}]"
19
+ %tr{ data: { cloneable_row: '' } }
20
+ %td
21
+ = currency_symbol
22
+ = text_field_tag 'range_facets[price][][from]', nil, title: t('workarea.admin.facets.price_inputs.from'), class: 'text-box text-box--small'
23
+ %td
24
+ = currency_symbol
25
+ = text_field_tag 'range_facets[price][][to]', nil, title: t('workarea.admin.facets.price_inputs.to'), class: 'text-box text-box--small'
26
+
27
+ - flow_currencies.each do |currency|
28
+ .property
29
+ = label_tag "currency_facets_#{currency.iso_code}", currency.name, class: 'property__name'
30
+ %table
31
+ %thead
32
+ %tr
33
+ %th= t('workarea.admin.facets.price_inputs.from')
34
+ %th= t('workarea.admin.facets.price_inputs.to')
35
+ %tbody
36
+ - (currency_localized_facets[currency.iso_code] || []).each_with_index do |range, index|
37
+ %tr
38
+ %td
39
+ = currency.symbol
40
+ = text_field_tag "currency_localized_facets[#{currency.iso_code}][][from]", range['from'], title: t('workarea.admin.facets.price_inputs.from'), class: 'text-box text-box--small', id: "currency_localized_facets[][from][#{currency.iso_code}][#{index}]"
41
+ %td
42
+ = currency.symbol
43
+ = text_field_tag "currency_localized_facets[#{currency.iso_code}][][to]", range['to'], title: t('workarea.admin.facets.price_inputs.to'), class: 'text-box text-box--small', id: "currency_localized_facets[][to][#{currency.iso_code}][#{index}]"
44
+ %tr{ data: { cloneable_row: '' } }
45
+ %td
46
+ = currency.symbol
47
+ = text_field_tag "currency_localized_facets[#{currency.iso_code}][][from]", nil, title: t('workarea.admin.facets.price_inputs.from'), class: 'text-box text-box--small', id: "currency_localized_facets[][from][#{currency.iso_code}]"
48
+ %td
49
+ = currency.symbol
50
+ = text_field_tag "currency_localized_facets[#{currency.iso_code}][][to]", nil, title: t('workarea.admin.facets.price_inputs.to'), class: 'text-box text-box--small', id: "currency_localized_facets[][to][#{currency.iso_code}]"