Skip to content

Instantly share code, notes, and snippets.

@geermc4
Last active June 5, 2019 22:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save geermc4/5216258 to your computer and use it in GitHub Desktop.
Save geermc4/5216258 to your computer and use it in GitHub Desktop.
commit 6e4a11335be2f2604c540e3ab5e2655d7392d133
Author: germanc4 <german@3drobotics.com>
Date: Wed Jul 18 14:46:57 2012 -0700
Adding in stock request, fixes #8
diff --git a/Gemfile b/Gemfile
index af25ab4..13ce726 100644
--- a/Gemfile
+++ b/Gemfile
@@ -37,9 +37,9 @@ gem 'capistrano'
# To use debugger
#gem 'ruby-debug'
-gem 'spree'
-gem 'spree_usa_epay'
-gem 'spree_skrill'
+gem 'spree', '~> 1.1.1'
+gem 'spree_usa_epay', '~> 1.0.2'
+gem 'spree_skrill', '~> 1.0.2'
gem 'spree_product_assembly', :git => 'https://github.com/spree/spree-product-assembly.git', :branch => '1-0-stable'
gem 'deface', :git => 'https://github.com/railsdog/deface.git', :branch => 'dsl'
@@ -50,3 +50,7 @@ gem 'spree_redirects', :git => 'git://github.com/citrus/spree_redirects.git'
gem 'spree_reviews_rating', '~> 1.0.1'
gem 'formtastic'
+
+gem 'fancybox-rails'
+
+gem 'valid_email', :require => 'valid_email/email_validator'
diff --git a/Gemfile.lock b/Gemfile.lock
index 69417fd..b2a6159 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -72,8 +72,9 @@ GEM
i18n (~> 0.6)
multi_json (~> 1.0)
acts_as_list (0.1.4)
- akami (1.0.0)
+ akami (1.1.0)
gyoku (>= 0.4.0)
+ nokogiri (>= 1.5.2)
arel (3.0.2)
aws-sdk (1.3.9)
httparty (~> 0.7)
@@ -107,6 +108,8 @@ GEM
erubis (2.7.0)
execjs (1.4.0)
multi_json (~> 1.0)
+ fancybox-rails (0.1.4)
+ railties (>= 3.1.0)
ffaker (1.12.1)
formtastic (2.2.1)
actionpack (>= 3.0)
@@ -117,10 +120,10 @@ GEM
httparty (0.8.3)
multi_json (~> 1.0)
multi_xml
- httpi (0.9.7)
+ httpi (1.0.0)
rack
i18n (0.6.0)
- journey (1.0.3)
+ journey (1.0.4)
jquery-rails (2.0.2)
railties (>= 3.2.0, < 5.0)
thor (~> 0.14)
@@ -133,7 +136,7 @@ GEM
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
- mime-types (1.18)
+ mime-types (1.19)
money (3.7.1)
i18n (~> 0.4)
multi_json (1.3.6)
@@ -149,7 +152,7 @@ GEM
net-ssh (2.5.2)
net-ssh-gateway (1.1.0)
net-ssh (>= 1.99.1)
- nokogiri (1.5.3)
+ nokogiri (1.5.5)
nori (1.1.0)
orm_adapter (0.0.7)
paperclip (2.7.0)
@@ -197,14 +200,14 @@ GEM
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
- savon (0.9.10)
- akami (~> 1.0)
+ savon (1.0.0)
+ akami (~> 1.1)
builder (>= 2.1.2)
gyoku (>= 0.4.0)
- httpi (~> 0.9)
+ httpi (~> 1.0)
nokogiri (>= 1.4.0)
nori (~> 1.1)
- wasabi (~> 2.1)
+ wasabi (~> 2.2)
spree (1.1.1)
spree_api (= 1.1.1)
spree_auth (= 1.1.1)
@@ -268,13 +271,17 @@ GEM
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.33)
- uglifier (1.2.4)
+ uglifier (1.2.5)
execjs (>= 0.3.0)
- multi_json (>= 1.0.2)
+ multi_json (~> 1.3)
uuidtools (2.1.2)
+ valid_email (0.0.4)
+ activemodel
+ mail
warden (1.1.1)
rack (>= 1.0)
- wasabi (2.2.0)
+ wasabi (2.4.1)
+ httpi (~> 1.0)
nokogiri (>= 1.4.0)
PLATFORMS
@@ -284,17 +291,19 @@ DEPENDENCIES
capistrano
coffee-rails (~> 3.2.1)
deface!
+ fancybox-rails
formtastic
jquery-rails
json
mysql2
rails (= 3.2.3)
sass-rails (~> 3.2.3)
- spree
+ spree (~> 1.1.1)
spree_product_assembly!
spree_redirects!
spree_reviews_rating (~> 1.0.1)
- spree_skrill
- spree_usa_epay
+ spree_skrill (~> 1.0.2)
+ spree_usa_epay (~> 1.0.2)
spree_user_groups!
uglifier (>= 1.0.3)
+ valid_email
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 9097d83..018bba1 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -11,5 +11,6 @@
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
+//= require fancybox
//= require jquery_ujs
//= require_tree .
diff --git a/app/assets/javascripts/store/notify_users.js.coffee b/app/assets/javascripts/store/notify_users.js.coffee
new file mode 100644
index 0000000..a77e6f2
--- /dev/null
+++ b/app/assets/javascripts/store/notify_users.js.coffee
@@ -0,0 +1,12 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+
+jQuery ->
+ $(document).ready ->
+ $('#notify').fancybox {
+ 'width': 400,
+ 'height': 120,
+ 'enableEscapeButton': true,
+ 'type': 'iframe',
+ 'href': @href }
diff --git a/app/assets/javascripts/store/products.js.coffee b/app/assets/javascripts/store/products.js.coffee
new file mode 100644
index 0000000..e69de29
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index 3b5cc66..715821d 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -9,5 +9,6 @@
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
+ *= require fancybox
*= require_tree .
*/
diff --git a/app/assets/stylesheets/spree/notify_users.css.scss b/app/assets/stylesheets/spree/notify_users.css.scss
new file mode 100644
index 0000000..3df6603
--- /dev/null
+++ b/app/assets/stylesheets/spree/notify_users.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the Spree::NotifyUsers controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/assets/stylesheets/store/notify_users.css b/app/assets/stylesheets/store/notify_users.css
new file mode 100644
index 0000000..0956edd
--- /dev/null
+++ b/app/assets/stylesheets/store/notify_users.css
@@ -0,0 +1,15 @@
+#flash_notice,
+#flash_error {
+ padding: 5px 8px;
+ margin: 10px 0;
+}
+
+#flash_error {
+ background-color: #FCC;
+ border: solid 1px #C66;
+}
+
+#flash_notice {
+ background-color: #CFC;
+ border: solid 1px #6C6;
+}
diff --git a/app/controllers/admin/products_controller_decorator.rb b/app/controllers/admin/products_controller_decorator.rb
new file mode 100644
index 0000000..8375e00
--- /dev/null
+++ b/app/controllers/admin/products_controller_decorator.rb
@@ -0,0 +1,17 @@
+Spree::Admin::ProductsController.class_eval do
+ before_filter :get_on_hand_value, :only => [ :update ]
+ after_filter :compare_on_hand_value
+
+ def get_on_hand_value
+ @updated = true
+ @before_on_hand = @product.on_hand
+ end
+
+ def compare_on_hand_value
+ if @updated then
+ if @before_on_hand <=0 and @product.on_hand > 0 then
+ Spree::UserNotification.notify(@product.id)
+ end
+ end
+ end
+end
diff --git a/app/controllers/spree/notify_users_controller.rb b/app/controllers/spree/notify_users_controller.rb
new file mode 100644
index 0000000..0793dd7
--- /dev/null
+++ b/app/controllers/spree/notify_users_controller.rb
@@ -0,0 +1,16 @@
+class Spree::NotifyUsersController < ApplicationController
+ layout = 'application'
+ def show
+ @product_id = params[:id]
+ end
+
+ def create
+ begin
+ a = Spree::UserNotification.create!(params[:user_notification])
+ flash[:notice] = "Notification Saved"
+ rescue ActiveRecord::RecordInvalid => e
+ flash[:error] = e.message
+ redirect_to :notify_user
+ end
+ end
+end
diff --git a/app/mailers/spree/user_notification_mailer.rb b/app/mailers/spree/user_notification_mailer.rb
new file mode 100644
index 0000000..68b726d
--- /dev/null
+++ b/app/mailers/spree/user_notification_mailer.rb
@@ -0,0 +1,12 @@
+module Spree
+ class UserNotificationMailer < ActionMailer::Base
+ def product_in_stock(mail_method,email,product)
+ @mail_method = mail_method
+ subject = "#{Spree::Config[:site_name]} #{t(:product_back_in_stock, :product => product)}"
+ mail(:from => "",
+ :to => email,
+ :subject => subject,
+ :body => t(:product_back_in_stock, :product => product))
+ end
+ end
+end
diff --git a/app/models/spree/user_notification.rb b/app/models/spree/user_notification.rb
new file mode 100644
index 0000000..2334faf
--- /dev/null
+++ b/app/models/spree/user_notification.rb
@@ -0,0 +1,23 @@
+class Spree::UserNotification < ActiveRecord::Base
+ belongs_to :products
+ attr_accessible :product_id, :email, :notified
+
+ validates :email, :presence => true, :email => true
+
+ validate :unique_product_email
+
+ def unique_product_email
+ if self.class.exists?(:product_id => product_id, :email => email, :notified => nil) then
+ errors.add :user, "already registered for notifications on this product"
+ end
+ end
+
+ def self.notify(product_id)
+ method = Spree::MailMethod.first( :conditions => [ "environment = ? ", ( Rails.env || "development" )])
+
+ all(:conditions => ["product_id = ? and notified is null", product_id]).each do |n|
+ Spree::UserNotificationMailer.product_in_stock(method,n.email,Spree::Product.find(product_id).name)
+ n.delete
+ end
+ end
+end
diff --git a/app/overrides/add_stock_warning_to_product.rb b/app/overrides/add_stock_warning_to_product.rb
new file mode 100644
index 0000000..b834bf6
--- /dev/null
+++ b/app/overrides/add_stock_warning_to_product.rb
@@ -0,0 +1,4 @@
+Deface::Override.new(:virtual_path => "spree/products/_cart_form",
+ :name => "add_stock_warning_to_product",
+ :insert_before => "code[erb-silent]:contains('if @product.price')",
+ :partial => "spree/products/low_stock")
diff --git a/app/views/spree/notify_users/create.html.erb b/app/views/spree/notify_users/create.html.erb
new file mode 100644
index 0000000..bb21566
--- /dev/null
+++ b/app/views/spree/notify_users/create.html.erb
@@ -0,0 +1,7 @@
+<% unless flash[:notice].blank? %>
+ <div id="flash_notice"><%=h flash[:notice]%> </div>
+<% end %>
+
+<script type="text/javascript">
+ setTimeout("parent.jQuery.fancybox.close();",1000);
+</script>
diff --git a/app/views/spree/notify_users/show.html.erb b/app/views/spree/notify_users/show.html.erb
new file mode 100644
index 0000000..95e6214
--- /dev/null
+++ b/app/views/spree/notify_users/show.html.erb
@@ -0,0 +1,16 @@
+<%= javascript_include_tag :application %>
+
+<% unless flash[:error].blank? %>
+ <div id="flash_error"><%=h flash[:error]%> </div>
+<% end %>
+
+<%= form_for :user_notification do |f| %>
+ <%= f.label :email %>
+ <%= f.text_field :email %>
+ <%= f.hidden_field :product_id, :value => @product_id %>
+ <br/>
+ <p align="right"><%= f.submit 'Save', :id => "save_notification" %></p>
+<% end %>
+
+
+
diff --git a/app/views/spree/products/_low_stock.html.erb b/app/views/spree/products/_low_stock.html.erb
new file mode 100644
index 0000000..2a270e5
--- /dev/null
+++ b/app/views/spree/products/_low_stock.html.erb
@@ -0,0 +1,20 @@
+<%= javascript_include_tag :fancybox %>
+<%= stylesheet_link_tag :fancybox %>
+
+<br/>
+<% count = @product.count_on_hand || 0 %>
+<% if count <= Configuration.product_show_stock_level_threshold then %>
+ <div id="stock_warning" style="color:red">
+ <% if count > 0 then %>
+ <%= t(:stock_warning, :amount => count) %>
+ <% else %>
+ <%= t(:out_of_stock) %>
+ <br/>
+ <%= t(:backorder) %>
+ <br/>
+ <%= t(:extra_shipping) %>
+ <br/>
+ <%= link_to "Get notified when the product is back in stock", "/notify_users/#{@product.id}", { :id => "notify" } %>
+ <% end %>
+ </div>
+<% end %>
diff --git a/config/environment.rb b/config/environment.rb
index 49763ce..f5d11c5 100644
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -5,3 +5,9 @@ require File.expand_path('../application', __FILE__)
Store::Application.initialize!
ActiveRecord::Base.include_root_in_json = true
+
+Store::Application.configure do
+ config.after_initialize do
+ Configuration.product_show_stock_level_threshold = 10
+ end
+end
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 2497828..b5061a4 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -14,7 +14,8 @@ Store::Application.configure do
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
- config.action_mailer.raise_delivery_errors = false
+ config.action_mailer.raise_delivery_errors = true
+ config.action_mailer.perform_deliveries = true
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
diff --git a/config/initializers/configuration.rb b/config/initializers/configuration.rb
new file mode 100644
index 0000000..161af0e
--- /dev/null
+++ b/config/initializers/configuration.rb
@@ -0,0 +1,7 @@
+class Configuration
+ class << self
+ attr_accessor :product_show_stock_level_threshold
+ end
+end
+
+
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2fca40a..d7212a3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -4,3 +4,7 @@
en:
hello: "Hello world"
minimum_order: "Minimum order amount of $%{amount} requirement for your group not met"
+ stock_warning: "%{amount} left, more comming soon!"
+ backorder: "You can backorder it and we'll ship it as soon as it's available"
+ extra_shipping: "Extra shipping fee may apply"
+ product_back_in_stock: "%{product} is back in stock"
diff --git a/config/routes.rb b/config/routes.rb
index 14bf839..5cc020e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -63,3 +63,12 @@ Store::Application.routes.draw do
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id))(.:format)'
end
+
+
+Spree::Core::Engine.routes.draw do
+ resources :notify_users, :except => :create do
+ collection do
+ post ':id' => 'notify_users#create', :as => :create
+ end
+ end
+end
diff --git a/db/migrate/20120713201821_create_spree_user_notifications.rb b/db/migrate/20120713201821_create_spree_user_notifications.rb
new file mode 100644
index 0000000..471df16
--- /dev/null
+++ b/db/migrate/20120713201821_create_spree_user_notifications.rb
@@ -0,0 +1,13 @@
+class CreateSpreeUserNotifications < ActiveRecord::Migration
+ def up
+ create_table :spree_user_notifications do |t|
+ t.column :product_id, :int, :null => false
+ t.column :email, :string, :null => false
+ t.column :notified, :date, :default => nil
+ t.timestamps
+ end
+ end
+ def down
+ drop_table :spree_user_notifications
+ end
+end
diff --git a/db/migrate/20120717213923_add_mail_methods.rb b/db/migrate/20120717213923_add_mail_methods.rb
new file mode 100644
index 0000000..3a27fe0
--- /dev/null
+++ b/db/migrate/20120717213923_add_mail_methods.rb
@@ -0,0 +1,25 @@
+class AddMailMethods < ActiveRecord::Migration
+ def up
+ dev = Spree::MailMethod.create(:environment => "development")
+ prod = Spree::MailMethod.create(:environment => "production")
+
+ dev.preferred_intercept_email = ""
+
+ [dev,prod].each do |m|
+ m.preferred_enable_mail_delivery = true
+ m.preferred_mails_from = ""
+ m.preferred_mail_bcc = ""
+ m.preferred_mail_domain = ""
+ m.preferred_mail_host = "smtp.gmail.com"
+ m.preferred_mail_port = 587
+ m.preferred_secure_connection_type = "SSL"
+ m.preferred_mail_auth_type = "login"
+ m.preferred_smtp_username = ""
+ m.preferred_smtp_password = ""
+ end
+ end
+
+ def down
+ Spree::MailMethod.delete(:conditions => ["environment in ('production','development')"])
+ end
+end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment