workarea-registries 1.0.1 → 1.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e5ab7f95e20ba90a464ec73c765ab167e8e72b6
4
- data.tar.gz: d4593a5909ddfa50c3b6b0b5ce28d8f484a2feb2
3
+ metadata.gz: 8f6da4e142c2c5b40a90b36ec6ac4d3697413c0c
4
+ data.tar.gz: 0f9cecbaca22c4b850e237780098078f85770253
5
5
  SHA512:
6
- metadata.gz: 867dfe500ce0ab7417b7630017dec70fbe3ed9af04f01634df609b344b3534da5223af412dce8d493e74f2b3004acf4062ff1286b81b801e9139ce53dddbb7b8
7
- data.tar.gz: f97bbd88043e4a6b913d323057b6037559da645815cf0d5eb9d5df93b944ab6003a997902a7fd2b250aaa7731514dc80024cca2108567dcd33fc05f23a45bb26
6
+ metadata.gz: 9d21cfd7a35ec95c5020094191d6d1793245ed75a683a05e6b6e01e7e0e2cec7589b4217287b58da7ffb2118307b7a570b8cbff8659563a1d30ee8f91fd7ad73
7
+ data.tar.gz: 42fe304c3e83d60b2e57ba696c88b5a78120faf934edf2cc7f3739ab2f86b966f7802e2a2b31a19ad89d4bb23079eeedfa772f41815f0e71d69fb8ed92133b27
@@ -0,0 +1,33 @@
1
+ module Workarea
2
+ decorate Admin::ReportsController, with: :registries do
3
+ def active_registries
4
+ page_number = params[:page] || 1
5
+
6
+ active_registries = Registry
7
+ .with_items
8
+ .page(page_number)
9
+ .per(Workarea.config.per_page)
10
+ .order_by(created_at: :desc)
11
+
12
+ @active_registries = PagedArray.from(
13
+ Admin::ActiveRegistryViewModel.wrap(active_registries),
14
+ page_number,
15
+ Workarea.config.per_page,
16
+ active_registries.total_count
17
+ )
18
+ end
19
+
20
+ def export_active_registries
21
+ emails = params[:emails].to_s.split(',').map(&:strip)
22
+
23
+ if emails.any?
24
+ Admin::ActiveRegistriesMailer.report(emails).deliver_later
25
+ flash[:success] = t('workarea.admin.reports.flash_messages.success')
26
+ else
27
+ flash[:error] = t('workarea.admin.report.flash_messages.email_is_required')
28
+ end
29
+
30
+ redirect_to active_registries_report_path
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ module Workarea
2
+ module Admin
3
+ class ActiveRegistriesMailer < Admin::ApplicationMailer
4
+ def report(emails)
5
+ report = ActiveRegistriesReport.new
6
+ report.generate
7
+ attachments['report.csv'] = File.read(report.file_path)
8
+ mail(
9
+ to: emails,
10
+ from: Workarea.config.email_from,
11
+ subject: t('workarea.admin.active_registries_mailer.report.subject'),
12
+ )
13
+ end
14
+ end
15
+ end
16
+ end
@@ -24,6 +24,7 @@ module Workarea
24
24
  validates :privacy, presence: true,
25
25
  inclusion: { in: %w(public shared private) }
26
26
 
27
+ scope :with_items, -> { where('items.0' => { '$exists' => true }) }
27
28
  scope :for_user, ->(user_id) { where(user_id: user_id.to_s) }
28
29
  scope :by_activity, -> { order(updated_at: :desc) }
29
30
 
@@ -53,6 +54,14 @@ module Workarea
53
54
  items.select(&:purchased_by?)
54
55
  end
55
56
 
57
+ def total_purchased_items
58
+ purchased_items.pluck('quantity').sum
59
+ end
60
+
61
+ def total_price
62
+ purchased_items.map{ |item| item.total_price }.sum
63
+ end
64
+
56
65
  def unpurchased_items
57
66
  items.reject(&:purchased_by?)
58
67
  end
@@ -61,6 +70,18 @@ module Workarea
61
70
  items.reject(&:purchased_by?).select(&:available?)
62
71
  end
63
72
 
73
+ def total_items
74
+ unpurchased_items.pluck('quantity').sum
75
+ end
76
+
77
+ def total_items_received
78
+ unpurchased_items.pluck('received').sum
79
+ end
80
+
81
+ def total_products
82
+ unpurchased_items.size
83
+ end
84
+
64
85
  def add_item(params)
65
86
  quantity = params.fetch(:quantity, 1).to_i
66
87
  existing_item = find_existing_item(sku: params[:sku])
