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,30 @@
1
+ module Workarea
2
+ module FlowIo
3
+ class DeleteItems
4
+ include Sidekiq::Worker
5
+ include Sidekiq::CallbacksWorker
6
+
7
+ sidekiq_options(
8
+ enqueue_on: {
9
+ Catalog::Product => :destroy,
10
+ Pricing::Sku => :destroy,
11
+ with: -> do
12
+ if self.class.name == "Workarea::Catalog::Product"
13
+ [self.skus]
14
+ else
15
+ [[id]]
16
+ end
17
+ end
18
+ }
19
+ )
20
+
21
+ def perform(skus)
22
+ client = FlowIo.client
23
+
24
+ skus.each do |sku|
25
+ client.items.delete_by_number(Workarea::FlowIo.organization_id, sku)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ module Workarea
2
+ module FlowIo
3
+ # Fetches new import CSVs from the FTP server, ignoring any that
4
+ # have already been processed.
5
+ class FetchImport
6
+ include Sidekiq::Worker
7
+
8
+ sidekiq_options lock: :until_executing
9
+
10
+ def perform
11
+ username = FlowIo.credentials[:ftp_username]
12
+ password = FlowIo.credentials[:ftp_password]
13
+ path = Pathname.new('flow').join('from-flow', 'export')
14
+
15
+ Net::SFTP.start(FlowIo::FTP_HOST, username, password: password) do |sftp|
16
+ sftp.dir.glob(path.to_s, '*.csv') do |entry|
17
+ Import.find_or_create_by!(name: entry.name) do |import|
18
+ import.file = Tempfile.new(entry.name).tap do |tmp|
19
+ begin
20
+ filepath = path.join(entry.name).to_s
21
+ csv = sftp.download!(filepath)
22
+
23
+ tmp.write(csv)
24
+ ensure
25
+ tmp.close
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ module Workarea
2
+ module FlowIo
3
+ class FulfillmentCancellation
4
+ include Sidekiq::Worker
5
+
6
+ def perform(id, canceled_items)
7
+ fulfillment_cancelation_form = FlowIo::FulfillmentCancellationForm.from(id: id, quantities: canceled_items)
8
+ order = Workarea::Order.find(id)
9
+
10
+ FlowIo.client.fulfillments.put_cancellations(FlowIo.organization_id, order.id, fulfillment_cancelation_form)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,47 @@
1
+ module Workarea
2
+ module FlowIo
3
+ class ItemExporter
4
+ include Sidekiq::Worker
5
+ include Sidekiq::CallbacksWorker
6
+
7
+ sidekiq_options(
8
+ enqueue_on: {
9
+ Catalog::Product => :save,
10
+ Shipping::Sku => :save,
11
+ Pricing::Sku => :save,
12
+ Pricing::Price => :save,
13
+ with: -> { ItemExporter.perform_with(self) }
14
+ }
15
+ )
16
+
17
+ def self.perform_with(model)
18
+ case model.class.name
19
+ when "Workarea::Pricing::Price"
20
+ [model.sku.class.name, model.sku.id]
21
+ else
22
+ [model.class.name, model.id]
23
+ end
24
+ end
25
+
26
+ def perform(class_name, id)
27
+ product, skus =
28
+ if class_name == "Workarea::Catalog::Product"
29
+ prod = Catalog::Product.find(id)
30
+ [prod, prod.skus]
31
+ else
32
+ [Catalog::Product.find_by_sku(id), [id]]
33
+ end
34
+
35
+ return unless product.present?
36
+
37
+ client = FlowIo.client
38
+ organization_id = Workarea::FlowIo.organization_id
39
+
40
+ skus.each do |sku|
41
+ item = Workarea::FlowIo::Item.new(product, sku)
42
+ client.items.put_by_number(organization_id, sku, item.form)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,28 @@
1
+ module Workarea
2
+ module FlowIo
3
+ # Reads the CSV stored in a `Workarea::FlowIo::Import`, and
4
+ # processes each row with `FlatFileItem.import`
5
+ class ProcessImport
6
+ include Sidekiq::Worker
7
+ include Sidekiq::CallbacksWorker
8
+
9
+ sidekiq_options \
10
+ lock: :until_executing,
11
+ enqueue_on: { Import => [:create] }
12
+
13
+ def perform(id)
14
+ import = Import.find(id)
15
+
16
+ import.update!(started_at: Time.current)
17
+
18
+ experiences = FlowIo.client.experiences.get(FlowIo.organization_id)
19
+
20
+ CSV.foreach(import.file_path, headers: true) do |row|
21
+ ImportedItem.process(row, experiences)
22
+ end
23
+
24
+ import.update!(completed_at: Time.current)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ module Workarea
2
+ module FlowIo
3
+ class ShippingNotifications
4
+ include Sidekiq::Worker
5
+
6
+ def perform(id, tracking_number)
7
+ shipping_notification_form = FlowIo::DetailedShippingNotificationForm.from(id: id, tracking_number: tracking_number)
8
+
9
+ FlowIo.client.shipping_notifications.post(FlowIo.organization_id, shipping_notification_form)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path('..', __dir__)
6
+ ENGINE_PATH = File.expand_path('../lib/workarea/flow_io/engine', __dir__)
7
+ APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
8
+
9
+ # Set up gems listed in the Gemfile.
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
11
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
12
+
13
+ require "rails"
14
+ # Pick the frameworks you want:
15
+ require "active_model/railtie"
16
+ require "active_job/railtie"
17
+ # require "active_record/railtie"
18
+ # require "active_storage/engine"
19
+ require "action_controller/railtie"
20
+ require "action_mailer/railtie"
21
+ require "action_view/railtie"
22
+ require "action_cable/engine"
23
+ require "sprockets/railtie"
24
+ require "rails/test_unit/railtie"
25
+ require 'rails/engine/commands'
@@ -0,0 +1,39 @@
1
+ Workarea.append_partials(
2
+ 'storefront.document_head',
3
+ 'workarea/storefront/flow_io_country_picker_javascript'
4
+ )
5
+
6
+ Workarea.append_javascripts(
7
+ 'storefront.modules',
8
+ 'workarea/storefront/flow_io/flow'
9
+ )
10
+
11
+ Workarea.append_javascripts(
12
+ 'storefront.config',
13
+ 'workarea/storefront/flow_io/configuration'
14
+ )
15
+
16
+ Workarea.append_partials(
17
+ 'storefront.footer_help',
18
+ 'workarea/storefront/flow_io_country_picker'
19
+ )
20
+
21
+ Workarea.append_partials(
22
+ 'admin.order_cards',
23
+ 'workarea/admin/orders/flow'
24
+ )
25
+
26
+ Workarea.append_partials(
27
+ 'admin.order_show_workflow_bar_left',
28
+ 'workarea/admin/orders/flow_aux_navigation'
29
+ )
30
+
31
+ Workarea::Plugin.append_stylesheets(
32
+ 'storefront.components',
33
+ 'flow_io/storefront/country_picker'
34
+ )
35
+
36
+ Workarea.append_partials(
37
+ 'admin.settings_menu',
38
+ 'workarea/admin/shared/flow_imports_link'
39
+ )
@@ -0,0 +1,23 @@
1
+ # This throws an *absurd* amount of deprecation warnings when running
2
+ # tests, making it pretty impossible to see what you're doing. It's due
3
+ # to the gem running in Ruby 2.6, which deprecated `BigDecimal.new` and
4
+ # replaced it with the `BigDecimal()` method. Every time
5
+ # `Helper.to_big_decimal` is called by the FlowCommerce gem, we get a
6
+ # big ol' deprecation warning in the console. This should silence those
7
+ # warnings until https://github.com/flowcommerce/ruby-sdk/issues/25 is
8
+ # resolved.
9
+ module Io
10
+ module Flow
11
+ module V0
12
+ module HttpClient
13
+ module Helper
14
+ def Helper.to_big_decimal(value)
15
+ return unless value.present?
16
+
17
+ BigDecimal(value.to_s)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ if Rails.application.config.action_dispatch.rack_cache
2
+ Rails.application.config.middleware.insert_before(
3
+ Rack::Cache,
4
+ Workarea::FlowIo::SessionMiddleware
5
+ )
6
+ else
7
+ Rails.application.config.middleware.insert_before(
8
+ Rack::Head,
9
+ Workarea::FlowIo::SessionMiddleware
10
+ )
11
+ end
@@ -0,0 +1,5 @@
1
+ if ENV['HTTP_PROXY'].present?
2
+ uri = URI.parse(ENV['HTTP_PROXY'])
3
+ ActiveMerchant::Billing::FlowGateway.proxy_address = uri.host
4
+ ActiveMerchant::Billing::FlowGateway.proxy_port = uri.port
5
+ end
@@ -0,0 +1,15 @@
1
+ class Rack::Attack
2
+ safelist('allow flow webhooks') do |req|
3
+ request_signature = req.env['HTTP_X_FLOW_SIGNATURE']
4
+
5
+ next false unless request_signature.present?
6
+
7
+ body = req.body.read
8
+ req.body.rewind
9
+
10
+ Workarea::FlowIo::WebhookRequestSignature.valid?(
11
+ request_signature: request_signature,
12
+ request_body: body
13
+ )
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ unless Workarea.config.skip_service_connections
2
+ if Workarea::FlowIo.credentials.key?(:ftp_username) && Workarea::FlowIo.credentials.key?(:ftp_password)
3
+ Sidekiq::Cron::Job.create(
4
+ name: 'Workarea::FlowIo::FetchImport',
5
+ klass: 'Workarea::FlowIo::FetchImport',
6
+ cron: "0 9 * * * #{Time.zone.tzinfo.identifier}"
7
+ )
8
+ end
9
+ end
@@ -0,0 +1,101 @@
1
+ Workarea.configure do |config|
2
+ config.cache_expirations.flow_io_country_cache = 1.hour
3
+
4
+ config.flow_io ||= ActiveSupport::Configurable::Configuration.new
5
+
6
+ # Enable JS integration for real-time price updates. Defaults to
7
+ # `false`.
8
+ config.flow_io.enable_javascript = false
9
+
10
+ # default payment action. FlowIO recomends purchase (auth/cap)
11
+ config.flow_io.default_payment_action = "purchase"
12
+
13
+ # default timeout on flow api calls
14
+ config.flow_io.default_timeout = 2
15
+
16
+ # hash of processor to image tags for flow
17
+ # see https://docs.flow.io/type/image-tag
18
+ config.flow_io.image_sizes = {
19
+ small_thumb: ["thumbnail"],
20
+ medium_thumb: ["checkout"],
21
+ }
22
+
23
+ # URI that flow checkouts will be redirected to.
24
+ # Exclude the trailing slash.
25
+ config.flow_io.checkout_uri = "https://checkout.flow.io"
26
+
27
+ config.tender_types.prepend(:flow_payment)
28
+
29
+ # The locale in which the content of the catalog is written.
30
+ config.flow_io.original_locale = "en_US"
31
+
32
+ config.flow_io.localization_attributes = [
33
+ {
34
+ key: 'regular_price',
35
+ options: {
36
+ required: true,
37
+ show_in_catalog: true,
38
+ show_in_harmonization: true
39
+ },
40
+ label: 'Regular Price',
41
+ intent: 'price',
42
+ type: 'decimal'
43
+ },
44
+ {
45
+ key: 'sale_price',
46
+ options: {
47
+ required: false,
48
+ show_in_catalog: true,
49
+ show_in_harmonization: true
50
+ },
51
+ label: 'Sale Price',
52
+ intent: 'price',
53
+ type: 'decimal'
54
+ },
55
+ {
56
+ key: 'msrp',
57
+ options: {
58
+ required: false,
59
+ show_in_catalog: true,
60
+ show_in_harmonization: true
61
+ },
62
+ label: 'MSRP',
63
+ intent: 'price',
64
+ type: 'decimal'
65
+ },
66
+ {
67
+ key: 'product_id',
68
+ options: {
69
+ required: true,
70
+ show_in_catalog: true,
71
+ show_in_harmonization: false
72
+ },
73
+ label: 'Product ID',
74
+ intent: 'product_id',
75
+ type: 'string'
76
+ },
77
+ {
78
+ key: 'fulfillment_method',
79
+ options: {
80
+ required: false,
81
+ show_in_catalog: true,
82
+ show_in_harmonization: false
83
+ },
84
+ label: 'Fulfillment Method',
85
+ intent: 'fulfillment_method',
86
+ type: 'String'
87
+ }
88
+ ]
89
+
90
+ config.pricing_calculators << "Workarea::Pricing::Calculators::FlowLocalizationCalculator"
91
+
92
+ config.flow_io.webhook_events = [
93
+ "order_upserted_v2",
94
+ "experience_deleted_v2",
95
+ "experience_upserted_v2"
96
+ ]
97
+
98
+ config.run_credit_card_refund_tests = true
99
+
100
+ config.exclude_from_search_results_breadcrumbs.push(:experience)
101
+ end
@@ -0,0 +1,11 @@
1
+ module Workarea
2
+ module I18n
3
+ module FlowIoConstraintOverride
4
+ def routes_constraint
5
+ Workarea::FlowIo::RoutingContraints.new
6
+ end
7
+ end
8
+
9
+ self.singleton_class.prepend FlowIoConstraintOverride
10
+ end
11
+ end
@@ -0,0 +1,72 @@
1
+ en:
2
+ workarea:
3
+ admin:
4
+ flow_imports:
5
+ errors:
6
+ error: Error
7
+ page_title: Errors for %{name} %{type}
8
+ dashboard_link: All Imports & Exports
9
+ title: Errors for %{name} %{type}
10
+ unknown_type: Unknown
11
+ table:
12
+ id_or_line: ID or Line Number
13
+ field: Field
14
+ message: Message
15
+ index:
16
+ dashboard_link: Settings dashboard
17
+ import: Import
18
+ info: Review details of imports from the last %{duration}
19
+ page_title: Flow Imports
20
+ showing: Showing %{count},
21
+ title: Flow Imports
22
+ view_imports: view imports
23
+ localized_prices:
24
+ label: Localized Prices
25
+ base: Base
26
+ base_tooltip: The price converted into the localized currency with rounding rules applied then converted back into the base currency.
27
+ localized: Localized
28
+ regular_base: Regular Base
29
+ regular_localized: Regular Localized
30
+ sale_localized: Sale Localized
31
+ sale_base: Sale Base
32
+ title: Localized Prices for %{sku}
33
+ orders:
34
+ view_flow_order: View Order in Flow Console
35
+ cards:
36
+ flow:
37
+ id: Flow Order ID
38
+ pending_import: Pending Import
39
+ flow_total_price: Flow Total Price
40
+ flow_tax_total: Flow Tax Total
41
+ attributes:
42
+ flow:
43
+ title: Flow
44
+ flow:
45
+ console: View in Flow Console
46
+ checkout:
47
+ title: Flow Checkout
48
+ customer: 'Customer:'
49
+ status: 'Status:'
50
+ items:
51
+ flow_pricing: "Flow Pricing (%{currency})"
52
+ pricing: "Base Pricing (%{currency})"
53
+ product: Product
54
+ quantity: Quantity
55
+ title: Items
56
+ title: "%{name} Details"
57
+ totals:
58
+ base_totals: Base Totals (%{currency})
59
+ flow_totals: "Flow Totals (%{currency})"
60
+ shipping: Shipping
61
+ subtotal: Subtotal
62
+ tax: Tax
63
+ title: Totals
64
+ total_price: Total Price
65
+ total_value: Total Value
66
+ pricing_skus:
67
+ cards:
68
+ localized_prices:
69
+ button: View Localized Prices
70
+ shared:
71
+ primary_nav:
72
+ flow_imports: Flow Imports