workarea-registries 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE +21 -0
  5. data/README.md +1 -0
  6. data/Rakefile +58 -0
  7. data/app/assets/images/workarea/storefront/registries/icons/email.svg +4 -0
  8. data/app/assets/images/workarea/storefront/registries/icons/link.svg +1 -0
  9. data/app/assets/javascripts/workarea/storefront/registries/modules/add_to_registry_button.js +49 -0
  10. data/app/assets/javascripts/workarea/storefront/registries/modules/copy_registry_url_button.js +51 -0
  11. data/app/assets/javascripts/workarea/storefront/registries/modules/toggle_registry_address.js +58 -0
  12. data/app/assets/javascripts/workarea/storefront/registries/templates/add_to_registry_button.jst.ejs +3 -0
  13. data/app/controllers/workarea/admin/registries_controller.rb +28 -0
  14. data/app/controllers/workarea/storefront/cart_items_controller.decorator +14 -0
  15. data/app/controllers/workarea/storefront/registries_controller.rb +47 -0
  16. data/app/controllers/workarea/storefront/users/registries_controller.rb +94 -0
  17. data/app/controllers/workarea/storefront/users/registry_items_controller.rb +67 -0
  18. data/app/controllers/workarea/storefront/users/registry_shares_controller.rb +43 -0
  19. data/app/controllers/workarea/storefront/users/registry_thanks_controller.rb +41 -0
  20. data/app/helpers/workarea/registries_helper.rb +41 -0
  21. data/app/mailers/workarea/storefront/registries_mailer.rb +52 -0
  22. data/app/models/workarea/checkout/steps/addresses.decorator +28 -0
  23. data/app/models/workarea/order.decorator +7 -0
  24. data/app/models/workarea/order/item.decorator +11 -0
  25. data/app/models/workarea/registry.rb +129 -0
  26. data/app/models/workarea/registry/item.rb +39 -0
  27. data/app/models/workarea/registry/public_search.rb +23 -0
  28. data/app/models/workarea/registry/share.rb +46 -0
  29. data/app/models/workarea/registry/thank.rb +26 -0
  30. data/app/models/workarea/search/admin/registry.rb +29 -0
  31. data/app/queries/workarea/search/admin_orders.decorator +7 -0
  32. data/app/queries/workarea/search/admin_registries.rb +16 -0
  33. data/app/seeds/workarea/registry_content_seeds.rb +50 -0
  34. data/app/services/workarea/inventory_adjustment.decorator +43 -0
  35. data/app/view_models/workarea/admin/registry_view_model.rb +19 -0
  36. data/app/view_models/workarea/storefront/checkout/addresses_view_model.decorator +17 -0
  37. data/app/view_models/workarea/storefront/order_item_view_model.decorator +9 -0
  38. data/app/view_models/workarea/storefront/order_view_model.decorator +8 -0
  39. data/app/view_models/workarea/storefront/registry_email_view_model.rb +37 -0
  40. data/app/view_models/workarea/storefront/registry_item_view_model.rb +72 -0
  41. data/app/view_models/workarea/storefront/registry_share_view_model.rb +6 -0
  42. data/app/view_models/workarea/storefront/registry_thank_view_model.rb +6 -0
  43. data/app/view_models/workarea/storefront/registry_view_model.rb +74 -0
  44. data/app/view_models/workarea/storefront/user_view_model.decorator +12 -0
  45. data/app/views/workarea/admin/registries/_menu.html.haml +1 -0
  46. data/app/views/workarea/admin/registries/index.html.haml +70 -0
  47. data/app/views/workarea/storefront/carts/_registry_details.html.haml +3 -0
  48. data/app/views/workarea/storefront/checkouts/_registry_address.html.haml +13 -0
  49. data/app/views/workarea/storefront/checkouts/_registry_address_fields.html.haml +28 -0
  50. data/app/views/workarea/storefront/checkouts/_registry_details.html.haml +3 -0
  51. data/app/views/workarea/storefront/products/_add_to_registry_placeholder.html.haml +1 -0
  52. data/app/views/workarea/storefront/registries/_registries_link.html.haml +4 -0
  53. data/app/views/workarea/storefront/registries/index.html.haml +39 -0
  54. data/app/views/workarea/storefront/registries/search.html.haml +35 -0
  55. data/app/views/workarea/storefront/registries/show.html.haml +63 -0
  56. data/app/views/workarea/storefront/registries_mailer/creation.html.haml +13 -0
  57. data/app/views/workarea/storefront/registries_mailer/gift_receipt.html.haml +51 -0
  58. data/app/views/workarea/storefront/registries_mailer/share.html.haml +21 -0
  59. data/app/views/workarea/storefront/registries_mailer/thank.html.haml +19 -0
  60. data/app/views/workarea/storefront/users/_registry_count.json.jbuilder +3 -0
  61. data/app/views/workarea/storefront/users/accounts/_registries.html.haml +14 -0
  62. data/app/views/workarea/storefront/users/registries/_form.html.haml +56 -0
  63. data/app/views/workarea/storefront/users/registries/_radio_list.html.haml +8 -0
  64. data/app/views/workarea/storefront/users/registries/_summary.html.haml +12 -0
  65. data/app/views/workarea/storefront/users/registries/edit.html.haml +4 -0
  66. data/app/views/workarea/storefront/users/registries/index.html.haml +24 -0
  67. data/app/views/workarea/storefront/users/registries/new.html.haml +4 -0
  68. data/app/views/workarea/storefront/users/registries/show.html.haml +75 -0
  69. data/app/views/workarea/storefront/users/registry_items/new.html.haml +10 -0
  70. data/app/views/workarea/storefront/users/registry_items/templates/_purchased.html.haml +29 -0
  71. data/app/views/workarea/storefront/users/registry_items/templates/_unpurchased.html.haml +35 -0
  72. data/app/views/workarea/storefront/users/registry_shares/_share_buttons.html.haml +18 -0
  73. data/app/views/workarea/storefront/users/registry_shares/new.html.haml +49 -0
  74. data/app/views/workarea/storefront/users/registry_thanks/new.html.haml +47 -0
  75. data/app/workers/workarea/send_gift_receipt.rb +15 -0
  76. data/app/workers/workarea/send_registry_creation_email.rb +12 -0
  77. data/app/workers/workarea/update_registry_items.rb +24 -0
  78. data/bin/rails +20 -0
  79. data/config/initializers/appends.rb +54 -0
  80. data/config/initializers/fields.rb +19 -0
  81. data/config/locales/en.yml +133 -0
  82. data/config/routes.rb +26 -0
  83. data/lib/workarea/mailer_previews/storefront/registry_mailer_preview.rb +25 -0
  84. data/lib/workarea/registries.rb +11 -0
  85. data/lib/workarea/registries/engine.rb +17 -0
  86. data/lib/workarea/registries/version.rb +5 -0
  87. data/test/dummy/config/application.rb +27 -0
  88. data/test/factories/workarea/registry.rb +67 -0
  89. data/test/integration/workarea/storefront/cart_item_registry_integration_test.rb +104 -0
  90. data/test/integration/workarea/storefront/checkout_registry_integration_test.rb +156 -0
  91. data/test/integration/workarea/storefront/registry_privacy_integration_test.rb +48 -0
  92. data/test/integration/workarea/storefront/user_registries_integration_test.rb +50 -0
  93. data/test/integration/workarea/storefront/user_registry_items_integration_test.rb +106 -0
  94. data/test/models/workarea/registry/item_test.rb +22 -0
  95. data/test/models/workarea/registry/public_search_test.rb +48 -0
  96. data/test/models/workarea/registry_test.rb +113 -0
  97. data/test/system/workarea/admin/registry_system_test.rb +20 -0
  98. data/test/workers/update_registry_items_test.rb +45 -0
  99. data/workarea-registries.gemspec +20 -0
  100. metadata +156 -0
@@ -0,0 +1,19 @@
1
+ Workarea::Configuration.define_fields do
2
+ fieldset 'Communication', namespaced: false do
3
+ field 'Max Email Registry Share Message Length',
4
+ type: :integer,
5
+ default: 2000,
6
+ description: %(
7
+ The maximum message length (in characters) that an email share
8
+ can contain. Used in the 'Share by Email' option on registry detail pages.
9
+ ).squish
10
+
11
+ field 'Max Email Registry Thanks Message Length',
12
+ type: :integer,
13
+ default: 2000,
14
+ description: %(
15
+ The maximum message length (in characters) that an email share
16
+ can contain. Used in the 'Thank You' option on registry detail pages.
17
+ ).squish
18
+ end
19
+ end
@@ -0,0 +1,133 @@
1
+ en:
2
+ workarea:
3
+ admin:
4
+ registries:
5
+ index:
6
+ dashboard_link: Orders dashboard
7
+ page_title: Registries
8
+ title: Registries
9
+ pluralize:
10
+ one: '%{count} Registry'
11
+ other: '%{count} Registries'
12
+ errors:
13
+ messages:
14
+ registry_sku_unavailable: "Sorry, %{registry} is not asking for %{sku} anymore. It has been removed"
15
+ registry_sku_limited_quantity: "%{registry} is only asking for %{quantity} of %{sku}, your quantity has been adjusted"
16
+ storefront:
17
+ carts:
18
+ registry_item: Registry Item
19
+ checkouts:
20
+ ship_to_another_address: Ship order to specified address
21
+ ship_to_registrant: Ship order to registrant's address
22
+ email:
23
+ registries:
24
+ creation:
25
+ heading: "%{registry_name}"
26
+ subject: You have created a new registry!
27
+ share:
28
+ from_info: Click the link below to view my registry.
29
+ subject: A Message from %{from}
30
+ gift_receipt:
31
+ heading: "Gift Receipt for Order: %{order_id}"
32
+ subject: Items have been purchased for your registry.
33
+ thank:
34
+ from_info: 'has included a personal note:'
35
+ subject: Thank you from %{from}
36
+ thank_you: wants to thank you for your gift!
37
+ flash_messages:
38
+ private_registry: This registry is private.
39
+ registry_created: Your registry has been created.
40
+ registry_item_created: Item has been added to your registry.
41
+ registry_item_destroyed: Item has been removed.
42
+ registry_item_not_created: Item could not be added to your registry.
43
+ registry_item_not_destroyed: Purchased items cannot be removed from your registry.
44
+ registry_item_updated: Item has been updated.
45
+ registry_not_created: There was a problem creating your registry.
46
+ registry_updated: Registry has been updated.
47
+ registry_item_not_updated: Item failed to update.
48
+ registry_not_updated: Registry could not been updated.
49
+ registry_share_message_sent: Thanks for sharing! An email has been sent to %{recipient}.
50
+ registry_thank_message_sent: An email has been sent to %{recipient}.
51
+ registry_url_copied: Link to Registry has been Copied!
52
+ registry_url_not_copied: "Something went wrong: %{error}"
53
+ products:
54
+ add_to_registry: Add to Registry
55
+ registries:
56
+ create: Add a Registry
57
+ description: Description
58
+ edit: Edit
59
+ edit_title: Edit %{name}
60
+ email: Email
61
+ event_date: Event Date
62
+ filter: Filter
63
+ index:
64
+ create: Easily create a registry and start adding products!
65
+ create_link: Create
66
+ find: Search for a registry by name or registry number.
67
+ find_link: Find
68
+ manage: Make changes or update an existing registry
69
+ manage_link: Manage
70
+ issues:
71
+ no_items: Your registry contains no items!
72
+ nothing_to_purchase: All items on this registry have been purchased!
73
+ items: Items
74
+ name: Registry Name
75
+ name_or_email: Search by Registry Name or Email
76
+ new: Create Your Registry
77
+ none: You haven't added a registry yet.
78
+ no_event_date: No date selected.
79
+ privacy_settings: Privacy Settings
80
+ private_privacy: Private
81
+ public_privacy: Public
82
+ purchased_items: Purchased Items
83
+ registry_home: Registry Home
84
+ registry_label: "%{name}'s Registry Item"
85
+ registry_search: Registry Search
86
+ registries_link: Registries
87
+ requested: '%{quantity} requested'
88
+ shared_privacy: Shared
89
+ share: Share your Registry
90
+ shipping_address: Shipping Address
91
+ show: Show
92
+ show_title: "%{name}'s Registry"
93
+ search:
94
+ heading: Search Registries
95
+ search_title: Registry Search
96
+ title: Registries
97
+ quantity_purchased: '%{quantity} purchased'
98
+ unpurchased_items: Unpurchased Items
99
+ view: View
100
+ view_all: View all your registries
101
+ your_registries: Your Registries
102
+ registry:
103
+ item:
104
+ purchased: purchased
105
+ thank_you: Say Thanks
106
+ unpurchased: unpurchased
107
+ deletion_confirm: Are you sure?
108
+ share:
109
+ copy_link: Copy link to clipboard
110
+ email: Email
111
+ from: From
112
+ from_email_placeholder: Your Email
113
+ from_name_placeholder: Your Name
114
+ message: Message
115
+ message_placeholder: Add a personal message
116
+ name: Name
117
+ share_title: Share by Email
118
+ share_by_email: Share by Email
119
+ to: To
120
+ to_email_placeholder: Friend's Email
121
+ to_name_placeholder: Friend's Name
122
+ thank:
123
+ email: Email
124
+ from: From
125
+ from_email_placeholder: Your Email
126
+ from_name_placeholder: Your Name
127
+ message: Message
128
+ message_placeholder: Add a personal message
129
+ name: Name
130
+ thank_you_email: Say Thanks
131
+ to: To
132
+ to_email_placeholder: Friend's Email
133
+ to_name_placeholder: Friend's Name
data/config/routes.rb ADDED
@@ -0,0 +1,26 @@
1
+ Workarea::Storefront::Engine.routes.draw do
2
+ scope '(:locale)', constraints: Workarea::I18n.routes_constraint do
3
+ namespace :users do
4
+ resources :registries do
5
+
6
+ collection do
7
+ resources :items, only: [:new, :create], as: :registry_items, controller: :registry_items
8
+ resources :shares, only: [:new, :create], as: :registry_shares, controller: :registry_shares
9
+ resources :thanks, only: [:new, :create], as: :registry_thanks, controller: :registry_thanks
10
+ end
11
+
12
+ resources :items, only: [:update, :destroy], controller: :registry_items
13
+ end
14
+ end
15
+
16
+ resources :registries, only: [:show, :index]
17
+
18
+ get 'registry/search', to: 'registries#search'
19
+ end
20
+ end
21
+
22
+ Workarea::Admin::Engine.routes.draw do
23
+ scope '(:locale)', constraints: Workarea::I18n.routes_constraint do
24
+ resources :registries, only: [:index, :show]
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ module Workarea
2
+ module Storefront
3
+ class RegistriesMailerPreview < ActionMailer::Preview
4
+ def creation
5
+ registry = Registry.first
6
+ RegistriesMailer.creation(registry.id)
7
+ end
8
+
9
+ def share
10
+ share = Registry::Share.first
11
+ RegistriesMailer.share(share.id)
12
+ end
13
+
14
+ def thank
15
+ thank = Registry::Thank.first
16
+ RegistriesMailer.thank(thank.id)
17
+ end
18
+
19
+ def gift_receipt
20
+ order = Order.where(ship_to_registrant: true).first
21
+ RegistriesMailer.gift_receipt(order.id)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ require 'workarea'
2
+ require 'workarea/storefront'
3
+ require 'workarea/admin'
4
+
5
+ require 'workarea/registries/engine'
6
+ require 'workarea/registries/version'
7
+
8
+ module Workarea
9
+ module Registries
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Workarea
2
+ module Registries
3
+ class Engine < ::Rails::Engine
4
+ include Workarea::Plugin
5
+ isolate_namespace Workarea::Registries
6
+
7
+ config.to_prepare do
8
+ Workarea::ApplicationController.helper(Workarea::RegistriesHelper)
9
+ Workarea::ApplicationMailer.helper(Workarea::RegistriesHelper)
10
+
11
+ # Shouldn't be necessary, but it seems to be.
12
+ Workarea::Storefront::ApplicationController.helper(Workarea::RegistriesHelper)
13
+ Workarea::Admin::ApplicationController.helper(Workarea::RegistriesHelper)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ module Workarea
2
+ module Registries
3
+ VERSION = '1.0.0'.freeze
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'boot'
2
+
3
+ require 'action_controller/railtie'
4
+ require 'action_view/railtie'
5
+ require 'action_mailer/railtie'
6
+ require 'rails/test_unit/railtie'
7
+ require 'sprockets/railtie'
8
+ require 'teaspoon-mocha'
9
+
10
+ # Workarea must be required before other gems to ensure control over Rails.env
11
+ # for running tests
12
+ require 'workarea/core'
13
+ require 'workarea/admin'
14
+ require 'workarea/storefront'
15
+ Bundler.require(*Rails.groups)
16
+ require 'workarea/registries'
17
+
18
+ module Dummy
19
+ class Application < Rails::Application
20
+ # Initialize configuration defaults for originally generated Rails version.
21
+ config.load_defaults 5.1
22
+
23
+ # Settings in config/environments/* take precedence over those specified here.
24
+ # Application configuration should go into files in config/initializers
25
+ # -- all .rb files in that directory are automatically loaded.
26
+ end
27
+ end
@@ -0,0 +1,67 @@
1
+ module Workarea
2
+ module Factories
3
+ module Registry
4
+ Factories.add(self)
5
+
6
+ def create_registry(overrides = {})
7
+ attributes = {
8
+ name: 'Test Registry',
9
+ }.merge(overrides)
10
+
11
+ attributes[:user_id] = create_user.id if attributes[:user_id].nil?
12
+ attributes[:email] = create_user.email if attributes[:email].nil?
13
+ Workarea::Registry.create!(attributes)
14
+ end
15
+
16
+ def create_registry_item(registry: nil, **overrides)
17
+ registry ||= create_registry
18
+ attributes = { quantity: 2 }.merge(overrides)
19
+
20
+ if attributes[:product_id].nil?
21
+ product = create_product
22
+ attributes[:product_id] = product.id
23
+ attributes[:sku] = product.variants.first.sku
24
+ end
25
+
26
+ registry.items.create!(attributes)
27
+ end
28
+
29
+ def create_checkout_with_registry_item
30
+ create_tax_category(
31
+ name: 'Sales Tax',
32
+ code: '001',
33
+ rates: [{ percentage: 0.07, country: 'US', region: 'PA' }]
34
+ )
35
+
36
+ registry = create_registry
37
+
38
+ product = create_product(
39
+ variants: [{ sku: 'SKU1', regular: 6.to_m, tax_code: '001' }]
40
+ )
41
+
42
+ registry_item = create_registry_item({
43
+ registry: registry,
44
+ product_id: product.id,
45
+ sku: product.variants.first.sku,
46
+ quantity: 2
47
+ })
48
+
49
+ create_shipping_service(
50
+ carrier: 'UPS',
51
+ name: 'Ground',
52
+ service_code: '03',
53
+ tax_code: '001',
54
+ rates: [{ price: 7.to_m }]
55
+ )
56
+
57
+ post storefront.cart_items_path,
58
+ params: {
59
+ product_id: product.id,
60
+ sku: product.skus.first,
61
+ quantity: 2,
62
+ registry_id: registry.id
63
+ }
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,104 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ module Storefront
5
+ class CartItemRegistryIntegrationTest < Workarea::IntegrationTest
6
+ setup :registry, :product
7
+
8
+ def registry
9
+ @registry ||= create_registry
10
+ end
11
+
12
+ def product
13
+ @product ||= create_product(
14
+ name: 'Integration Product',
15
+ variants: [
16
+ { sku: 'SKU1', regular: 5.to_m },
17
+ { sku: 'SKU2', regular: 6.to_m }
18
+ ]
19
+ )
20
+ end
21
+
22
+ def order
23
+ Order.first
24
+ end
25
+
26
+ def test_create_item_from_registry
27
+ registry_item = create_registry_item({
28
+ registry: registry,
29
+ product_id: product.id,
30
+ sku: product.variants.first.sku
31
+ })
32
+
33
+ post storefront.cart_items_path,
34
+ params: {
35
+ product_id: registry_item.product_id,
36
+ sku: registry_item.sku,
37
+ quantity: 1,
38
+ registry_id: registry.id
39
+ }
40
+
41
+ assert(response.ok?)
42
+
43
+ order.reload
44
+ assert_equal(@product.id, order.items.first.product_id)
45
+ assert_equal(@product.skus.first, order.items.first.sku)
46
+ assert_equal(1, order.items.first.quantity)
47
+ assert_equal(5.to_m, order.items.first.total_price)
48
+ assert_equal(@registry.id.to_s, order.items.first.registry_id)
49
+ end
50
+
51
+ def test_cannot_create_more_items_than_requested
52
+ registry_item = create_registry_item({
53
+ registry: registry,
54
+ product_id: product.id,
55
+ sku: product.variants.first.sku,
56
+ received: 1
57
+ })
58
+
59
+ post storefront.cart_items_path,
60
+ params: {
61
+ product_id: registry_item.product_id,
62
+ sku: registry_item.sku,
63
+ quantity: 2,
64
+ registry_id: @registry.id
65
+ }
66
+
67
+ assert(response.ok?)
68
+
69
+ order.reload
70
+ assert_equal(@product.id, order.items.first.product_id)
71
+ assert_equal(@product.skus.first, order.items.first.sku)
72
+ assert_equal(1, order.items.first.quantity)
73
+ assert_equal(5.to_m, order.items.first.total_price)
74
+ assert_equal(@registry.id.to_s, order.items.first.registry_id)
75
+ end
76
+
77
+ def test_cannot_add_more_quantity_than_requested
78
+ registry_item = create_registry_item({
79
+ registry: registry,
80
+ product_id: product.id,
81
+ sku: product.variants.first.sku,
82
+ received: 1
83
+ })
84
+
85
+ post storefront.cart_items_path,
86
+ params: {
87
+ product_id: registry_item.product_id,
88
+ sku: registry_item.sku,
89
+ quantity: 2,
90
+ registry_id: @registry.id
91
+ }
92
+
93
+ assert(response.ok?)
94
+
95
+ order.reload
96
+ assert_equal(product.id, order.items.first.product_id)
97
+ assert_equal(product.skus.first, order.items.first.sku)
98
+ assert_equal(1, order.items.first.quantity)
99
+ assert_equal(5.to_m, order.items.first.total_price)
100
+ assert_equal(registry.id.to_s, order.items.first.registry_id)
101
+ end
102
+ end
103
+ end
104
+ end