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
@@ -7,6 +7,10 @@ module Workarea
7
7
  @order = order
8
8
  end
9
9
 
10
+ def occured_at
11
+ order.placed_at
12
+ end
13
+
10
14
  def user
11
15
  @user ||= Metrics::User.find_or_initialize_by(id: email)
12
16
  end
@@ -38,6 +42,14 @@ module Workarea
38
42
  end
39
43
  end
40
44
 
45
+ def user_data
46
+ {
47
+ email: email,
48
+ revenue: total_price,
49
+ discounts: sales_data[:discounts],
50
+ }
51
+ end
52
+
41
53
  def shipping_before_discounts
42
54
  all_price_adjustments
43
55
  .select { |pa| pa.price == 'shipping' }
@@ -85,7 +97,7 @@ module Workarea
85
97
 
86
98
  def menus
87
99
  @menus ||= categories.reduce({}) do |memo, (category_id, data)|
88
- category = category_models.detect { |c| c.id.to_s == category_id.to_s }
100
+ category = category_models[category_id]
89
101
  taxon_ids = [category&.taxon&.id, category&.taxon&.parent_ids].flatten.reject(&:blank?)
90
102
 
91
103
  Navigation::Menu.any_in(taxon_id: taxon_ids).pluck(:id).map(&:to_s).each do |menu_id|
@@ -104,8 +116,12 @@ module Workarea
104
116
  end
105
117
  end
106
118
 
119
+ def payment
120
+ @payment ||= Payment.find_or_initialize_by(id: order.id)
121
+ end
122
+
107
123
  def country
108
- Payment.find(order.id).address.country.alpha2 rescue nil
124
+ payment.address&.country&.alpha2
109
125
  end
110
126
 
111
127
  def shippings
@@ -138,6 +154,19 @@ module Workarea
138
154
  end
139
155
  end
140
156
 
157
+ def tenders
158
+ @tenders ||= payment.tenders.each_with_object({}) do |tender, data|
159
+ data[tender.slug] ||= { orders: 1, revenue: 0 }
160
+ data[tender.slug][:revenue] += tender.amount
161
+ end
162
+ end
163
+
164
+ def segments
165
+ @segments ||= order.segment_ids.each_with_object({}) do |segment_id, data|
166
+ data[segment_id] = sales_data
167
+ end
168
+ end
169
+
141
170
  private
142
171
 
143
172
  def calculate_based_on_items(items)
@@ -197,7 +226,7 @@ module Workarea
197
226
  end
198
227
 
199
228
  def category_models
200
- @category_models ||= Catalog::Category.any_in(id: categories.keys).to_a
229
+ @category_models ||= Catalog::Category.any_in(id: categories.keys).to_lookup_hash
201
230
  end
202
231
  end
203
232
  end
@@ -34,8 +34,19 @@ module Workarea
34
34
  private
35
35
 
36
36
  def categories
37
- @categories ||= @options[:categories] ||
38
- Categorization.new(@product).to_models
37
+ @categories ||=
38
+ (@options[:categories] || Categorization.new(@product).to_models)
39
+ .tap(&method(:load_taxons))
40
+ end
41
+
42
+ def load_taxons(categories)
43
+ taxons = Navigation::Taxon
44
+ .where(navigable_type: Catalog::Category.name)
45
+ .in(navigable_id: categories.map(&:id))
46
+ .map { |taxon| [taxon.navigable_id, taxon] }
47
+ .to_h
48
+
49
+ categories.each { |cat| cat.set_relation(:taxon, taxons[cat.id]) }
39
50
  end
40
51
  end
41
52
  end