@@ -82,7 +103,8 @@ module Workarea
82
103
 
83
104
  if existing_purchased_item
84
105
  quantity = existing_purchased_item.quantity + params[:quantity]
85
- existing_purchased_item.update(quantity: quantity)
106
+ total_price = existing_purchased_item.total_price + params[:total_price]
107
+ existing_purchased_item.update(quantity: quantity, total_price: total_price)
86
108
  else
87
109
  items.build(params)
88
110
  end
@@ -8,6 +8,7 @@ module Workarea
8
8
  field :quantity, type: Integer, default: 1
9
9
  field :received, type: Integer, default: 0
10
10
  field :purchased_by, type: String
11
+ field :total_price, type: Money, default: 0.to_m
11
12
 
12
13
  embedded_in :registry,
13
14
  class_name: 'Workarea::Registry',
@@ -23,6 +24,10 @@ module Workarea
23
24
  quantity > received
24
25
  end
25
26
 
27
+ def unavailable?
28
+ !available?
29
+ end
30
+
26
31
  def received?
27
32
  received.positive?
28
33
  end
@@ -0,0 +1,43 @@
1
+ module Workarea
2
+ class ActiveRegistriesReport
3
+ include ActionView::Helpers::NumberHelper
4
+ attr_reader :file_path
5
+
6
+ def initialize
7
+ @file_path = "#{Rails.root}/tmp/active_registries/report.csv"
8
+ end
9
+
10
+ def generate
11
+ dir_path = File.dirname(file_path)
12
+ FileUtils.mkdir_p dir_path unless File.directory?(dir_path)
13
+ CSV.open(file_path, 'w') do |csv|
14
+ csv << [
15
+ 'Name',
16
+ 'Email',
17
+ 'Products',
18
+ 'Items',
19
+ 'Purchased Items',
20
+ 'Total Price',
21
+ ]
22
+ populate_csv(csv)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def populate_csv(csv)
29
+ Registry.with_items.order_by(created_at: :desc).each_by(100) do |registry|
30
+ registry = Admin::ActiveRegistryViewModel.new(registry)
31
+
32
+ csv << [
33
+ registry.name,
34
+ registry.email,
35
+ registry.total_products,
36
+ registry.total_items,
37
+ registry.total_purchased_items,
38
+ number_to_currency(registry.total_price)
39
+ ]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,19 @@
1
+ module Workarea
2
+ module Admin
3
+ class ActiveRegistryViewModel < ApplicationViewModel
4
+ def total_price
5
+ @total_price ||= begin
6
+ purchased_items.map{ |item| item.total_price }.sum
7
+ end
8
+ end
9
+
10
+ def unpurchased_items
11
+ @unpurchased_items ||= items.reject(&:purchased_by?)
12
+ end
13
+
14
+ def purchased_items
15
+ @purchased_items ||= items.select(&:purchased_by?)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ module Workarea
2
+ decorate Admin::Dashboards::ReportsViewModel, with: :registries do
3
+ def active_registries
4
+ @active_registries ||= Registry.order_by(created_at: :desc)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ %p="Please download the CSV attachment"
@@ -0,0 +1,16 @@
1
+ .grid__cell
2
+ .card{ class: card_classes(:active_wish_lists_report, local_assigns[:active]) }
3
+ = link_to active_wish_lists_report_path, class: 'card__header' do
4
+ %span.card__header-text= t('workarea.admin.report.active_registries.title')
5
+ = inline_svg 'workarea/admin/icons/insights.svg', class: 'card__icon'
6
+
7
+ .card__body
8
+ .card__centered-content
9
+ %table
10
+ %tbody
11
+ - @dashboard.active_registries.limit(4).each do |registry|
12
+ %tr
13
+ %td= local_time_ago(registry.created_at)
14
+
15
+ = link_to active_registries_report_path, class: 'card__button' do
16
+ %span.button.button--small= t('workarea.admin.dashboards.reports.view_full_report')
@@ -46,6 +46,8 @@
46
46
  %th= t('workarea.admin.fields.name')
47
47
  %th= t('workarea.admin.fields.user_id')
48
48
  %th= t('workarea.admin.fields.items')
49
+ %th= t('workarea.admin.fields.purchased_items')
50
+ %th= t('workarea.admin.fields.total_price')
49
51
  %tbody
50
52
  - @search.results.each do |result|
51
53
  %tr.index-table__row
@@ -59,7 +61,9 @@
59
61
  = result.user_id
60
62
  - else
61
63
  = link_to result.user.name, user_path(result.user)
62
- %td= result.items.size
64
+ %td= result.total_items
65
+ %td= result.total_purchased_items
66
+ %td= number_to_currency(result.total_price)
63
67
 
