workarea-core 3.4.45 → 3.5.0.beta.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 (427) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +52 -0
  3. data/app/assets/javascripts/workarea/core/modules/duplicate_id.js +1 -5
  4. data/app/assets/javascripts/workarea/core/modules/style_guide_autocomplete_fields.js +9 -42
  5. data/app/assets/javascripts/workarea/core/modules/url.js +14 -0
  6. data/app/controllers/workarea/application_controller.rb +5 -1
  7. data/app/controllers/workarea/authentication.rb +15 -26
  8. data/app/controllers/workarea/authorization.rb +3 -3
  9. data/app/controllers/workarea/current_referrer.rb +1 -2
  10. data/app/controllers/workarea/current_release.rb +1 -1
  11. data/app/controllers/workarea/current_segments.rb +52 -0
  12. data/app/controllers/workarea/current_tracking.rb +45 -0
  13. data/app/controllers/workarea/http_caching.rb +30 -0
  14. data/app/controllers/workarea/impersonation.rb +18 -44
  15. data/app/helpers/workarea/schema_org_helper.rb +21 -0
  16. data/app/mailers/workarea/application_mailer.rb +2 -4
  17. data/app/middleware/workarea/application_middleware.rb +44 -0
  18. data/app/middleware/workarea/query_cache_middleware.rb +55 -0
  19. data/app/middleware/workarea/release_server_middleware.rb +1 -1
  20. data/app/models/workarea/application_document.rb +1 -1
  21. data/app/models/workarea/bulk_action/product_edit.rb +6 -6
  22. data/app/models/workarea/calculate_percent_change.rb +1 -1
  23. data/app/models/workarea/catalog/category.rb +0 -2
  24. data/app/models/workarea/catalog/product.rb +19 -2
  25. data/app/models/workarea/checkout/collect_payment.rb +10 -1
  26. data/app/models/workarea/checkout/fraud/analyzer.rb +44 -0
  27. data/app/models/workarea/checkout/fraud/no_decision_analyzer.rb +14 -0
  28. data/app/models/workarea/checkout/fraud/test_analyzer.rb +26 -0
  29. data/app/models/workarea/checkout.rb +18 -6
  30. data/app/models/workarea/configuration/admin.rb +25 -0
  31. data/app/models/workarea/configuration/params.rb +45 -0
  32. data/app/models/workarea/content/asset.rb +5 -18
  33. data/app/models/workarea/content/block.rb +8 -2
  34. data/app/models/workarea/content/block_draft.rb +7 -2
  35. data/app/models/workarea/content/block_type.rb +2 -2
  36. data/app/models/workarea/content/block_type_definition.rb +4 -0
  37. data/app/models/workarea/content/preset.rb +1 -1
  38. data/app/models/workarea/content.rb +12 -82
  39. data/app/models/workarea/data_file/csv.rb +6 -8
  40. data/app/models/workarea/data_file/import.rb +9 -1
  41. data/app/models/workarea/data_file/json.rb +1 -20
  42. data/app/models/workarea/data_file/operation.rb +0 -4
  43. data/app/models/workarea/data_file/tax_rates.rb +3 -0
  44. data/app/models/workarea/featured_products.rb +8 -0
  45. data/app/models/workarea/fulfillment/policies/base.rb +21 -0
  46. data/app/models/workarea/fulfillment/policies/download.rb +21 -0
  47. data/app/models/workarea/fulfillment/policies/ignore.rb +11 -0
  48. data/app/models/workarea/fulfillment/policies/ship.rb +15 -0
  49. data/app/models/workarea/fulfillment/sku.rb +72 -0
  50. data/app/models/workarea/fulfillment/token.rb +36 -0
  51. data/app/models/workarea/inquiry.rb +1 -2
  52. data/app/models/workarea/insights/customer_acquisition.rb +5 -9
  53. data/app/models/workarea/insights/trending_products.rb +2 -2
  54. data/app/models/workarea/insights/trending_searches.rb +2 -2
  55. data/app/models/workarea/inventory/collection.rb +30 -0
  56. data/app/models/workarea/inventory/collection_status.rb +40 -0
  57. data/app/models/workarea/metrics/affinity.rb +33 -0
  58. data/app/models/workarea/metrics/country_by_day.rb +4 -0
  59. data/app/models/workarea/metrics/product_by_day.rb +3 -0
  60. data/app/models/workarea/metrics/product_by_week.rb +2 -0
  61. data/app/models/workarea/metrics/product_for_last_week.rb +8 -12
  62. data/app/models/workarea/metrics/sales_by_day.rb +5 -0
  63. data/app/models/workarea/metrics/search_by_day.rb +1 -3
  64. data/app/models/workarea/metrics/search_for_last_week.rb +5 -11
  65. data/app/models/workarea/metrics/segment_by_day.rb +31 -0
  66. data/app/models/workarea/metrics/sku_by_day.rb +3 -0
  67. data/app/models/workarea/metrics/tender_by_day.rb +11 -0
  68. data/app/models/workarea/metrics/update_user_aggregations.rb +77 -0
  69. data/app/models/workarea/metrics/user.rb +73 -87
  70. data/app/models/workarea/navigation/breadcrumbs.rb +10 -1
  71. data/app/models/workarea/order/fraud_decision.rb +18 -0
  72. data/app/models/workarea/order/item.rb +5 -0
  73. data/app/models/workarea/order/queries.rb +1 -0
  74. data/app/models/workarea/order/status.rb +10 -1
  75. data/app/models/workarea/order.rb +47 -4
  76. data/app/models/workarea/payment/credit_card.rb +12 -0
  77. data/app/models/workarea/payment.rb +7 -2
  78. data/app/models/workarea/pricing/cache_key.rb +9 -3
  79. data/app/models/workarea/pricing/calculator.rb +5 -1
  80. data/app/models/workarea/pricing/calculators/tax_calculator.rb +32 -5
  81. data/app/models/workarea/pricing/discount/application_group.rb +8 -3
  82. data/app/models/workarea/pricing/discount/free_gift.rb +2 -1
  83. data/app/models/workarea/pricing/discount/redemption.rb +1 -1
  84. data/app/models/workarea/pricing/discount.rb +2 -3
  85. data/app/models/workarea/pricing/item_tax_applier.rb +41 -0
  86. data/app/models/workarea/pricing/price.rb +1 -0
  87. data/app/models/workarea/pricing/request.rb +11 -0
  88. data/app/models/workarea/pricing/sku.rb +1 -0
  89. data/app/models/workarea/pricing/tax_application.rb +21 -0
  90. data/app/models/workarea/pricing/tax_applier.rb +12 -15
  91. data/app/models/workarea/pricing/unsupported_segmentation.rb +22 -0
  92. data/app/models/workarea/product_rule.rb +5 -0
  93. data/app/models/workarea/releasable.rb +83 -89
  94. data/app/models/workarea/release/activation.rb +45 -0
  95. data/app/models/workarea/release/changes.rb +45 -0
  96. data/app/models/workarea/release/changeset.rb +42 -52
  97. data/app/models/workarea/release/preview.rb +28 -0
  98. data/app/models/workarea/release/status.rb +2 -24
  99. data/app/models/workarea/release.rb +72 -99
  100. data/app/models/workarea/release_session.rb +11 -11
  101. data/app/models/workarea/search/admin/catalog_product.rb +1 -2
  102. data/app/models/workarea/search/admin/fulfillment_sku.rb +27 -0
  103. data/app/models/workarea/search/admin/order.rb +1 -1
  104. data/app/models/workarea/search/admin/pricing_discount.rb +1 -1
  105. data/app/models/workarea/search/admin/release.rb +1 -4
  106. data/app/models/workarea/search/admin/segment.rb +19 -0
  107. data/app/models/workarea/search/admin.rb +17 -39
  108. data/app/models/workarea/search/order_text.rb +23 -6
  109. data/app/models/workarea/search/storefront/category_query.rb +152 -0
  110. data/app/models/workarea/search/storefront/product/categories.rb +11 -45
  111. data/app/models/workarea/search/storefront.rb +33 -29
  112. data/app/models/workarea/segment/first_time_customer.rb +8 -0
  113. data/app/models/workarea/segment/first_time_visitor.rb +12 -0
  114. data/app/models/workarea/segment/life_cycle.rb +44 -0
  115. data/app/models/workarea/segment/loyal_customer.rb +12 -0
  116. data/app/models/workarea/segment/returning_customer.rb +14 -0
  117. data/app/models/workarea/segment/returning_visitor.rb +12 -0
  118. data/app/models/workarea/segment/rules/base.rb +16 -0
  119. data/app/models/workarea/segment/rules/browser_info.rb +29 -0
  120. data/app/models/workarea/segment/rules/geolocation.rb +29 -0
  121. data/app/models/workarea/segment/rules/geolocation_option.rb +53 -0
  122. data/app/models/workarea/segment/rules/last_order.rb +14 -0
  123. data/app/models/workarea/segment/rules/logged_in.rb +13 -0
  124. data/app/models/workarea/segment/rules/orders.rb +17 -0
  125. data/app/models/workarea/segment/rules/revenue.rb +17 -0
  126. data/app/models/workarea/segment/rules/sessions.rb +17 -0
  127. data/app/models/workarea/segment/rules/tags.rb +14 -0
  128. data/app/models/workarea/segment/rules/traffic_referrer.rb +18 -0
  129. data/app/models/workarea/segment.rb +54 -0
  130. data/app/models/workarea/segmentable.rb +66 -0
  131. data/app/models/workarea/sort.rb +14 -2
  132. data/app/models/workarea/tax/rate.rb +35 -1
  133. data/app/models/workarea/user/authorization.rb +19 -13
  134. data/app/models/workarea/user/login.rb +4 -0
  135. data/app/models/workarea/user/password_reset.rb +1 -3
  136. data/app/queries/workarea/categorization.rb +3 -3
  137. data/app/queries/workarea/featured_categorization.rb +53 -0
  138. data/app/queries/workarea/order_cancellation_metrics.rb +155 -0
  139. data/app/queries/workarea/order_item_details.rb +16 -3
  140. data/app/queries/workarea/order_metrics.rb +32 -3
  141. data/app/queries/workarea/product_primary_navigation.rb +13 -2
  142. data/app/queries/workarea/product_releases.rb +38 -0
  143. data/app/queries/workarea/recommendation/user_activity_based.rb +14 -6
  144. data/app/queries/workarea/reports/average_order_value.rb +1 -1
  145. data/app/queries/workarea/reports/customers.rb +14 -11
  146. data/app/queries/workarea/reports/first_time_vs_returning_sales.rb +1 -1
  147. data/app/queries/workarea/reports/group_by_time.rb +13 -17
  148. data/app/queries/workarea/reports/sales_by_category.rb +1 -1
  149. data/app/queries/workarea/reports/sales_by_country.rb +10 -3
  150. data/app/queries/workarea/reports/sales_by_discount.rb +1 -1
  151. data/app/queries/workarea/reports/sales_by_menu.rb +1 -1
  152. data/app/queries/workarea/reports/sales_by_product.rb +39 -4
  153. data/app/queries/workarea/reports/sales_by_sku.rb +39 -4
  154. data/app/queries/workarea/reports/sales_by_tender.rb +42 -0
  155. data/app/queries/workarea/reports/sales_by_traffic_referrer.rb +1 -1
  156. data/app/queries/workarea/reports/sales_over_time.rb +10 -3
  157. data/app/queries/workarea/reports/searches.rb +1 -1
  158. data/app/queries/workarea/reports/searches_over_time.rb +1 -1
  159. data/app/queries/workarea/reports/searches_without_results_over_time.rb +1 -1
  160. data/app/queries/workarea/search/admin_fulfillment_skus.rb +20 -0
  161. data/app/queries/workarea/search/admin_releases.rb +1 -4
  162. data/app/queries/workarea/search/admin_search.rb +0 -4
  163. data/app/queries/workarea/search/admin_segments.rb +16 -0
  164. data/app/queries/workarea/search/admin_sorting.rb +1 -1
  165. data/app/queries/workarea/search/pagination.rb +1 -4
  166. data/app/queries/workarea/search/product_display_rules.rb +40 -8
  167. data/app/queries/workarea/search/product_entries.rb +15 -1
  168. data/app/queries/workarea/search/product_search.rb +4 -1
  169. data/app/queries/workarea/search/storefront_search/exact_matches.rb +1 -1
  170. data/app/queries/workarea/search/storefront_search/response.rb +6 -4
  171. data/app/queries/workarea/search/storefront_search.rb +5 -4
  172. data/app/seeds/workarea/assets_seeds.rb +2 -1
  173. data/app/seeds/workarea/insights_seeds.rb +0 -23
  174. data/app/seeds/workarea/orders_seeds.rb +7 -6
  175. data/app/seeds/workarea/products_seeds.rb +2 -0
  176. data/app/seeds/workarea/segments_seeds.rb +8 -0
  177. data/app/seeds/workarea/tax_seeds.rb +3 -3
  178. data/app/services/workarea/cancel_order.rb +8 -3
  179. data/app/services/workarea/copy_order.rb +6 -0
  180. data/app/services/workarea/create_fulfillment.rb +5 -3
  181. data/app/services/workarea/direct_upload.rb +11 -19
  182. data/app/services/workarea/hash_update.rb +1 -18
  183. data/app/services/workarea/packaging.rb +1 -1
  184. data/app/services/workarea/save_publishing.rb +5 -1
  185. data/app/workers/sidekiq/callbacks.rb +4 -52
  186. data/app/workers/sidekiq/callbacks_worker.rb +4 -6
  187. data/app/workers/workarea/bulk_index_admin.rb +2 -2
  188. data/app/workers/workarea/bulk_index_products.rb +6 -5
  189. data/app/workers/workarea/bulk_index_searches.rb +5 -5
  190. data/app/workers/workarea/deactivate_stale_discounts.rb +3 -3
  191. data/app/workers/workarea/generate_insights.rb +1 -1
  192. data/app/workers/workarea/index_admin_search.rb +1 -0
  193. data/app/workers/workarea/index_categorization.rb +4 -7
  194. data/app/workers/workarea/index_category.rb +2 -1
  195. data/app/workers/workarea/index_category_changes.rb +11 -6
  196. data/app/workers/workarea/index_fulfillment_changes.rb +2 -1
  197. data/app/workers/workarea/index_help.rb +2 -1
  198. data/app/workers/workarea/index_page.rb +2 -1
  199. data/app/workers/workarea/index_payment_transactions.rb +2 -1
  200. data/app/workers/workarea/index_product.rb +4 -4
  201. data/app/workers/workarea/index_product_children.rb +4 -3
  202. data/app/workers/workarea/index_product_rule.rb +3 -2
  203. data/app/workers/workarea/index_search_customizations.rb +3 -2
  204. data/app/workers/workarea/index_skus.rb +5 -6
  205. data/app/workers/workarea/keep_product_index_fresh.rb +3 -5
  206. data/app/workers/workarea/process_import.rb +3 -3
  207. data/app/workers/workarea/process_search_recommendations.rb +5 -9
  208. data/app/workers/workarea/publish_release.rb +1 -0
  209. data/app/workers/workarea/save_metrics.rb +116 -0
  210. data/app/workers/workarea/save_order_cancellation_metrics.rb +35 -0
  211. data/app/workers/workarea/save_order_metrics.rb +10 -74
  212. data/app/workers/workarea/status_reporter.rb +2 -4
  213. data/app/workers/workarea/synchronize_user_metrics.rb +17 -0
  214. data/app/workers/workarea/update_payment_profile_email.rb +22 -0
  215. data/app/workers/workarea/verify_scheduled_releases.rb +4 -11
  216. data/config/initializers/00_configuration.rb +185 -0
  217. data/config/initializers/02_assets.rb +1 -0
  218. data/config/initializers/05_scheduled_jobs.rb +0 -7
  219. data/config/initializers/10_rack_middleware.rb +2 -5
  220. data/config/initializers/11_payment.rb +4 -0
  221. data/config/initializers/13_rack_attack.rb +2 -4
  222. data/config/initializers/14_content_block_types.rb +16 -16
  223. data/config/initializers/15_endpoint_monitoring.rb +3 -6
  224. data/config/initializers/{21_premailer.rb → 24_premailer.rb} +1 -0
  225. data/config/initializers/{20_i18n_js.rb → 25_i18n_js.rb} +0 -0
  226. data/config/locales/en.yml +13 -24
  227. data/lib/generators/workarea/content_block_type/templates/initializer.rb +1 -1
  228. data/lib/generators/workarea/install/USAGE +0 -1
  229. data/lib/generators/workarea/install/install_generator.rb +0 -21
  230. data/lib/generators/workarea/install/templates/initializer.rb.erb +1 -1
  231. data/lib/tasks/insights.rake +1 -0
  232. data/lib/tasks/migrate.rake +106 -0
  233. data/lib/tasks/search.rake +17 -19
  234. data/lib/tasks/tests.rake +1 -1
  235. data/lib/workarea/cache.rb +6 -35
  236. data/lib/workarea/changelog.rake +2 -2
  237. data/lib/workarea/configuration/administrable/definition.rb +42 -0
  238. data/lib/workarea/configuration/administrable/field.rb +79 -0
  239. data/lib/workarea/configuration/administrable/fieldset.rb +44 -0
  240. data/lib/workarea/configuration/administrable_options.rb +24 -0
  241. data/lib/workarea/configuration/cache_store.rb +3 -1
  242. data/lib/workarea/configuration/content_blocks.rb +17 -0
  243. data/lib/workarea/configuration/mongoid.rb +1 -4
  244. data/lib/workarea/configuration/session.rb +36 -0
  245. data/lib/workarea/configuration/sidekiq.rb +3 -1
  246. data/lib/workarea/configuration.rb +121 -148
  247. data/lib/workarea/core/engine.rb +3 -58
  248. data/lib/workarea/core.rb +15 -11
  249. data/lib/workarea/elasticsearch/document.rb +8 -15
  250. data/lib/workarea/ext/freedom_patches/action_view_cache_helper.rb +4 -6
  251. data/lib/workarea/ext/freedom_patches/active_support_duration.rb +14 -0
  252. data/lib/workarea/ext/freedom_patches/money.rb +11 -0
  253. data/lib/workarea/ext/freedom_patches/premailer.rb +6 -0
  254. data/lib/workarea/ext/freedom_patches/string.rb +19 -4
  255. data/lib/workarea/ext/mongoid/find_ordered.rb +2 -2
  256. data/lib/workarea/ext/mongoid/lookup_hash.rb +30 -0
  257. data/lib/workarea/geolocation.rb +24 -6
  258. data/lib/workarea/routes_constraints/super_admin.rb +1 -1
  259. data/lib/workarea/version.rb +3 -4
  260. data/lib/workarea/visit.rb +92 -0
  261. data/lib/workarea/warnings.rb +95 -0
  262. data/lib/workarea.rb +102 -3
  263. data/test/dummy/config/initializers/session_store.rb +1 -1
  264. data/test/fixtures/tax_rates.csv +3 -3
  265. data/test/generators/workarea/content_block_type_generator_test.rb +1 -1
  266. data/test/generators/workarea/install_generator_test.rb +0 -13
  267. data/test/integration/workarea/authentication_test.rb +27 -4
  268. data/test/integration/workarea/authorization_test.rb +5 -0
  269. data/test/integration/workarea/cache_varies_integration_test.rb +21 -23
  270. data/test/integration/workarea/monitoring_integration_test.rb +5 -10
  271. data/test/javascripts/duplicate_id_spec.js +1 -7
  272. data/test/javascripts/fixtures/{duplicate_id_fail.html.haml → duplicate_id.html.haml} +0 -1
  273. data/test/javascripts/form_submitting_controls_spec.js +0 -1
  274. data/test/lib/workarea/asset_endpoints/favicons_test.rb +11 -13
  275. data/test/lib/workarea/configuration/administrable/definition_test.rb +71 -0
  276. data/test/lib/workarea/configuration/administrable/field_test.rb +128 -0
  277. data/test/lib/workarea/configuration/administrable/fieldset_test.rb +78 -0
  278. data/test/lib/workarea/configuration/configuration_test.rb +20 -0
  279. data/test/lib/workarea/elasticsearch/document_test.rb +0 -20
  280. data/test/lib/workarea/elasticsearch/query_cache_test.rb +7 -7
  281. data/test/lib/workarea/ext/freedom_patches/money_test.rb +11 -0
  282. data/test/lib/workarea/ext/mongoid/lookup_hash_test.rb +86 -0
  283. data/test/lib/workarea/geolocation_test.rb +20 -0
  284. data/test/mailers/workarea/application_mailer_test.rb +1 -11
  285. data/test/middleware/workarea/query_cache_middleware_test.rb +55 -0
  286. data/test/models/workarea/checkout/collect_payment_test.rb +14 -6
  287. data/test/models/workarea/checkout_test.rb +31 -57
  288. data/test/models/workarea/configuration/params_test.rb +37 -0
  289. data/test/models/workarea/data_file/csv_test.rb +8 -73
  290. data/test/models/workarea/data_file/import_test.rb +31 -0
  291. data/test/models/workarea/data_file/json_test.rb +6 -48
  292. data/test/models/workarea/data_file/tax_test.rb +3 -0
  293. data/test/models/workarea/fulfillment/policies/download_test.rb +39 -0
  294. data/test/models/workarea/fulfillment/sku_test.rb +54 -0
  295. data/test/models/workarea/insights/best_customers_test.rb +5 -2
  296. data/test/models/workarea/insights/best_full_price_customers_test.rb +5 -2
  297. data/test/models/workarea/insights/customer_acquisition_test.rb +1 -1
  298. data/test/models/workarea/insights/customers_at_risk_test.rb +1 -1
  299. data/test/models/workarea/insights/low_aov_customers_test.rb +1 -1
  300. data/test/models/workarea/inventory/collection_test.rb +75 -0
  301. data/test/models/workarea/metrics/affinity_test.rb +85 -0
  302. data/test/models/workarea/metrics/product_by_week_test.rb +27 -31
  303. data/test/models/workarea/metrics/search_by_day_test.rb +3 -0
  304. data/test/models/workarea/metrics/search_by_week_test.rb +27 -31
  305. data/test/models/workarea/metrics/update_user_aggregations_test.rb +62 -0
  306. data/test/models/workarea/metrics/user_test.rb +146 -63
  307. data/test/models/workarea/navigation/breadcrumbs_test.rb +12 -2
  308. data/test/models/workarea/order/queries_test.rb +2 -0
  309. data/test/models/workarea/order_test.rb +44 -0
  310. data/test/models/workarea/payment/address_test.rb +109 -111
  311. data/test/models/workarea/payment/credit_card_integration_test.rb +0 -52
  312. data/test/models/workarea/payment/credit_card_test.rb +5 -0
  313. data/test/models/workarea/pricing/cache_key_test.rb +7 -1
  314. data/test/models/workarea/pricing/calculators/tax_calculator_test.rb +41 -1
  315. data/test/models/workarea/pricing/discount/collection_test.rb +27 -29
  316. data/test/models/workarea/pricing/discount_test.rb +22 -24
  317. data/test/models/workarea/pricing/item_tax_applier_test.rb +83 -0
  318. data/test/models/workarea/pricing/price_test.rb +9 -0
  319. data/test/models/workarea/pricing/request_test.rb +13 -0
  320. data/test/models/workarea/pricing/sku_test.rb +9 -0
  321. data/test/models/workarea/releasable_active_test.rb +113 -0
  322. data/test/models/workarea/releasable_test.rb +69 -120
  323. data/test/models/workarea/release/changeset_test.rb +41 -0
  324. data/test/models/workarea/release_jobs_test.rb +52 -0
  325. data/test/models/workarea/release_previewing_test.rb +43 -0
  326. data/test/models/workarea/release_test.rb +59 -153
  327. data/test/models/workarea/search/admin/content_asset_test.rb +26 -28
  328. data/test/models/workarea/search/order_text_test.rb +35 -0
  329. data/test/models/workarea/search/storefront/category_query_test.rb +81 -0
  330. data/test/models/workarea/search/storefront/product/categories_test.rb +10 -70
  331. data/test/models/workarea/search/storefront/product_test.rb +10 -11
  332. data/test/models/workarea/search/storefront_test.rb +1 -13
  333. data/test/models/workarea/segment/life_cycle_test.rb +24 -0
  334. data/test/models/workarea/segment/rules/browser_info_test.rb +33 -0
  335. data/test/models/workarea/segment/rules/geolocation_option_test.rb +16 -0
  336. data/test/models/workarea/segment/rules/geolocation_test.rb +49 -0
  337. data/test/models/workarea/segment/rules/last_order_test.rb +32 -0
  338. data/test/models/workarea/segment/rules/logged_in_test.rb +25 -0
  339. data/test/models/workarea/segment/rules/orders_test.rb +59 -0
  340. data/test/models/workarea/segment/rules/revenue_test.rb +59 -0
  341. data/test/models/workarea/segment/rules/sessions_test.rb +26 -0
  342. data/test/models/workarea/segment/rules/tags_test.rb +27 -0
  343. data/test/models/workarea/segment/rules/traffic_referrer_test.rb +31 -0
  344. data/test/models/workarea/segment_test.rb +80 -0
  345. data/test/models/workarea/segmentable_test.rb +74 -0
  346. data/test/models/workarea/shipping/address_test.rb +109 -111
  347. data/test/models/workarea/shipping/sku_test.rb +8 -12
  348. data/test/models/workarea/user/password_reset_test.rb +4 -12
  349. data/test/models/workarea/user_test.rb +13 -10
  350. data/test/queries/workarea/admin_search_query_wrapper_test.rb +21 -25
  351. data/test/queries/workarea/categorization_test.rb +49 -0
  352. data/test/queries/workarea/featured_categorization_test.rb +66 -0
  353. data/test/queries/workarea/order_cancellation_metrics_test.rb +203 -0
  354. data/test/queries/workarea/order_item_details_test.rb +17 -0
  355. data/test/queries/workarea/order_metrics_test.rb +12 -0
  356. data/test/queries/workarea/product_releases_test.rb +56 -0
  357. data/test/queries/workarea/recommendation/searches_test.rb +3 -3
  358. data/test/queries/workarea/recommendation/user_activity_based_test.rb +4 -4
  359. data/test/queries/workarea/reports/customers_test.rb +12 -8
  360. data/test/queries/workarea/reports/report_test.rb +4 -6
  361. data/test/queries/workarea/reports/sales_by_country_test.rb +18 -3
  362. data/test/queries/workarea/reports/sales_by_product_test.rb +28 -8
  363. data/test/queries/workarea/reports/sales_by_sku_test.rb +28 -8
  364. data/test/queries/workarea/reports/sales_by_tender_test.rb +100 -0
  365. data/test/queries/workarea/reports/sales_by_traffic_referrer_test.rb +6 -6
  366. data/test/queries/workarea/search/admin_releases_test.rb +1 -26
  367. data/test/queries/workarea/search/admin_search_test.rb +0 -10
  368. data/test/queries/workarea/search/admin_users_test.rb +2 -2
  369. data/test/queries/workarea/search/category_browse_test.rb +53 -0
  370. data/test/queries/workarea/search/facet_sorting/size_test.rb +11 -13
  371. data/test/queries/workarea/search/pagination_test.rb +9 -26
  372. data/test/queries/workarea/search/product_entries_test.rb +27 -0
  373. data/test/queries/workarea/search/product_search_test.rb +0 -16
  374. data/test/queries/workarea/search/storefront_search/response_test.rb +26 -0
  375. data/test/queries/workarea/search/storefront_search_test.rb +34 -36
  376. data/test/services/workarea/cancel_order_test.rb +27 -13
  377. data/test/services/workarea/copy_order_test.rb +17 -0
  378. data/test/services/workarea/direct_upload_test.rb +1 -46
  379. data/test/services/workarea/export_report_test.rb +41 -45
  380. data/test/services/workarea/hash_update_test.rb +12 -12
  381. data/test/services/workarea/packaging_test.rb +9 -11
  382. data/test/services/workarea/save_publishing_test.rb +23 -0
  383. data/test/workers/sidekiq/callbacks_test.rb +0 -22
  384. data/test/workers/workarea/deactivate_stale_discounts_test.rb +2 -2
  385. data/test/workers/workarea/index_category_changes_test.rb +5 -7
  386. data/test/workers/workarea/keep_product_index_fresh_test.rb +1 -1
  387. data/test/workers/workarea/process_import_test.rb +0 -6
  388. data/test/workers/workarea/process_search_recommendations_test.rb +4 -5
  389. data/test/workers/workarea/status_reporter_test.rb +2 -1
  390. data/test/workers/workarea/synchronize_user_metrics_test.rb +57 -0
  391. data/test/workers/workarea/update_payment_profile_email_test.rb +27 -0
  392. data/test/workers/workarea/verify_scheduled_releases_test.rb +0 -26
  393. data/workarea-core.gemspec +13 -11
  394. metadata +196 -92
  395. data/app/assets/javascripts/workarea/core/templates/ui_menu_item.jst.ejs +0 -10
  396. data/app/controllers/workarea/admin_guest_browsing.rb +0 -54
  397. data/app/middleware/workarea/rack_cache_config_middleware.rb +0 -19
  398. data/app/queries/workarea/search/search_suggestions.rb +0 -43
  399. data/app/workers/workarea/bust_discount_cache.rb +0 -16
  400. data/app/workers/workarea/clean_user_activity.rb +0 -11
  401. data/app/workers/workarea/undo_release.rb +0 -15
  402. data/app/workers/workarea/update_email.rb +0 -33
  403. data/lib/generators/workarea/docker/USAGE +0 -16
  404. data/lib/generators/workarea/docker/docker_generator.rb +0 -61
  405. data/lib/generators/workarea/docker/templates/.env.erb +0 -6
  406. data/lib/generators/workarea/docker/templates/Dockerfile.erb +0 -48
  407. data/lib/generators/workarea/docker/templates/docker-compose.yml.erb +0 -72
  408. data/lib/generators/workarea/docker/templates/docker-entrypoint.sh.erb +0 -6
  409. data/lib/generators/workarea/docker/templates/docker-sync.yml.erb +0 -8
  410. data/lib/generators/workarea/docker/templates/docker-wait.sh +0 -11
  411. data/lib/generators/workarea/docker/templates/docker.env +0 -16
  412. data/lib/generators/workarea/docker/templates/docker_init.rb.erb +0 -29
  413. data/lib/workarea/configuration/headless_chrome.rb +0 -42
  414. data/lib/workarea/configuration/puma.rb +0 -37
  415. data/lib/workarea/ext/freedom_patches/i18n_js.rb +0 -27
  416. data/lib/workarea/ext/freedom_patches/mongoid_localized_defaults.rb +0 -25
  417. data/lib/workarea/ext/jbuilder/jbuilder_cache.rb +0 -29
  418. data/lib/workarea/ext/referer_parser/parser.decorator +0 -43
  419. data/lib/workarea/queues_pauser.rb +0 -26
  420. data/lib/workarea/robots.rb +0 -9
  421. data/test/generators/workarea/docker_generator_test.rb +0 -156
  422. data/test/javascripts/fixtures/duplicate_id_pass.html.haml +0 -2
  423. data/test/lib/workarea/ext/freedom_patches/mongoid_localized_defaults_test.rb +0 -25
  424. data/test/lib/workarea/ext/referer_parser/parser_test.rb +0 -20
  425. data/test/queries/workarea/search/search_suggestions_test.rb +0 -29
  426. data/test/workers/workarea/undo_release_test.rb +0 -23
  427. data/test/workers/workarea/update_email_test.rb +0 -39