@@ -0,0 +1,38 @@
1
+ module Workarea
2
+ class ProductReleases
3
+ attr_reader :product
4
+
5
+ def initialize(product)
6
+ @product = product
7
+ end
8
+
9
+ def releases
10
+ changesets
11
+ .uniq(&:release)
12
+ .reject { |cs| cs.release.blank? }
13
+ .flat_map { |cs| [cs.release] + cs.release.scheduled_after }
14
+ .uniq
15
+ end
16
+
17
+ # All {Releasable}s that could affect the product's Elasticsearch document
18
+ # should add their changesets to this method.
19
+ #
20
+ # @example Add to the changesets affecting a product in a decorator
21
+ # def changesets
22
+ # super.merge(SomeReleasable.for_product(product.id).changesets_with_children)
23
+ # end
24
+ #
25
+ # @return [Mongoid::Criteria]
26
+ #
27
+ def changesets
28
+ criteria = product.changesets_with_children
29
+ pricing_skus.each { |ps| criteria.merge!(ps.changesets_with_children) }
30
+ criteria.merge!(FeaturedProducts.changesets(product.id))
31
+ criteria.includes(:release)
32
+ end
33
+
34
+ def pricing_skus
35
+ Pricing::Sku.in(id: product.skus).to_a
36
+ end
37
+ end
38
+ end
@@ -1,12 +1,12 @@
1
1
  module Workarea
2
2
  module Recommendation
3
3
  class UserActivityBased
4
- def initialize(user_activity)
5
- @user_activity = user_activity
4
+ def initialize(metrics)
5
+ @metrics = metrics
6
6
  end
7
7
 
8
8
  def results
9
- if @user_activity.product_ids.blank? && @user_activity.category_ids.blank?
9
+ if recent_product_ids.blank? && recent_category_ids.blank?
10
10
  popular_product_ids.take(max_results)
11
11
  else
12
12
  related_product_ids.take(max_results)
@@ -18,6 +18,14 @@ module Workarea
18
18
  Workarea.config.per_page
19
19
  end
20
20
 
21
+ def recent_product_ids
22
+ @metrics.viewed.recent_product_ids(unique: true)
23
+ end
24
+
25
+ def recent_category_ids
26
+ @metrics.viewed.recent_category_ids(unique: true)
27
+ end
28
+
21
29
  def popular_product_ids
22
30
  Insights::TopProducts
23
31
  .current
@@ -28,9 +36,9 @@ module Workarea
28
36
 
29
37
  def related_product_ids
30
38
  query = Workarea::Search::RelatedProducts.new(
31
- product_ids: @user_activity.product_ids,
32
- category_ids: @user_activity.category_ids,
33
- exclude_product_ids: @user_activity.product_ids
39
+ product_ids: recent_product_ids,
40
+ category_ids: recent_category_ids,
41
+ exclude_product_ids: recent_product_ids
34
42
  )
35
43
 
36
44
  query.results.map { |r| r[:catalog_id] }
@@ -14,7 +14,7 @@ module Workarea
14
14
  def filter_date_range_and_zeroes
15
15
  {
16
16
  '$match' => {
17
- 'reporting_on' => { '$gte' => starts_at.utc, '$lte' => ends_at.utc },
17
+ 'reporting_on' => { '$gte' => starts_at, '$lte' => ends_at },
18
18
  'orders' => { '$gt' => 0 },
19
19
  'revenue' => { '$gt' => 0 }
20
20
  }
@@ -4,13 +4,14 @@ module Workarea
4
4
  include Report
5
5
 
6
6
  self.reporting_class = Metrics::User
7
- self.sort_fields = %w(revenue first_order_at last_order_at orders average_order_value)
7
+ self.sort_fields = %w(revenue refund first_order_at last_order_at orders average_order_value cancellations)
8
8
 
9
9
  def aggregation
10
- result = [add_returning]
11
- result << filter_to_returning if params[:results_filter] == 'returning'
12
- result << filter_to_one_time if params[:results_filter] == 'one_time'
13
- result + [project_fields]
10
+ [filter_orders, add_returning, filter_returning, project_fields].compact
11
+ end
12
+
13
+ def filter_orders
14
+ { '$match' => { 'orders' => { '$gt' => 0 } } }
14
15
  end
15
16
 
16
17
  def add_returning
@@ -21,12 +22,12 @@ module Workarea
21
22
  }