64
68
  - if @search.results.total_pages > 1
65
69
  = render 'workarea/admin/shared/pagination', collection: @search.results
@@ -67,4 +71,4 @@
67
71
  .workflow-bar
68
72
  .grid
69
73
  .grid__cell.grid__cell--50
70
- = render 'workarea/admin/shared/bulk_actions', klass: Workarea::Registry, search: @search, bulk_delete: false
74
+ = render 'workarea/admin/shared/bulk_actions', klass: Workarea::Registry, search: @search, bulk_delete: false
@@ -0,0 +1,46 @@
1
+ - @page_title = t('workarea.admin.report.active_registries.title')
2
+
3
+ .view
4
+ .view__header
5
+ .grid
6
+ .grid__cell.grid__cell--25
7
+ .grid__cell.grid__cell--50
8
+ .view__heading
9
+ = link_to "↑ #{t('workarea.admin.reports.all_reports')}", reports_dashboards_path
10
+ %h1.heading.heading--no-margin= t('workarea.admin.report.active_registries.title')
11
+ .grid__cell.grid__cell--25.grid--right
12
+ = link_to(t('workarea.admin.report.export'), '#export', data: { tooltip: { interactive: true, side: 'bottom' } })
13
+ = form_tag export_active_registries_report_path, method: 'post', id: 'export', class: 'tooltip-content align-center' do
14
+ %h2= t('workarea.admin.reports.export.where_will_the_file_go')
15
+ .property
16
+ = email_field_tag 'emails', params[:emails] || current_user.email, class: 'text-box text-box--wide', required: true, placeholder: t('workarea.admin.reports.export.enter_email'), multiple: true
17
+ %span.property__note
18
+ = t('workarea.admin.reports.export.emails_note')
19
+ = button_tag t('workarea.admin.reports.export.start_export'), value: 'create_export', class: 'button button--inline'
20
+
21
+ .view__container
22
+ %table
23
+ %thead
24
+ %tr
25
+ %th= t('workarea.admin.fields.name')
26
+ %th= t('workarea.admin.fields.user')
27
+ %th= t('workarea.admin.fields.products')
28
+ %th= t('workarea.admin.fields.items')
29
+ %th= t('workarea.admin.fields.purchased_items')
30
+ %th= t('workarea.admin.fields.total_price')
31
+ %th= t('workarea.admin.fields.updated_at')
32
+ %th= t('workarea.admin.fields.created_at')
33
+ %tbody
34
+ - @active_registries.each do |registry|
35
+ %tr
36
+ %td= registry.name
37
+ %td= registry.email
38
+ %td= registry.total_products
39
+ %td= registry.total_items
40
+ %td= registry.total_purchased_items
41
+ %td= number_to_currency(registry.total_price)
42
+ %td= local_time_ago(registry.updated_at)
43
+ %td= local_time_ago(registry.created_at)
44
+
45
+ - if @active_registries.total_pages > 1
46
+ = render 'workarea/admin/shared/pagination', collection: @active_registries
@@ -0,0 +1 @@
1
+ %li{ class: "primary-nav__item" }= link_to t('workarea.admin.shared.primary_nav.active_registries'), active_registries_report_path, class: navigation_link_classes(active_registries_report_path)
@@ -6,14 +6,11 @@
6
6
  %tr
7
7
  %td
8
8
  %h1= @content
9
- %p
10
- %strong= @thank.from
11
- %p= t('workarea.storefront.email.thank.thank_you')
9
+ %p= t('workarea.storefront.email.registries.thank.thank_you', registry_owner: @thank.friendly_from )
12
10
 
13
11
  - if @thank.message.present?
14
- %p
15
- %strong #{@thank.from} #{t('workarea.storefront.email.thank.from_message_html')}
16
- %p= @thank.message
12
+ %p
13
+ %i= @thank.message
17
14
 
18
15
 
19
16
  = append_partials('storefront.registry_thank_mailer.bottom')
@@ -56,13 +56,21 @@
56
56
 
57
57
  %h2= t('workarea.storefront.registries.items')
58
58
 