@@ -0,0 +1,55 @@
1
+ module Workarea
2
+ # Execute sidekiq jobs with query caches enabled. Each job can specify one or
3
+ # both query_caches to use via `query_cache`, `mongoid_query_cache`, or
4
+ # `elasticsearch_query_cache` options.
5
+ #
6
+ # @return [ Object ] The result of the call.
7
+ #
8
+ class QueryCacheMiddleware
9
+ def initialize(options = {})
10
+ @options = options
11
+ end
12
+
13
+ def call(worker, msg, queue)
14
+ cache_options = CacheOptions.new(worker.class.sidekiq_options)
15
+ return yield if cache_options.none?
16
+
17
+ if cache_options.all?
18
+ Mongoid::QueryCache.cache do
19
+ Elasticsearch::QueryCache.cache do
20
+ yield
21
+ end
22
+ end
23
+ elsif cache_options.mongoid?
24
+ Mongoid::QueryCache.cache { yield }
25
+ elsif cache_options.elasticsearch?
26
+ Elasticsearch::QueryCache.cache { yield }
27
+ end
28
+ ensure
29
+ Mongoid::QueryCache.clear_cache
30
+ Elasticsearch::QueryCache.clear_cache
31
+ end
32
+
33
+ class CacheOptions
34
+ def initialize(options)
35
+ @options = options
36
+ end
37
+
38
+ def none?
39
+ !mongoid? && !elasticsearch?
40
+ end
41
+
42
+ def all?
43
+ mongoid? && elasticsearch?
44
+ end
45
+
46
+ def mongoid?
47
+ !!(@options['mongoid_query_cache'] || @options['query_cache'])
48
+ end
49
+
50
+ def elasticsearch?
51
+ !!(@options['elasticsearch_query_cache'] || @options['query_cache'])
52
+ end
53
+ end
54
+ end
55
+ end
@@ -5,7 +5,7 @@ module Workarea
5
5
  end