22
23
  end
23
24
 
24
- def filter_to_returning
25
- { '$match' => { 'returning' => true } }
26
- end
27
-
28
- def filter_to_one_time
29
- { '$match' => { 'returning' => false } }
25
+ def filter_returning
26
+ if params[:results_filter] == 'returning'
27
+ { '$match' => { 'returning' => true } }
28
+ elsif params[:results_filter] == 'one_time'
29
+ { '$match' => { 'returning' => false } }
30
+ end
30
31
  end
31
32
 
32
33
  def project_fields
@@ -36,7 +37,9 @@ module Workarea
36
37
  'first_order_at' => 1,
37
38
  'last_order_at' => 1,
38
39
  'orders' => 1,
40
+ 'cancellations' => 1,
39
41
  'revenue' => 1,
42
+ 'refund' => 1,
40
43
  'average_order_value' => { '$divide': ['$revenue', '$orders'] }
41
44
  }
42
45
  }
@@ -14,7 +14,7 @@ module Workarea
14
14
  def filter
15
15
  {
16
16
  '$match' => {
17
- 'reporting_on' => { '$gte' => starts_at.utc, '$lte' => ends_at.utc },
17
+ 'reporting_on' => { '$gte' => starts_at, '$lte' => ends_at },
18
18
  'orders' => { '$gt' => 0 }
19
19
  }
20
20
  }
@@ -25,50 +25,46 @@ module Workarea
25
25
 
26
26
  private
27
27
 
28
- def reporting_on_in_time_zone
29
- { 'date' => '$reporting_on', 'timezone' => Time.zone.tzinfo.name }
30
- end
31
-
32
28
  def day_id
33
29
  {
34
- 'year' => { '$year' => reporting_on_in_time_zone },
35
- 'month' => { '$month' => reporting_on_in_time_zone },
36
- 'day' => { '$dayOfMonth' => reporting_on_in_time_zone }
30
+ 'year' => { '$year' => '$reporting_on' },
31
+ 'month' => { '$month' => '$reporting_on' },
32
+ 'day' => { '$dayOfMonth' => '$reporting_on' }
37
33
  }
38
34
  end
39
35
 
40
36
  def week_id
41
37
  {
42
- 'year' => { '$year' => reporting_on_in_time_zone },
43
- 'week' => { '$isoWeek' => reporting_on_in_time_zone }
38
+ 'year' => { '$year' => '$reporting_on' },
39
+ 'week' => { '$isoWeek' => '$reporting_on' }
44
40
  }
45
41
  end
46
42
 
47
43
  def day_of_week_id
48
- { 'day_of_week' => { '$dayOfWeek' => reporting_on_in_time_zone } }
44
+ { 'day_of_week' => { '$dayOfWeek' => '$reporting_on' } }
49
45
  end
50
46
 
51
47
  def month_id
52
48
  {
53
- 'year' => { '$year' => reporting_on_in_time_zone },
54
- 'month' => { '$month' => reporting_on_in_time_zone }
49
+ 'year' => { '$year' => '$reporting_on' },
50
+ 'month' => { '$month' => '$reporting_on' }
55
51
  }
56
52
  end
57
53
 
58
54
  def quarter_id
59
55
  {
60
- 'year' => { '$year' => reporting_on_in_time_zone },
56
+ 'year' => { '$year' => '$reporting_on' },
61
57
  'quarter' => {
62
58
  '$cond' => [
63
- { '$lte' => [{ '$month' => reporting_on_in_time_zone }, 3] },
59
+ { '$lte' => [{ '$month' => '$reporting_on' }, 3] },
64
60
  1,
65
61
  {
66
62
  '$cond' => [
67
- { '$lte' => [{ '$month' => reporting_on_in_time_zone }, 6] },
63
+ { '$lte' => [{ '$month' => '$reporting_on' }, 6] },
68
64
  2,
69
65
  {
70
66
  '$cond' => [
71
- { '$lte' => [{ '$month' => reporting_on_in_time_zone }, 9] },
67
+ { '$lte' => [{ '$month' => '$reporting_on' }, 9] },
72
68
  3,
73
69
  4
74
70
  ]
@@ -81,7 +77,7 @@ module Workarea
81
77
  end
82
78
 
83
79
  def year_id
84
- { 'year' => { '$year' => reporting_on_in_time_zone } }
80
+ { 'year' => { '$year' => '$reporting_on' } }
85
81
  end
86
82
  end
87
83
  end
@@ -13,7 +13,7 @@ module Workarea
13
13
  def filter
14
14
  {
15
15
  '$match' => {
16
- 'reporting_on' => { '$gte' => starts_at.utc, '$lte' => ends_at.utc },
16
+ 'reporting_on' => { '$gte' => starts_at, '$lte' => ends_at },
17
17
  'orders' => { '$gt' => 0 }
18
18
  }
19
19
  }
@@ -4,7 +4,7 @@ module Workarea
4
4
  include Report
5
5
 
6
6
  self.reporting_class = Metrics::CountryByDay
7
- self.sort_fields = %w(orders units_sold merchandise discounts shipping tax revenue)
7
+ self.sort_fields = %w(orders cancellations units_sold units_canceled merchandise discounts shipping tax refund revenue)
8
8
 
9
9
  def aggregation
10
10
  [filter, project_used_fields, group_by_country]
@@ -13,10 +13,11 @@ module Workarea
13
13
  def filter
14
14
  {
15
15
  '$match' => {
16
- 'reporting_on' => { '$gte' => starts_at.utc, '$lte' => ends_at.utc },
16
+ 'reporting_on' => { '$gte' => starts_at, '$lte' => ends_at },
17
17
  '$or' => [
18
18
  { 'orders' => { '$gt' => 0 } },
19
- { 'units_sold' => { '$gt' => 0 } }
19
+ { 'units_sold' => { '$gt' => 0 } },
20
+ { 'units_canceled' => { '$gt' => 0 } }
20
21
  ]
21
22
  }
22
23
  }
@@ -27,11 +28,14 @@ module Workarea
27
28
  '$project' => {
28
29
  'country' => 1,
29
30
  'orders' => 1,
31
+ 'cancellations' => 1,
30
32
  'units_sold' => 1,
33
+ 'units_canceled' => 1,
31
34
  'merchandise' => 1,
32
35
  'shipping' => 1,
33
36
  'discounts' => 1,
34
37
  'tax' => 1,
38
+ 'refund' => 1,
35
39
  'revenue' => 1
36
40
  }
37
41
  }
@@ -42,11 +46,14 @@ module Workarea
42
46
  '$group' => {
43
47
  '_id' => '$country',
44
48
  'orders' => { '$sum' => '$orders' },
49
+ 'cancellations' => { '$sum' => '$cancellations' },
45
50
  'units_sold' => { '$sum' => '$units_sold' },
51
+ 'units_canceled' => { '$sum' => '$units_canceled' },
46
52
  'merchandise' => { '$sum' => '$merchandise' },
47
53
  'shipping' => { '$sum' => '$shipping' },
48
54
  'discounts' => { '$sum' => '$discounts' },
49
55
  'tax' => { '$sum' => '$tax' },
56
+ 'refund' => { '$sum' => '$refund' },
50
57
  'revenue' => { '$sum' => '$revenue' }
51
58
  }
52
59
  }
@@ -13,7 +13,7 @@ module Workarea
13
13
  def filter
14
14
  {
15
15
  '$match' => {
16
- 'reporting_on' => { '$gte' => starts_at.utc, '$lte' => ends_at.utc },
16
+ 'reporting_on' => { '$gte' => starts_at, '$lte' => ends_at },
17
17
  'orders' => { '$gt' => 0 }
18
18
  }
19
19
  }
@@ -13,7 +13,7 @@ module Workarea
13
13
  def filter
14
14
  {
15
15
  '$match' => {
16
- 'reporting_on' => { '$gte' => starts_at.utc, '$lte' => ends_at.utc },
16
+ 'reporting_on' => { '$gte' => starts_at, '$lte' => ends_at },
17
17
  'orders' => { '$gt' => 0 }
18
18
  }
19
19
  }
@@ -4,19 +4,20 @@ module Workarea
4
4
  include Report
5
5
 
6
6
  self.reporting_class = Metrics::ProductByDay
7
- self.sort_fields = %w(units_sold orders merchandise discounts tax revenue)
7
+ self.sort_fields = %w(units_sold units_canceled orders average_price merchandise discounts tax refund revenue)
8
8
 
9
9
  def aggregation
10
- [filter, project_used_fields, group_by_product]
10
+ [filter, project_used_fields, group_by_product, add_average_price]
11
11
  end
12
12
 
13
13
  def filter
14
14
  {
15
15
  '$match' => {
16
- 'reporting_on' => { '$gte' => starts_at.utc, '$lte' => ends_at.utc },
16
+ 'reporting_on' => { '$gte' => starts_at, '$lte' => ends_at },
17
17
  '$or' => [
18
18
  { 'orders' => { '$gt' => 0 } },
19
- { 'units_sold' => { '$gt' => 0 } }
19
+ { 'units_sold' => { '$gt' => 0 } },
20
+ { 'units_canceled' => { '$gt' => 0 } }
20
21
  ]
21
22
  }
22
23
  }
@@ -28,9 +29,11 @@ module Workarea
28
29
  'product_id' => 1,
29
30
  'orders' => 1,
30
31
  'units_sold' => 1,
32
+ 'units_canceled' => 1,
31
33
  'merchandise' => 1,
32
34
  'discounts' => 1,
33
35
  'tax' => 1,
36
+ 'refund' => 1,
34
37
  'revenue' => 1
35
38
  }
36
39
  }
@@ -42,13 +45,45 @@ module Workarea
42
45
  '_id' => '$product_id',
43
46
  'orders' => { '$sum' => '$orders' },
44
47
  'units_sold' => { '$sum' => '$units_sold' },
48
+ 'units_canceled' => { '$sum' => '$units_canceled' },
45
49
  'merchandise' => { '$sum' => '$merchandise' },
46
50
  'discounts' => { '$sum' => '$discounts' },
47
51
  'tax' => { '$sum' => '$tax' },
52
+ 'refund' => { '$sum' => '$refund' },
48
53
  'revenue' => { '$sum' => '$revenue' }
49
54
  }
50
55
  }
51
56
  end
57
+
58
+ def add_average_price
59
+ {
60
+ '$addFields' => {
61
+ 'average_price' => {
62
+ '$cond' => {
63
+ 'if' => { '$lt' => ['$units_sold', 1] },
64
+ 'then' => 0,
65
+ 'else' => {
66
+ '$divide' => [
67
+ {
68
+ '$trunc' => {
69
+ '$multiply' => [
70
+ { '$divide' => [
71
+ { '$sum' => ['$merchandise', '$discounts'] },
72
+ '$units_sold'
73
+ ]
74
+ },
75
+ 100
76
+ ]
77
+ }
78
+ },
79
+ 100
80
+ ]
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ end
52
87
  end
53
88
  end
54
89
  end
@@ -4,23 +4,24 @@ module Workarea
4
4
  include Report
5
5
 
6
6
  self.reporting_class = Metrics::SkuByDay
7
- self.sort_fields = %w(units_sold orders merchandise discounts tax revenue _id)
7
+ self.sort_fields = %w(units_sold units_canceled orders merchandise discounts tax refund revenue _id average_price)
8
8
 
9
9
  def skus
10
10
  Array.wrap(params[:skus])
11
11
  end
12
12
 
13
13
  def aggregation
14
- [filter, project_used_fields, group_by_sku]
14
+ [filter, project_used_fields, group_by_sku, add_average_price]
15
15
  end
16
16
 
17
17
  def filter
18
18
  result = {
19
19
  '$match' => {
20
- 'reporting_on' => { '$gte' => starts_at.utc, '$lte' => ends_at.utc },
20
+ 'reporting_on' => { '$gte' => starts_at, '$lte' => ends_at },
21
21
  '$or' => [
22
22
  { 'orders' => { '$gt' => 0 } },
23
- { 'units_sold' => { '$gt' => 0 } }
23
+ { 'units_sold' => { '$gt' => 0 } },
24
+ { 'units_canceled' => { '$gt' => 0 } }
24
25
  ]
25
26
  }
26
27
  }
@@ -35,9 +36,11 @@ module Workarea
35
36
  'sku' => 1,
36
37
  'orders' => 1,
37
38
  'units_sold' => 1,
39
+ 'units_canceled' => 1,
38
40
  'merchandise' => 1,
39
41
  'discounts' => 1,
40
42
  'tax' => 1,
43
+ 'refund' => 1,
41
44
  'revenue' => 1
42
45
  }
43
46
  }
@@ -49,13 +52,45 @@ module Workarea
49
52
  '_id' => '$sku',
50
53
  'orders' => { '$sum' => '$orders' },
51
54
  'units_sold' => { '$sum' => '$units_sold' },
55
+ 'units_canceled' => { '$sum' => '$units_canceled' },
52
56
  'merchandise' => { '$sum' => '$merchandise' },
53
57
  'discounts' => { '$sum' => '$discounts' },
54
58
  'tax' => { '$sum' => '$tax' },
59
+ 'refund' => { '$sum' => '$refund' },
55
60
  'revenue' => { '$sum' => '$revenue' }
56
61
  }
57
62
  }
58
63
  end
64
+
65
+ def add_average_price
66
+ {
67
+ '$addFields' => {
68
+ 'average_price' => {
69
+ '$cond' => {
70
+ 'if' => { '$lt' => ['$units_sold', 1] },
71
+ 'then' => 0,
72
+ 'else' => {
73
+ '$divide' => [
74
+ {
75
+ '$trunc' => {
76
+ '$multiply' => [
77
+ { '$divide' => [
78
+ { '$sum' => ['$merchandise', '$discounts'] },
79
+ '$units_sold'
80
+ ]
81
+ },
82
+ 100
83
+ ]
84
+ }
85
+ },
86
+ 100
87
+ ]
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ end
59
94
  end
60
95
  end
61
96
  end
@@ -0,0 +1,42 @@
1
+ module Workarea
2
+ module Reports
3
+ class SalesByTender
4
+ include Report
5
+
6
+ self.reporting_class = Metrics::TenderByDay
7
+ self.sort_fields = %w(orders revenue)
8
+
9
+ def aggregation
10
+ [filter_date_range, project_used_fields, group_by_country]
11
+ end
12
+
13
+ def filter_date_range
14
+ {
15
+ '$match' => {
16
+ 'reporting_on' => { '$gte' => starts_at, '$lte' => ends_at }
17
+ }
18
+ }
19
+ end
20
+
21
+ def project_used_fields
22
+ {
23
+ '$project' => {
24
+ 'tender' => 1,
25
+ 'orders' => 1,
26
+ 'revenue' => 1
27
+ }
28
+ }
29
+ end
30
+
31
+ def group_by_country
32
+ {
33
+ '$group' => {
34
+ '_id' => '$tender',
35
+ 'orders' => { '$sum' => '$orders' },
36
+ 'revenue' => { '$sum' => '$revenue' }
37
+ }
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -23,7 +23,7 @@ module Workarea
23
23
  def filter
24
24
  {
25
25
  '$match' => {
26
- 'reporting_on' => { '$gte' => starts_at.utc, '$lte' => ends_at.utc },
26
+ 'reporting_on' => { '$gte' => starts_at, '$lte' => ends_at },
27
27
  'orders' => { '$gt' => 0 }
28
28
  }
29
29
  }