59
- .browsing-controls
60
- = form_tag users_registry_path, method: 'get', class: 'browsing-controls__form' do
61
- %p.browsing-controls__form-item.property
62
- = label_tag :state, nil, class: 'property__name' do
63
- %span.property__text= t('workarea.storefront.registries.filter')
64
- %span.value= select_tag :state, options_for_select(@registry.state_options, params[:state]), data: { form_submitting_control: '' }
65
- %p.browsing-controls__form-item.hidden-if-js-enabled= button_tag t('workarea.storefront.forms.go'), class: 'button'
59
+ .grid.grid--auto.grid--middle
60
+ - if @registry.purchased_items.any?
61
+ .grid__cell
62
+ .browsing-controls
63
+ = form_tag users_registry_path, method: 'get', class: 'browsing-controls__form' do
64
+ %p.browsing-controls__form-item.property
65
+ = label_tag :state, nil, class: 'property__name' do
66
+ %span.property__text= t('workarea.storefront.registries.filter')
67
+ %span.value= select_tag :state, options_for_select(@registry.state_options, params[:state]), data: { form_submitting_control: '' }
68
+ %p.browsing-controls__form-item.hidden-if-js-enabled= button_tag t('workarea.storefront.forms.go'), class: 'button'
69
+ - if @registry.unpurchased_items.any?
70
+ .grid__cell
71
+ = t('workarea.storefront.registries.total_products', count: @registry.total_products)
72
+ |
73
+ = t('workarea.storefront.registries.total_items_received', count: @registry.total_items_received)
66
74
 
67
75
  .grid
68
76
  .grid__cell
@@ -9,15 +9,18 @@ module Workarea
9
9
  order = Order.find(order_id)
10
10
 
11
11
  order.items.each do |item|
12
- next unless item.registry_id.present?
12
+ next unless item.registry_item?
13
13
  registry = Workarea::Registry.find(item.registry_id)
14
14
  registry.mark_item_received(item)
15
- registry.add_purchased_item({
16
- sku: item.sku,
17
- product_id: item.product_id,
18
- quantity: item.quantity,
19
- purchased_by: order.email
20
- })
15
+ registry.add_purchased_item(
16
+ {
17
+ sku: item.sku,
18
+ product_id: item.product_id,
19
+ quantity: item.quantity,
20
+ purchased_by: order.email,
21
+ total_price: item.total_price
22
+ }
23
+ )
21
24
  end
22
25
  end
23
26
  end