6
6
 
7
7
  def call(worker, msg, queue)
8
- Release.with_current(nil) { yield }
8
+ Release.without_current { yield }
9
9
  end
10
10
  end
11
11
  end
@@ -14,7 +14,7 @@ module Workarea
14
14
  end
15
15
 
16
16
  def releasable?
17
- false
17
+ is_a?(Releasable)
18
18
  end
19
19
 
20
20
  private
@@ -36,15 +36,15 @@ module Workarea
36
36
  end
37
37
 
38
38
  def apply_details!(product)
39
- product.details = HashUpdate
40
- .new(original: product.details, adds: add_details, removes: remove_details)
41
- .result
39
+ HashUpdate
40
+ .new(adds: add_details, removes: remove_details)
41
+ .apply(product.details)
42
42
  end
43
43
 
44
44
  def apply_filters!(product)
45
- product.filters = HashUpdate
46
- .new(original: product.filters, adds: add_filters, removes: remove_filters)
47
- .result
45
+ HashUpdate
46
+ .new(adds: add_filters, removes: remove_filters)
47
+ .apply(product.filters)
48
48
  end
49
49
 
50
50
  def apply_pricing!(product)
@@ -1,7 +1,7 @@
1
1
  module Workarea
2
2
  module CalculatePercentChange
3
3
  def calculate_percent_change(first, second)
4
- return nil if first.zero?
4
+ return nil if first.blank? || first.zero?
5
5
  ((second.to_f - first) / first.to_f) * 100
6
6
  end
7
7
  end
@@ -23,8 +23,6 @@ module Workarea
23
23
  validates :client_id, uniqueness: true, allow_blank: true
24
24
 
25
25
  scope :recent, ->(l = 5) { order_by([:created_at, :desc]).limit(l) }
26
- scope :by_product, ->(id) { self.in(product_ids: id) }
27
-
28
26
  index({ client_id: 1 })
29
27
  end
30
28
  end
@@ -12,7 +12,6 @@ module Workarea
12
12
  field :name, type: String, localize: true
13
13
  field :filters, type: Hash, default: {}, localize: true
14
14
  field :template, type: String, default: 'generic'
15
- field :digital, type: Boolean, default: false
16
15
  field :customizations, type: String
17
16
  field :browser_title, type: String, localize: true
18
17
  field :meta_description, type: String, localize: true
@@ -21,6 +20,14 @@ module Workarea
21
20
  field :purchasable, type: Boolean, default: true
22
21
  field :default_category_id, type: String
23
22
 
23
+ # DEPRECATED. This field will be remove in v3.6 in favor of using
24
+ # Fulfillment::SKU to determine behavior in checkout for items not
25
+ # requiring phsyical fulfillment.
26
+ #
27
+ # TODO: remove in v3.6
28
+ #
29
+ field :digital, type: Boolean, default: false
30
+
24
31
  index({ 'variants.sku': 1 })
25
32
  index({ last_indexed_at: 1 })
26
33
  index({ 'images.option': 1 })
@@ -119,7 +126,17 @@ module Workarea
119
126
  end
120
127
 
121
128
  def active?
122
- super && variants.active.any?
129
+ super && active_by_relations?
130
+ end
131
+
132
+ # This hook allows plugins extending this model a place to hook into
133
+ # #active? without overriding all the logic in that method's `super`. For
134
+ # example, package products.
135
+ #
136
+ # @return [Boolean]
137
+ #
138
+ def active_by_relations?
139
+ variants.active.any?
123
140
  end
124
141
 
125
142
  # Whether to allow purchasing on this product. This is always false if
@@ -33,7 +33,16 @@ module Workarea
33
33
  end
34
34
 
35
35
  def action
36
- Workarea.config.auto_capture ? 'purchase!' : 'authorize!'
36
+ # TODO deprecated, remove in v3.6
37
+ return 'purchase!' if Workarea.config.auto_capture
38
+
39
+ if @order.items.all?(&:requires_shipping?)
40
+ Workarea.config.checkout_payment_action[:shipped]
41
+ elsif @order.items.any?(&:requires_shipping?)
42
+ Workarea.config.checkout_payment_action[:mixed]
43
+ else
44
+ Workarea.config.checkout_payment_action[:not_shipped]
45
+ end
37
46
  end
38
47
  end
39
48
  end
@@ -0,0 +1,44 @@
1
+ module Workarea
2
+ class Checkout
3
+ module Fraud
4
+ class Analyzer
5
+ attr_reader :checkout
6
+
7
+ delegate :order, :user, :payment, :payment_profile, :shipping, :shippings,
8
+ to: :checkout, allow_nil: true
9
+ delegate :fraud_suspected?, to: :order
10
+
11
+ def initialize(checkout)
12
+ @checkout = checkout
13
+ end
14
+
15
+ def decide!
16
+ begin
17
+ decision = make_decision.tap { |r| r.analyzer = self.class.name }
18
+ rescue => e
19
+ decision = error_decision(e.message)
20
+ ensure
21
+ order.set_fraud_decision!(decision)
22
+ end
23
+ end
24
+
25
+ # Gets a decision about the fraudlence of a given checkout
26
+ #
27
+ # @param [Workarea::Checkout] checkout
28
+ #
29
+ # @return [Workarea::Order::FraudDecision]
30
+ #
31
+ def make_decision(checkout = nil)
32
+ raise(NotImplementedError, "#{self.class} must implement the #make_decision method")
33
+ end
34
+
35
+ def error_decision(message)
36
+ Workarea::Order::FraudDecision.new(
37
+ decision: :no_decision,
38
+ message: "An error occured during the fraud check: #{message}"
39
+ )
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,14 @@
1
+ module Workarea
2
+ class Checkout
3
+ module Fraud
4
+ class NoDecisionAnalyzer < Analyzer
5
+ def make_decision
6
+ Workarea::Order::FraudDecision.new(
7
+ decision: :no_decision,
8
+ message: I18n.t('workarea.storefront.fraud.default_message')
9
+ )
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ module Workarea
2
+ class Checkout
3
+ module Fraud
4
+ class TestAnalyzer < Analyzer
5
+ def make_decision
6
+ if order.email == "decline@workarea.com"
7
+ Workarea::Order::FraudDecision.new(
8
+ decision: :declined,
9
+ message: "Forced test fraud decline."
10
+ )
11
+ elsif order.email == "approved@workarea.com"
12
+ Workarea::Order::FraudDecision.new(
13
+ decision: :approved,
14
+ message: "Forced test fraud approval."
15
+ )
16
+ else
17
+ Workarea::Order::FraudDecision.new(
18
+ decision: :no_decision,
19
+ message: "Workarea default fraud check. Automatic no decision."
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -158,14 +158,10 @@ module Workarea
158
158
  # Used in auto completing an order for a logged in user.
159
159
  #
160
160
  # @param [Hash] parameters for updating
161
- # @return [Boolean] whether the update was successful.
161
+ # @return [self]
162
162
  #
163
163
  def update(params = {})
164
- return true if params.blank?
165
-
166
- steps.reduce(true) do |result, step|
167
- result &= step.new(self).update(params)
168
- end
164
+ steps.each { |s| s.new(self).update(params) }
169
165
  end
170
166
 
171
167
  # Whether this checkout needs any further information
@@ -191,6 +187,9 @@ module Workarea
191
187
  return false unless shippable?
192
188
  return false unless payable?
193
189
 
190
+ fraud_analyzer.decide!
191
+ return false if fraud_analyzer.fraud_suspected?
192
+
194
193
  inventory.purchase
195
194
  return false unless inventory.captured?
196
195
 
@@ -221,6 +220,15 @@ module Workarea
221
220
  payment.valid? && payment_collection.valid?
222
221
  end
223
222
 
223
+ # Recalculate the amounts on tenders if payment is persisted.
224
+ #
225
+ # @return [Boolean, nil]
226
+ #
227
+ def adjust_tender_amounts!
228
+ return unless payment.persisted?
229
+ payment.adjust_tender_amounts(order.total_price)
230
+ end
231
+
224
232
  private
225
233
 
226
234
  def auto_complete
@@ -234,5 +242,9 @@ module Workarea
234
242
  def place_order_side_effects
235
243
  CreateFulfillment.new(order).perform
236
244
  end
245
+
246
+ def fraud_analyzer
247
+ @fraud_analyzer ||= Workarea.config.fraud_analyzer.constantize.new(self)
248
+ end
237
249
  end
238
250
  end
@@ -0,0 +1,25 @@
1
+ module Workarea
2
+ module Configuration
3
+ class Admin
4
+ include ApplicationDocument
5
+ include ::Mongoid::Encrypted
6
+
7
+ delegate :definition, to: :class
8
+
9
+ def self.instance
10
+ first || create
11
+ end
12
+
13
+ def self.definition
14
+ Workarea.config.admin_definition
15
+ end
16
+
17
+ definition.fields.each do |f|
18
+ field f.key,
19
+ type: f.type_class,
20
+ default: f.default,
21
+ encrypted: f.encrypted?
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ module Workarea
2
+ module Configuration
3
+ class Params
4
+ def initialize(params)
5
+ @params = params
6
+ end
7
+
8
+ def to_h
9
+ Admin.definition.fields.each_with_object({}) do |field, memo|
10
+ next unless @params.key?(field.key)
11
+ value = @params[field.key]
12
+
13
+ formatted_value =
14
+ if value.present? && respond_to?(field.type)
15
+ send(field.type, field, value)
16
+ else
17
+ value
18
+ end
19
+
20
+ memo[field.key] =
21
+ if formatted_value.blank? && !field.allow_blank?
22
+ field.default
23
+ else
24
+ formatted_value
25
+ end
26
+ end
27
+ end
28
+
29
+ def array(field, value)
30
+ Array.wrap(CSV.parse(value).first).map(&:strip)
31
+ end
32
+
33
+ def hash(field, value)
34
+ value.each_slice(2)
35
+ .to_h
36
+ .reject { |k, v| k.blank? || v.blank? }
37
+ .transform_values { |v| field.values_type_class.mongoize(v) }
38
+ end
39
+
40
+ def duration(field, value)
41
+ value.first.to_i.send(value.last.to_sym)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -7,6 +7,7 @@ module Workarea
7
7
 
8
8
  field :name, type: String
9
9
  field :type, type: String
10
+ field :alt_text, type: String
10
11
 
11
12
  #
12
13
  # The values for the following fields are automatically populated via
@@ -45,15 +46,6 @@ module Workarea
45
46
  after_validation :set_name
46
47
  after_validation :set_type
47
48
 
48
- # TODO v3.5 remove
49
- def self.placeholder
50
- warn <<~eos
51
- [DEPRECATION] `Asset.placeholder` is deprecated and will be removed in
52
- version 3.5.0. Please use `Asset.image_placeholder` instead.
53
- eos
54
- self.image_placeholder
55
- end
56
-
57
49
  def self.image_placeholder
58
50
  find_by(file_name: Workarea.config.image_placeholder_image_name)
59
51
 
@@ -91,17 +83,12 @@ module Workarea
91
83
  tagged_with(['favicon', type].compact.join('-'))
92
84
  end
93
85
 
94
- def favicon?
95
- tags.any? { |t| t.starts_with?('favicon') }
86
+ def self.open_graph_default
87
+ tagged_with('og-default').first
96
88
  end
97
89
 
98
- # TODO v3.5 remove
99
- def placeholder?
100
- warn <<~eos
101
- [DEPRECATION] `Asset#placeholder?` is deprecated and will be removed in
102
- version 3.5.0. Please use `Asset#image_placeholder?` instead.
103
- eos
104
- image_placeholder?
90
+ def favicon?
91
+ tags.any? { |t| t.starts_with?('favicon') }
105
92
  end
106
93
 
107
94
  def image_placeholder?
@@ -8,7 +8,7 @@ module Workarea
8
8
  # The data field is passed to the partial as local assigns.
9
9
  #
10
10
  # This flexibility makes it very easy to add a new type to the system:
11
- # 1) Define the block type using the DSL ({Workarea::Content.define_block_types})
11
+ # 1) Define the block type using the DSL ({Workarea.define_content_block_types})
12
12
  # 2) Add the storefront partial, e.g. workarea/storefront/content_blocks/types/_foo.html.haml
13
13
  #
14
14
  class Block
@@ -91,7 +91,7 @@ module Workarea
91
91
  end
92
92
 
93
93
  # The {Workarea::Content::BlockType} that this block is. See documentation
94
- # for {Content.define_block_types} for info how to define block types.
94
+ # for {Workarea.define_content_block_types} for info how to define block types.
95
95
  #
96
96
  # @return [Workarea::Content::BlockType]
97
97
  #
@@ -127,6 +127,12 @@ module Workarea
127
127
  self == siblings.select(&:active?).last
128
128
  end
129
129
 
130
+ def to_draft
131
+ result = Content::BlockDraft.instantiate(as_document.merge('content_id' => _parent.id))
132
+ result.new_record = true
133
+ result
134
+ end
135
+
130
136
  private
131
137
 
132
138
  def set_defaults
@@ -2,9 +2,12 @@ module Workarea
2
2
  class Content
3
3
  class BlockDraft
4
4
  include ApplicationDocument
5
- include Mongoid::Attributes::Dynamic
5
+ include Releasable
6
6
 
7
7
  field :content_id, type: String
8
+ Block.fields.except('_id').each do |name, field_instance|
9
+ field name, field_instance.options.except(:klass)
10
+ end
8
11
 
9
12
  index(
10
13
  { created_at: 1 },
@@ -29,7 +32,9 @@ module Workarea
29
32
  end
30
33
 
31
34
  def to_block
32
- content.blocks.build(attributes.except('content_id'))
35
+ result = Content::Block.instantiate(as_document.except('content_id'))
36
+ result.new_record = true
37
+ result
33
38
  end
34
39
  end
35
40
  end
@@ -83,7 +83,7 @@ module Workarea
83
83
 
84
84
  # Define a fieldset on the block type. The block will be evaluated in the
85
85
  # {Workarea::Content::Fieldset} to provide the DSL. See more info on the
86
- # block type DSL at {Workarea::Content.define_block_types}
86
+ # block type DSL at {Workarea.define_content_block_types}.
87
87
  #
88
88
  # @param name [String]
89
89
  # @yield evaluated in the {Workarea::Content::Fieldset} for DSL
@@ -130,7 +130,7 @@ module Workarea
130
130
  # Define a {Workarea::Content::Field} on this block type. Given that this
131
131
  # is being declared without a {Workarea::Content::Fieldset}, this will be
132
132
  # added to a default {Workarea::Content::Fieldset} called 'Settings'. See
133
- # more info on the block type DSL at {Workarea::Content.define_block_types}
133
+ # more info on the block type DSL at {Workarea.define_content_block_types}
134
134
  #
135
135
  # @param name [String]
136
136
  # @param type [Symbol] a slug version of a {Workarea::Content::Field} subclass
@@ -1,6 +1,10 @@
1
1
  module Workarea
2
2
  class Content
3
3
  class BlockTypeDefinition
4
+ def self.define(&block)
5
+ new.instance_eval(&block)
6
+ end
7
+
4
8
  def block_type(name, &block)
5
9
  block_type = BlockType.new(name)
6
10
 
@@ -54,7 +54,7 @@ module Workarea
54
54
  end
55
55
 
56
56
  # The {Workarea::Content::BlockType} that this block is. See documentation
57
- # for {Content.define_block_types} for info how to define block types.
57
+ # for {Workarea.define_content_block_types} for info how to define block types.
58
58
  #
59
59
  # @return [Workarea::Content::BlockType]
60
60
  #
@@ -8,6 +8,7 @@ module Workarea
8
8
  field :browser_title, type: String, localize: true
9
9
  field :meta_description, type: String, localize: true
10
10
  field :javascript, type: String
11
+ field :head_content, type: String
11
12
  field :css, type: String
12
13
  field :automate_metadata, type: Boolean, default: true
13
14
  field :open_graph_asset_id, type: String
@@ -57,88 +58,17 @@ module Workarea
57
58
  find_by('blocks._id' => block_id) rescue nil
58
59
  end
59
60
 
60
- # Define block types for use by administrators. A block type represents a
61
- # row of content on the storefront, self-contained with its own styles and
62
- # responsive logic.
63
- #
64
- # == Defining new block types
65
- #
66
- # Workarea::Content.define_block_types do
67
- # # Create a new block type called 2 Column Text
68
- # # The ID or slug for this type will be :2_column_text
69
- # block_type '2 Column Text' do
70
- # # Set a description, which will be shown to admin users when
71
- # # selecting a block type
72
- # description 'Provides 2 columns of text'
73
- #
74
- # # Allows custom specification of which icon to use to display this
75
- # # block type in the admin when selecting a new block. The default
76
- # # is workarea/admin/content_block_types/#{block_type_id}
77
- # icon 'workarea/admin/content_block_types/columns'
78
- #
79
- # # Tags are used for filtering content block types in the admin when
80
- # # creating a new block and selecting its type
81
- # tags %w(columns text)
82
- #
83
- # # You can also specify a custom view model to be used in the store
84
- # # front when rendering. You could even share view models for
85
- # # different blocks
86
- # view_model 'Workarea::Storefront::ContentBlocks::ColumnsViewModel'
87
- #
88
- # # If your block type requires developer-facing configuration, you
89
- # # you can specify any arbitrary attributes and they will be added
90
- # # to the #config hash on the block type. For example, configuration
91
- # # values tied to site design.
92
- # height 960
93
- # width 470
94
- #
95
- # # Use fieldset to group fields together for admin display. The
96
- # # fieldset has no other use.
97
- # fieldset 'Left Column' do
98
- # # A field corresponds to one input in the admin and one key in
99
- # # the Workarea::Content::Block#data hash. It will be referenced
100
- # # by a systemized version of the name.
101
- #
102
- # # The second argument must be a type. Out-of-the-box valid types
103
- # # include :asset, :category, :options, :products, :rich_text,
104
- # # :string, and :url.
105
- #
106
- # # Options can be specific to the field type. All field types
107
- # # support :default and :required.
108
- # field 'Left Column Text', :text, required: true, default: 'Left Column'
109
- # end
110
- #
111
- # fieldset 'Right Column' do
112
- # field 'Right Column Text', :text, required: true, default: 'Right Column'
113
- # end
114
- # end
115
- # end
116
- #
117
- # == Overriding values for existing block types
118
- #
119
- # To allow full customization, all details about a block type and its fields
120
- # can be overridden. Here's an example of overriding details on the Product
121
- # List block type which ships out of the box.
122
- #
123
- # Workarea::Content.define_block_types do
124
- # # Open the Product List block up again
125
- # block_type 'Product List' do
126
- # # Override the default on Title
127
- # field 'Title', :string, default: 'Staff Picks'
128
- # # Add a new field called description
129
- # field 'Description', :text, default: 'Top picks by our staff
130
- #
131
- # # No need to touch other fields, they remain the same
132
- # end
133
- # end
134
- #
135
- # == Admin UI
136
- # The admin UI for the block will be automatically generated based on the
137
- # fields provided.
138
- #
139
- def self.define_block_types(&block)
140
- definition = BlockTypeDefinition.new
141
- definition.instance_eval(&block)
61
+ # @deprecated Use `Workarea.define_content_block_types` instead.
62
+ class << self
63
+ def define_block_types(&block)
64
+ require_dependency 'workarea/content/block_type_definition'
65
+ definition = BlockTypeDefinition.new
66
+ definition.instance_eval(&block)
67
+ end
68
+ Workarea.deprecation.deprecate_methods(
69
+ self,
70
+ define_block_types: 'Use `Workarea.define_content_block_types` instead.'
71
+ )
142
72
  end
143
73
 
144
74
  # The name for this content, returns the name of the contentable
@@ -48,8 +48,6 @@ module Workarea
48
48
 
49
49
  def assign_attributes(model, attrs)
50
50
  model.fields.each do |name, metadata|
51
- next if name == 'updated_at'
52
-
53
51
  value = CsvFields.deserialize_from(attrs, field: metadata, model: model)
54
52
  model.send("#{name}=", value) if value.present?
55
53
  end
@@ -88,17 +86,17 @@ module Workarea
88
86
  ]
89
87
 
90
88
  if unnamespaced_attrs.values.any?(&:present?)
91
- klass = attrs["#{name}_type"].constantize if attrs["#{name}_type"].present?
92
- klass ||= root.relations[name].class_name.constantize
93
-
94
89
  if metadata.many?
95
90
  id = attrs["#{name}_id"]
96
- instance = root.send(name).find_by(id: id) rescue nil
97
- instance ||= root.send(name).build({}, klass)
91
+ instance = if id.present?
92
+ root.send(name).find_or_initialize_by(id: id)
93
+ else
94
+ root.send(name).build
95
+ end
98
96
 
99
97
  assign_attributes(instance, unnamespaced_attrs)
100
98
  else
101
- instance = root.send(name) || root.send("build_#{name}", {}, klass)
99
+ instance = root.send(name) || root.send("build_#{name}")
102
100
  assign_attributes(instance, unnamespaced_attrs)
103
101
  end
104
102
  end