@@ -1,3 +1,13 @@
1
+ Workarea.append_partials(
2
+ 'admin.reports_menu',
3
+ 'workarea/admin/shared/primary_nav/active_registries_report_link',
4
+ )
5
+
6
+ Workarea.append_partials(
7
+ 'admin.reports_dashboard',
8
+ 'workarea/admin/dashboards/active_registries_report_card',
9
+ )
10
+
1
11
  Workarea.append_partials(
2
12
  'admin.orders_menu',
3
13
  'workarea/admin/registries/menu'
@@ -1,6 +1,14 @@
1
1
  en:
2
2
  workarea:
3
3
  admin:
4
+ registries:
5
+ fields:
6
+ email: email
7
+ items: Items
8
+ name: Name
9
+ products: Products
10
+ purchased_items: Items Sold
11
+ total_price: Total Price
4
12
  registries:
5
13
  index:
6
14
  dashboard_link: Orders dashboard
@@ -9,6 +17,15 @@ en:
9
17
  pluralize:
10
18
  one: '%{count} Registry'
11
19
  other: '%{count} Registries'
20
+ report:
21
+ active_registries:
22
+ title: Active Registries
23
+ flash_messages:
24
+ email_is_required: Email is required
25
+ shared:
26
+ primary_nav:
27
+ active_registries: Active Registries
28
+ registries: Registries
12
29
  errors:
13
30
  messages:
14
31
  registry_sku_unavailable: "Sorry, %{registry} is not asking for %{sku} anymore. It has been removed"
@@ -33,7 +50,7 @@ en:
33
50
  thank:
34
51
  from_info: 'has included a personal note:'
35
52
  subject: Thank you from %{from}
36
- thank_you: wants to thank you for your gift!
53
+ thank_you: '%{registry_owner} wants to thank you for your gift!'
37
54
  flash_messages:
38
55
  private_registry: This registry is private.
39
56
  registry_created: Your registry has been created.
@@ -94,6 +111,15 @@ en:
94
111
  heading: Search Registries
95
112
  search_title: Registry Search
96
113
  title: Registries
114
+ total_items:
115
+ one: '%{count} Item'
116
+ other: '%{count} Items'
117
+ total_items_received:
118
+ one: '%{count} Item Purchased'
119
+ other: '%{count} Items Purchased'
120
+ total_products:
121
+ one: '%{count} Product'
122
+ other: '%{count} Products'
97
123
  quantity_purchased: '%{quantity} purchased'
98
124
  unpurchased_items: Unpurchased Items
99
125
  view: View
data/config/routes.rb CHANGED
@@ -22,5 +22,10 @@ end
22
22
  Workarea::Admin::Engine.routes.draw do
23
23
  scope '(:locale)', constraints: Workarea::I18n.routes_constraint do
24
24
  resources :registries, only: [:index, :show]
25
+
26
+ resource :report do
27
+ get :active_registries
28
+ post :export_active_registries
29
+ end
25
30
  end
26
31
  end
@@ -1,5 +1,5 @@
1
1
  module Workarea
2
2
  module Registries
3
- VERSION = '1.0.1'.freeze
3
+ VERSION = '1.1.0'.freeze
4
4
  end
5
5
  end
@@ -29,7 +29,14 @@ module Workarea
29
29
  def test_perform
30
30
  user = create_user
31
31
  order = create_order(email: user.email, user_id: user.id)
32
- order.items.build(product_id: product.id, sku: product.variants.first.sku, quantity: 1, registry_id: registry.id)
32
+ item_price = Workarea::Pricing::Sku.find('SKU1').regular_price
33
+ order.items.build(
34
+ product_id: product.id,
35
+ sku: product.variants.first.sku,
36
+ quantity: 1,
37
+ registry_id: registry.id,
38
+ total_price: item_price
39
+ )
33
40
  order.save!
34
41
 
35
42
  UpdateRegistryItems.new.perform(order.id)
@@ -40,6 +47,7 @@ module Workarea
40
47
  assert_equal(1, registry.items.first.received)
41
48
  assert(registry.items.first.received?)
42
49
  assert(registry.items.last.purchased?)
50
+ assert_equal(500, registry.items.last.total_price.cents)
43
51
  end
44
52
  end
45
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workarea-registries
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jurgen Hahn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-16 00:00:00.000000000 Z
11
+ date: 2021-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: workarea
@@ -43,6 +43,7 @@ files:
43
43
  - app/assets/javascripts/workarea/storefront/registries/modules/toggle_registry_address.js
44
44
  - app/assets/javascripts/workarea/storefront/registries/templates/add_to_registry_button.jst.ejs
45
45
  - app/controllers/workarea/admin/registries_controller.rb
46
+ - app/controllers/workarea/admin/reports_controller.decorator
46
47
  - app/controllers/workarea/storefront/cart_items_controller.decorator
47
48
  - app/controllers/workarea/storefront/registries_controller.rb
48
49
  - app/controllers/workarea/storefront/users/registries_controller.rb
@@ -50,6 +51,7 @@ files:
50
51
  - app/controllers/workarea/storefront/users/registry_shares_controller.rb
51
52
  - app/controllers/workarea/storefront/users/registry_thanks_controller.rb
52
53
  - app/helpers/workarea/registries_helper.rb
54
+ - app/mailers/workarea/admin/active_registries_mailer.rb
53
55
  - app/mailers/workarea/storefront/registries_mailer.rb
54
56
  - app/models/workarea/checkout/steps/addresses.decorator
55
57
  - app/models/workarea/order.decorator
@@ -64,6 +66,9 @@ files:
64
66
  - app/queries/workarea/search/admin_registries.rb
65
67
  - app/seeds/workarea/registry_content_seeds.rb
66
68
  - app/services/workarea/inventory_adjustment.decorator
69
+ - app/services/workarea/registries/active_registries_report.rb
70
+ - app/view_models/workarea/admin/active_registry_view_model.rb
71
+ - app/view_models/workarea/admin/dashboards/reports_view_model.decorator
67
72
  - app/view_models/workarea/admin/registry_view_model.rb
68
73
  - app/view_models/workarea/storefront/checkout/addresses_view_model.decorator
69
74
  - app/view_models/workarea/storefront/order_item_view_model.decorator
@@ -74,8 +79,12 @@ files:
74
79
  - app/view_models/workarea/storefront/registry_thank_view_model.rb
75
80
  - app/view_models/workarea/storefront/registry_view_model.rb
76
81
  - app/view_models/workarea/storefront/user_view_model.decorator
82
+ - app/views/workarea/admin/active_registries_mailer/report.html.haml
83
+ - app/views/workarea/admin/dashboards/_active_registries_report_card.html.haml
77
84
  - app/views/workarea/admin/registries/_menu.html.haml
78
85
  - app/views/workarea/admin/registries/index.html.haml
86
+ - app/views/workarea/admin/reports/active_registries.html.haml
87
+ - app/views/workarea/admin/shared/primary_nav/_active_registries_report_link.html.haml
79
88
  - app/views/workarea/storefront/carts/_registry_details.html.haml
80
89
  - app/views/workarea/storefront/checkouts/_registry_address.html.haml
81
90
  - app/views/workarea/storefront/checkouts/_registry_address_fields.html.haml