Merge branch 'local-organics'

Conflicts:
	Gemfile
	Gemfile.lock
	app/assets/stylesheets/store/variables.css.scss
	app/overrides/add_feedback_script.rb
	app/views/spree/shared/_order_details_steps_data.html.erb
	db/schema.rb
	script/rails
	spec/spec_helper.rb
This commit is contained in:
Rohan Mitchell
2013-07-23 11:40:03 +10:00
93 changed files with 887 additions and 102 deletions

1
.gitignore vendored
View File

@@ -31,5 +31,6 @@ public/images
public/spree
config/abr.yml
config/heroku_env.rb
config/initializers/feature_toggle.rb
NERD_tree*
coverage

12
Gemfile
View File

@@ -19,7 +19,6 @@ gem 'simple_form', :git => 'git://github.com/RohanM/simple_form.git'
gem 'unicorn'
gem 'bugsnag'
gem 'newrelic_rpm'
gem 'spree_heroku', :git => 'git://github.com/eaterprises/spree-heroku.git'
gem 'haml'
gem 'sass'
gem 'aws-sdk'
@@ -29,6 +28,8 @@ gem 'truncate_html'
gem 'representative_view'
gem 'rabl'
gem 'oj'
gem 'chili', :github => 'eaterprises/chili'
gem 'deface', :github => 'spree/deface'
# Gems used only for assets and not required
# in production environments by default.
@@ -59,7 +60,14 @@ group :test, :development do
gem 'database_cleaner', '0.7.1', :require => false
gem 'simplecov', :require => false
gem 'awesome_print'
gem "letter_opener"
gem 'letter_opener'
gem 'timecop'
end
group :chili do
gem 'enterprises_distributor_info_rich_text_feature', path: 'lib/chili/enterprises_distributor_info_rich_text_feature'
gem 'eaterprises_feature', path: 'lib/chili/eaterprises_feature'
gem 'local_organics_feature', path: 'lib/chili/local_organics_feature'
end
group :development do

View File

@@ -7,12 +7,12 @@ GIT
activemodel (~> 3.0)
GIT
remote: git://github.com/eaterprises/spree-heroku.git
revision: a1e07bf7a22fc0c07a1be9148f477d20b557dbf6
remote: git://github.com/eaterprises/chili.git
revision: b82608623d504eb39f852115b138a53af5f89505
specs:
spree_heroku (1.0)
aws-sdk (~> 1.3.4)
spree_core (>= 0.70.0)
chili (3.1.0)
deface (~> 1.0.0.rc2)
rails (~> 3.2)
GIT
remote: git://github.com/eaterprises/spree-last-address.git
@@ -22,6 +22,15 @@ GIT
spree_last_address (1.1.0)
spree_core (>= 1.1)
GIT
remote: git://github.com/spree/deface.git
revision: 1110a1336252109bce7f98f9182042e0bc2930ae
specs:
deface (1.0.0.rc3)
colorize (>= 0.5.8)
nokogiri (~> 1.6.0)
rails (>= 3.1)
GIT
remote: git://github.com/spree/spree.git
revision: 94566bf1b7d50f474333d10844534e570b6edf5a
@@ -74,7 +83,7 @@ GIT
GIT
remote: git://github.com/spree/spree_paypal_express.git
revision: 483f6ababa9c8a1c574aad0a948c96cc21a591db
revision: 9d70ab6d537420ff41468d05d6d2ac3c8d2ff3bf
branch: 1-3-stable
specs:
spree_paypal_express (1.2.0)
@@ -91,6 +100,27 @@ GIT
devise-encryptable (= 0.1.2)
spree_core
PATH
remote: lib/chili/eaterprises_feature
specs:
eaterprises_feature (0.0.1)
chili (~> 3.1)
rails (~> 3.2.11)
PATH
remote: lib/chili/enterprises_distributor_info_rich_text_feature
specs:
enterprises_distributor_info_rich_text_feature (0.0.1)
chili (~> 3.1)
rails (~> 3.2.11)
PATH
remote: lib/chili/local_organics_feature
specs:
local_organics_feature (0.0.1)
chili (~> 3.1)
rails (~> 3.2.11)
GEM
remote: https://rubygems.org/
specs:
@@ -111,14 +141,14 @@ GEM
active_utils (1.0.5)
activesupport (>= 2.3.11)
i18n
activemerchant (1.34.1)
activemerchant (1.34.0)
active_utils (>= 1.0.2)
activesupport (>= 2.3.14)
builder (>= 2.0.0)
i18n
json (>= 1.5.1)
money
nokogiri (< 1.6.0)
nokogiri
activemodel (3.2.13)
activesupport (= 3.2.13)
builder (~> 3.0.0)
@@ -173,6 +203,7 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.3.3)
colorize (0.5.8)
columnize (0.3.6)
comfortable_mexican_sofa (1.6.24)
active_link_to (~> 1.0.0)
@@ -189,9 +220,6 @@ GEM
debugger-ruby_core_source (~> 1.2.3)
debugger-linecache (1.2.0)
debugger-ruby_core_source (1.2.3)
deface (0.9.1)
nokogiri (~> 1.5.0)
rails (~> 3.1)
devise (2.2.4)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
@@ -251,6 +279,7 @@ GEM
treetop (~> 1.4.8)
method_source (0.8.1)
mime-types (1.23)
mini_portile (0.5.1)
money (5.0.0)
i18n (~> 0.4)
json
@@ -260,7 +289,8 @@ GEM
net-ssh (>= 2.6.5)
net-ssh (2.6.8)
newrelic_rpm (3.6.5.130)
nokogiri (1.5.10)
nokogiri (1.6.0)
mini_portile (~> 0.5.0)
oj (2.1.2)
orm_adapter (0.4.0)
paperclip (2.8.0)
@@ -365,6 +395,7 @@ GEM
libv8 (~> 3.3.10)
thor (0.18.1)
tilt (1.4.1)
timecop (0.6.2.2)
treetop (1.4.14)
polyglot
polyglot (>= 0.3.1)
@@ -402,16 +433,21 @@ DEPENDENCIES
aws-sdk
bugsnag
capybara
chili!
coffee-rails (~> 3.2.1)
comfortable_mexican_sofa
database_cleaner (= 0.7.1)
db2fog
debugger-linecache
deface!
eaterprises_feature!
enterprises_distributor_info_rich_text_feature!
factory_girl_rails
faker
haml
jquery-rails
letter_opener
local_organics_feature!
newrelic_rpm
oj
pg
@@ -427,11 +463,11 @@ DEPENDENCIES
simplecov
spree!
spree_auth_devise!
spree_heroku!
spree_i18n!
spree_last_address!
spree_paypal_express!
therubyracer
timecop
truncate_html
turbo-sprockets-rails3
turn (~> 0.8.3)

BIN
app/assets/images/ofw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -192,6 +192,11 @@ fieldset#product-distributor-details {
}
}
/* Checkout address page */
#checkout .alternative-available-distributors {
padding-top: 30px;
}
/* Delivery fees table on checkout page */
#delivery-fees {

View File

@@ -7,7 +7,7 @@ $c_red: #e45353 !default; /* Error red */
$layout_background_color: #FFFFFF !default;
$title_text_color: #404042 !default;
$body_text_color: #404042 !default;
$link_text_color: #006066 !default;
$link_text_color: #00ADEE !default;
$product_background_color: #FFFFFF !default;
$product_title_text_color: #404042 !default;
@@ -60,3 +60,5 @@ $ff_base: 'Ubuntu', sans-serif !default;
$button_border_color: rgba(0, 138, 189, .75) !default;
$table_head_color: lighten($body_text_color, 60) !default;
@import "./variables_changes.css.scss";

View File

@@ -333,11 +333,11 @@ Spree::Admin::ReportsController.class_eval do
if params[:q][:completed_at_gt].blank?
params[:q][:completed_at_gt] = Time.zone.now.beginning_of_month
else
params[:q][:completed_at_gt] = Time.zone.parse(params[:q][:completed_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
params[:q][:completed_at_gt] = Time.zone.parse(params[:q][:completed_at_gt]) rescue Time.zone.now.beginning_of_month
end
if params[:q] && !params[:q][:completed_at_lt].blank?
params[:q][:completed_at_lt] = Time.zone.parse(params[:q][:completed_at_lt]).end_of_day rescue ""
params[:q][:completed_at_lt] = Time.zone.parse(params[:q][:completed_at_lt]) rescue ""
end
params[:q][:meta_sort] ||= "completed_at.desc"

View File

@@ -5,6 +5,31 @@ Spree::OrdersController.class_eval do
before_filter :populate_order_count_on_hand, :only => :populate
after_filter :populate_variant_attributes, :only => :populate
def select_distributor
distributor = Enterprise.is_distributor.find params[:id]
order = current_order(true)
order.distributor = distributor
order.save!
redirect_to main_app.enterprise_path(distributor)
end
def deselect_distributor
order = current_order(true)
order.distributor = nil
order.save!
redirect_to root_path
end
private
# -- Callbacks
def populate_order_distributor
@distributor = params[:distributor_id].present? ? Enterprise.is_distributor.find(params[:distributor_id]) : nil
@@ -51,26 +76,8 @@ Spree::OrdersController.class_eval do
end
end
def select_distributor
distributor = Enterprise.is_distributor.find params[:id]
order = current_order(true)
order.distributor = distributor
order.save!
redirect_to main_app.enterprise_path(distributor)
end
def deselect_distributor
order = current_order(true)
order.distributor = nil
order.save!
redirect_to root_path
end
private
# -- Utils
def populate_valid? distributor
# -- Distributor must be specified

View File

@@ -0,0 +1,5 @@
module HtmlHelper
def strip_html(html)
strip_tags(html).gsub(/&nbsp;/i, ' ').gsub(/&amp;/i, '&')
end
end

View File

@@ -0,0 +1,3 @@
Spree::OrderMailer.class_eval do
helper HtmlHelper
end

View File

@@ -27,9 +27,9 @@ class Enterprise < ActiveRecord::Base
def to_param
"#{id}-#{name.parameterize}"
end
def available_variants
ProductDistribution.find_all_by_distributor_id( self.id ).map{ |pd| pd.product.variants + [pd.product.master] }.flatten
Spree::Variant.joins(:product => :product_distributions).where('product_distributions.distributor_id=?', self.id)
end

View File

@@ -0,0 +1,19 @@
module Spree
class Gateway::Migs < Gateway
preference :login, :string
preference :password, :string
attr_accessible :preferred_login, :preferred_password
def provider_class
ActiveMerchant::Billing::MigsGateway
end
def options_with_test_preference
options_without_test_preference.merge(:test => self.preferred_test_mode)
end
alias_method_chain :options, :test_preference
end
end

View File

@@ -5,11 +5,16 @@ Spree::LineItem.class_eval do
before_create :set_itemwise_shipping_method
def itemwise_shipping_cost
order = OpenStruct.new :line_items => [self]
shipping_method.compute_amount(order)
end
def update_itemwise_shipping_method_without_callbacks!(distributor)
update_column(:shipping_method_id, self.product.shipping_method_for_distributor(distributor).id)
end
private

View File

@@ -3,13 +3,20 @@ require 'open_food_web/distributor_change_validator'
Spree::Order.class_eval do
belongs_to :distributor, :class_name => 'Enterprise'
before_validation :shipping_address_from_distributor
validate :products_available_from_new_distributor, :if => :distributor_id_changed?
attr_accessible :distributor_id
before_validation :shipping_address_from_distributor
before_save :update_line_item_shipping_methods
after_create :set_default_shipping_method
def empty!
line_items.destroy_all
adjustments.destroy_all
set_default_shipping_method
end
def products_available_from_new_distributor
# Check that the line_items in the current order are available from a newly selected distributor
errors.add(:distributor_id, "cannot supply the products in your cart") unless DistributorChangeValidator.new(self).can_change_to_distributor?(distributor)
@@ -32,7 +39,7 @@ Spree::Order.class_eval do
end
def line_item_variants
line_items.map{ |li| li.variant }
line_items.map { |li| li.variant }
end
@@ -66,4 +73,11 @@ Spree::Order.class_eval do
end
end
end
def update_line_item_shipping_methods
if %w(cart address delivery resumed).include? state
self.line_items.each { |li| li.update_itemwise_shipping_method_without_callbacks!(distributor) }
self.update!
end
end
end

View File

@@ -1,5 +0,0 @@
Deface::Override.new(:virtual_path => "spree/layouts/spree_application",
:insert_bottom => "[data-hook='inside_head']",
:partial => "layouts/feedback_script",
:name => "add_feedback_script",
:original => '429dfd9824ee588f51fb1b69013933424f149592')

View File

@@ -6,7 +6,7 @@
%tr
%th Description:
%td= @enterprise.description
%tr
%tr{"data-hook" => "long_description"}
%th Extended Description:
%td= @enterprise.long_description.andand.html_safe
%tr

View File

@@ -1,23 +1,24 @@
%h2= distributor.name
%p
%strong Address:
%br/
= render 'spree/shared/address', :address => distributor.address
%p
%strong Next collection time:
%br/
= distributor.next_collection_at
%p
%strong Regular collection times:
%br/
= distributor.pickup_times
%p
%strong Contact:
%br/
= distributor.contact
%br/
= "Phone: #{distributor.phone}"
%br/
= "Email: #{distributor.email}"
%p= distributor.description
%p= link_to distributor.website, distributor.website if distributor.website
.distributor-details{'data-hook' => 'distributor-details'}
%h2= distributor.name
%p
%strong Address:
%br/
= render 'spree/shared/address', :address => distributor.address
%p
%strong Next collection time:
%br/
= distributor.next_collection_at
%p
%strong Regular collection times:
%br/
= distributor.pickup_times
%p
%strong Contact:
%br/
= distributor.contact
%br/
= "Phone: #{distributor.phone}"
%br/
= "Email: #{distributor.email}"
%p= distributor.description
%p= link_to distributor.website, distributor.website if distributor.website

View File

@@ -3,11 +3,11 @@
%br
.date-range-filter
%div{"class" => "left sub-field"}
= f.text_field :completed_at_gt, :class => 'datepicker'
= f.text_field :completed_at_gt, :class => 'datetimepicker'
%br
= label_tag nil, t(:start), :class => 'sub'
%div{"class" => "right sub-field"}
= f.text_field :completed_at_lt, :class => 'datepicker'
= f.text_field :completed_at_lt, :class => 'datetimepicker'
%br
= label_tag nil, t(:stop)
%br

View File

@@ -1,5 +1,5 @@
<% unless @order.state != 'address' %>
<div class="columns omega four" style="padding-top: 30px">
<div class="columns omega four alternative-available-distributors">
<% unless alternative_available_distributors(@order).empty? %>
<%= form_for(@order) do |f| %>
<%= f.label :distributor_label, "Alternative distributors for this order:" %>
@@ -10,4 +10,4 @@
No alternative distributors available.
<% end %>
</div>
<% end %>
<% end %>

View File

@@ -19,16 +19,16 @@
%div.cleared
%br
- if order.nil? || order.distributor.nil?
%div Distributor for your order:
%div.distributor Distributor for your order:
= select_tag "distributor_id", options_from_collection_for_select([Enterprise.new]+@product.distributors, "id", "name", :include_blank => '')
- else
- available_distributors = DistributorChangeValidator.new(order).available_distributors(@product.distributors)
- if available_distributors.length > 1
%div Distributor for your order:
%div.distributor Distributor for your order:
= select_tag "distributor_id", options_from_collection_for_select(available_distributors, "id", "name", current_distributor.andand.id)
- else
= hidden_field_tag "distributor_id", order.distributor.id
.distributor-fixed= "Your distributor for this order is #{order.distributor.name}"
%br
= button_tag :class => 'large primary', :id => 'add-to-cart-button', :type => :submit do
= t(:add_to_cart)
= t(:add_to_cart)

View File

@@ -4,8 +4,7 @@
<div class="columns alpha six">
<h6><%= "Customer Details" %> <%= link_to "(#{t(:edit)})", checkout_state_path(:address) unless @order.completed? %></h6>
<div class="address">
Name: <%= order.bill_address.full_name %><br />
Address: <%= order.bill_address.address1 + ", " + order.bill_address.city %>
<%= render 'enterprises/distributor_details', :distributor => order.distributor %>
</div>
</div>
@@ -35,4 +34,4 @@
</div>
</div>
</div>
</div>

View File

@@ -37,6 +37,10 @@ module Openfoodweb
OpenFoodWeb::Calculator::Weight]
end
# Register Spree payment methods
initializer "spree.gateway.payment_methods", :after => "spree.register.payment_methods" do |app|
app.config.spree.payment_methods << Spree::Gateway::Migs
end
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
@@ -72,7 +76,7 @@ module Openfoodweb
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
config.assets.initialize_on_precompile = false
config.assets.initialize_on_precompile = true
config.assets.precompile += ['store/all.css', 'store/all.js', 'admin/all.css', 'admin/*.js', 'admin/**/*.js', 'comfortable_mexican_sofa/*']
end
end

View File

@@ -11,10 +11,6 @@ require 'spree/product_filters'
require 'open_food_web/searcher'
Spree.config do |config|
config.site_name = "Open Food Web"
config.logo = 'logo.jpg'
config.admin_interface_logo = 'logo.jpg'
config.shipping_instructions = true
config.checkout_zone = 'Australia'
config.address_requires_state = true

View File

@@ -1,6 +1,6 @@
preload_app true # https://newrelic.com/docs/ruby/no-data-with-unicorn
worker_processes 4 # amount of unicorn workers to spin up
timeout 30 # restarts workers that hang for 30 seconds
timeout 60 # restarts workers that hang for 30 seconds
# https://devcenter.heroku.com/articles/forked-pg-connections

View File

@@ -0,0 +1,6 @@
# This migration comes from enterprises_distributor_info_rich_text_feature (originally 20130426022945)
class AddDistributorInfoToEnterprises < ActiveRecord::Migration
def change
add_column :enterprises, :distributor_info, :text
end
end

View File

@@ -156,6 +156,7 @@ ActiveRecord::Schema.define(:version => 20130629120645) do
t.string "next_collection_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.text "distributor_info"
end
create_table "exchange_fees", :force => true do |t|

View File

@@ -2,6 +2,7 @@
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
require File.expand_path('../../spec/factories', __FILE__)
require File.expand_path('../../spec/support/spree/init', __FILE__)
# -- Spree

View File

@@ -0,0 +1,3 @@
.bundle/
log/*.log
pkg/

View File

@@ -0,0 +1,3 @@
= Eaterprises Feature
This feature is released under the AGPL licence.

View File

@@ -0,0 +1,13 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require_tree .

View File

@@ -0,0 +1,13 @@
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
*= require_tree .
*/

View File

@@ -0,0 +1 @@
$link_text_color: #006066;

View File

@@ -0,0 +1,3 @@
<!-- insert_bottom 'head' -->
<%= stylesheet_link_tag 'eaterprises_feature/application' %>
<%= javascript_include_tag 'eaterprises_feature/application' %>

View File

@@ -1,3 +1,4 @@
<!-- insert_bottom "[data-hook='inside_head']" -->
<% if Rails.env.production? %>
<script type="text/javascript">
var uvOptions = {};

View File

@@ -0,0 +1,3 @@
EaterprisesFeature::Engine.automount!
EaterprisesFeature::Engine.routes.draw do
end

View File

@@ -0,0 +1,22 @@
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "eaterprises_feature/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "eaterprises_feature"
s.version = EaterprisesFeature::VERSION
s.authors = ["Rohan Mitchell"]
s.email = ["rohan@rohanmitchell.com"]
s.homepage = ""
s.summary = "Summary of EaterprisesFeature."
s.description = "Description of EaterprisesFeature."
s.files = Dir["{app,config,db,lib}/**/*"] + ["README.rdoc"]
s.add_dependency "rails", "~> 3.2.11"
s.add_dependency 'chili', '~> 3.1'
s.add_development_dependency "sqlite3"
end

View File

@@ -0,0 +1,7 @@
require "chili"
require "eaterprises_feature/engine"
module EaterprisesFeature
extend Chili::Base
active_if { OpenFoodWeb::FeatureToggle.enabled? :eaterprises }
end

View File

@@ -0,0 +1,17 @@
require 'open_food_web/feature_toggle'
module EaterprisesFeature
class Engine < ::Rails::Engine
isolate_namespace EaterprisesFeature
if OpenFoodWeb::FeatureToggle.enabled? :eaterprises
initializer 'eaterprises_feature.sass', :after => :load_config_initializers do |app|
app.config.sass.load_paths += [self.root.join('app', 'assets', 'stylesheets', 'eaterprises_feature')] if Rails.application.config.respond_to? :sass
end
initializer :assets do |app|
app.config.assets.precompile += ['eaterprises_feature/*']
end
end
end
end

View File

@@ -0,0 +1,3 @@
module EaterprisesFeature
VERSION = "0.0.1"
end

View File

@@ -0,0 +1,3 @@
class EaterprisesFeatureGenerator < Rails::Generators::Base
include Chili::GeneratorProxy
end

View File

@@ -0,0 +1,3 @@
.bundle/
log/*.log
pkg/

View File

@@ -0,0 +1,3 @@
= EnterprisesDistributorInfoRichTextFeature
This project rocks and uses MIT-LICENSE.

View File

@@ -0,0 +1,13 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require_tree .

View File

@@ -0,0 +1,13 @@
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
*= require_tree .
*/

View File

@@ -0,0 +1,5 @@
.distributor-details .next-collection-at {
font-size: 20px;
font-weight: bold;
color: #de790c;
}

View File

@@ -0,0 +1,4 @@
/ insert_after "[data-hook='long_description']"
%tr{"data-hook" => "distributor_info"}
%td Distributor Info:
%td= f.text_area :distributor_info, :class => 'rich_text'

View File

@@ -0,0 +1,3 @@
/ replace_contents "[data-hook='long_description']"
%td Profile Info:
%td= f.text_area :long_description, :class => 'rich_text'

View File

@@ -0,0 +1,4 @@
/ insert_after "[data-hook='long_description']"
%tr{'data-hook' => 'distributor_info'}
%th Distributor Info:
%td= @enterprise.distributor_info.andand.html_safe

View File

@@ -0,0 +1,3 @@
/ replace_contents "[data-hook='long_description']"
%th Profile Info:
%td= @enterprise.long_description.andand.html_safe

View File

@@ -0,0 +1,4 @@
/ replace_contents "[data-hook='distributor-details']"
%h2= distributor.name
= distributor.distributor_info.andand.html_safe
.next-collection-at= distributor.next_collection_at

View File

@@ -0,0 +1,2 @@
<!-- insert_bottom 'head' -->
<%= stylesheet_link_tag 'enterprises_distributor_info_rich_text_feature/application' %>

View File

@@ -0,0 +1,36 @@
Dear <%= @order.bill_address.firstname %>,
Please review and retain the following order information for your records.
============================================================
Order Summary
============================================================
Order for: <%= @order.bill_address.full_name %>
<% @order.line_items.each do |item| %>
<%= item.variant.sku %> <%= raw(item.variant.product.name) %> <%= raw(item.variant.options_text) -%> (<%=item.quantity%>) @ <%= number_to_currency item.price %> = <%= number_to_currency(item.price * item.quantity) %>
<% end %>
============================================================
Subtotal: <%= number_to_currency @order.item_total %>
<% @order.adjustments.each do |adjustment| %>
<%= raw(adjustment.label) %> <%= number_to_currency(adjustment.amount) %>
<% end %>
Order Total: <%= number_to_currency(@order.total) %>
<% if @order.payment_method.name.include? "EFT" %>
============================================================
Payment Details
============================================================
<%= @order.payment_method.description.html_safe %>
<% end %>
============================================================
Collection / Delivery Details
============================================================
<%= raw strip_html @order.distributor.distributor_info %>
<%= @order.distributor.next_collection_at %>
Thanks for your support.
Marcus and Angie,
Local Organics

View File

@@ -0,0 +1,3 @@
EnterprisesDistributorInfoRichTextFeature::Engine.automount!
EnterprisesDistributorInfoRichTextFeature::Engine.routes.draw do
end

View File

@@ -0,0 +1,5 @@
class AddDistributorInfoToEnterprises < ActiveRecord::Migration
def change
add_column :enterprises, :distributor_info, :text
end
end

View File

@@ -0,0 +1,22 @@
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "enterprises_distributor_info_rich_text_feature/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "enterprises_distributor_info_rich_text_feature"
s.version = EnterprisesDistributorInfoRichTextFeature::VERSION
s.authors = ["Rohan Mitchell"]
s.email = ["rohan@rohanmitchell.com"]
s.homepage = ""
s.summary = "Summary of EnterprisesDistributorInfoRichTextFeature."
s.description = "Description of EnterprisesDistributorInfoRichTextFeature."
s.files = Dir["{app,config,db,lib}/**/*"] + ["README.rdoc"]
s.add_dependency "rails", "~> 3.2.11"
s.add_dependency 'chili', '~> 3.1'
s.add_development_dependency "sqlite3"
end

View File

@@ -0,0 +1,7 @@
require "chili"
require "enterprises_distributor_info_rich_text_feature/engine"
module EnterprisesDistributorInfoRichTextFeature
extend Chili::Base
active_if { OpenFoodWeb::FeatureToggle.enabled? :enterprises_distributor_info_rich_text }
end

View File

@@ -0,0 +1,23 @@
require 'open_food_web/feature_toggle'
module EnterprisesDistributorInfoRichTextFeature
class Engine < ::Rails::Engine
isolate_namespace EnterprisesDistributorInfoRichTextFeature
initializer 'enterprises_distributor_info_rich_text_feature.mailer', :after => :load_config_initializers do |app|
if OpenFoodWeb::FeatureToggle.enabled? :enterprises_distributor_info_rich_text
::Spree::OrderMailer.class_eval do
def confirm_email(order, resend = false)
@order = order
subject = (resend ? "[#{t(:resend).upcase}] " : '')
subject += "#{Spree::Config[:site_name]} #{t('order_mailer.confirm_email.subject')} ##{order.number}"
mail(:to => order.email,
:subject => subject,
:template_name => 'confirm_email_with_distributor_info')
end
end
end
end
end
end

View File

@@ -0,0 +1,3 @@
module EnterprisesDistributorInfoRichTextFeature
VERSION = "0.0.1"
end

View File

@@ -0,0 +1,3 @@
class EnterprisesDistributorInfoRichTextFeatureGenerator < Rails::Generators::Base
include Chili::GeneratorProxy
end

View File

@@ -0,0 +1,3 @@
.bundle/
log/*.log
pkg/

View File

@@ -0,0 +1,3 @@
= Local Organics Feature
This feature is released under the AGPL licence.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@@ -0,0 +1,13 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require_tree .

View File

@@ -0,0 +1,10 @@
body.admin {
#header {
height: 150px;
}
#header #logo {
background-color: #fff;
border: 5px solid #fff;
}
}

View File

@@ -0,0 +1,13 @@
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
*= require_tree .
*/

View File

@@ -0,0 +1,48 @@
body {
background-color: #FFF5E0;
}
h2 {
font-size: 26px;
color: #331f00;
}
nav #main-nav-bar {
border-bottom: 9px solid #A3DCFF;
}
nav#taxonomies .taxonomy-root,
nav#taxonomies .taxons-list li a,
nav#filters .filter_name,
nav#filters .filter_choices li a {
font-size: 16px;
}
/* Products listing page */
#products-local ul {
background-color: #e6f4ff;
}
ul.product-listing li a.info {
font-size: 16px;
color: #331f00;
}
ul.product-listing li .price {
font-size: 20px;
}
/* Product details page */
#cart-form .distributor {
font-size: 14px;
font-weight: bold;
}
/* Checkout address page */
#checkout .alternative-available-distributors {
display: none;
}
div#checkout .form-buttons {
padding-top: 30px;
margin-left: 0;
}

View File

@@ -0,0 +1,3 @@
<!-- insert_bottom 'head' -->
<%= stylesheet_link_tag 'local_organics_feature/admin' %>
<%= javascript_include_tag 'local_organics_feature/admin' %>

View File

@@ -0,0 +1,5 @@
<!-- replace_contents '#header' sequence 1 -->
<div data-hook="admin_login_navigation_bar"></div>
<%= link_to image_tag('local_organics_feature/logo.png', :id => 'logo'), spree.admin_path %>
<h1><%= link_to t(:administration), spree.admin_path %></h1>
<div id="progress"><%= image_tag 'admin/progress.gif' %> <%= t(:loading) %>...</div>

View File

@@ -0,0 +1,3 @@
<!-- insert_bottom 'head' -->
<%= stylesheet_link_tag 'local_organics_feature/application' %>
<%= javascript_include_tag 'local_organics_feature/application' %>

View File

@@ -0,0 +1,3 @@
<!-- insert_bottom '#footer-left p' -->
| <%= link_to 'Terms and Conditions', "http://www.localorg.com.au/contactterms-and-conditions.html" %>
| <%= link_to "http://openfoodweb.org/foundation" do %><%= image_tag 'ofw.png', alt: 'Open Food Web Foundation' %><% end %>

View File

@@ -0,0 +1,2 @@
<!-- replace_contents 'figure#logo' -->
<%= logo 'local_organics_feature/logo.png' %>

View File

@@ -0,0 +1,3 @@
/ replace_contents '#products-local'
%h5= "Products at #{current_distributor.name}"
= render 'spree/shared/products', :products => @products_local, :taxon => @taxon

View File

@@ -0,0 +1,3 @@
/ replace_contents '#products-remote'
%h5 Products found elsewhere
= render 'spree/shared/products', :products => @products_remote, :taxon => @taxon

View File

@@ -0,0 +1,3 @@
LocalOrganicsFeature::Engine.automount!
LocalOrganicsFeature::Engine.routes.draw do
end

View File

@@ -0,0 +1,3 @@
class LocalOrganicsFeatureGenerator < Rails::Generators::Base
include Chili::GeneratorProxy
end

View File

@@ -0,0 +1,7 @@
require "chili"
require "local_organics_feature/engine"
module LocalOrganicsFeature
extend Chili::Base
active_if { OpenFoodWeb::FeatureToggle.enabled? :local_organics }
end

View File

@@ -0,0 +1,17 @@
require 'open_food_web/feature_toggle'
module LocalOrganicsFeature
class Engine < ::Rails::Engine
isolate_namespace LocalOrganicsFeature
if OpenFoodWeb::FeatureToggle.enabled? :local_organics
initializer 'local_organics_feature.sass', :after => :load_config_initializers do |app|
app.config.sass.load_paths += [self.root.join('app', 'assets', 'stylesheets', 'local_organics_feature')] if Rails.application.config.respond_to? :sass
end
initializer :assets do |app|
app.config.assets.precompile += ['local_organics_feature/*']
end
end
end
end

View File

@@ -0,0 +1,3 @@
module LocalOrganicsFeature
VERSION = "0.0.1"
end

View File

@@ -0,0 +1,22 @@
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "local_organics_feature/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "local_organics_feature"
s.version = LocalOrganicsFeature::VERSION
s.authors = ["Rohan Mitchell"]
s.email = ["rohan@rohanmitchell.com"]
s.homepage = ""
s.summary = "Summary of LocalOrganicsFeature."
s.description = "Description of LocalOrganicsFeature."
s.files = Dir["{app,config,db,lib}/**/*"] + ["README.rdoc"]
s.add_dependency "rails", "~> 3.2.11"
s.add_dependency 'chili', '~> 3.1'
s.add_development_dependency "sqlite3"
end

View File

@@ -11,12 +11,16 @@ class DistributorChangeValidator
def can_change_to_distributor? distributor
# Distributor may not be changed once an item has been added to the cart/order, unless all items are available from the specified distributor
@order.line_items.empty? || (available_distributors(Enterprise.all) || []).include?(distributor)
@order.line_items.empty? || all_available_distributors.include?(distributor)
end
def all_available_distributors
@all_available_distributors ||= (available_distributors(Enterprise.all) || [])
end
def available_distributors enterprises
enterprises.select do |e|
(@order.line_item_variants - e.available_variants).empty?
end
end
end
end

View File

@@ -0,0 +1,16 @@
module OpenFoodWeb
class FeatureToggle
def self.enabled? feature
features[feature]
end
private
def self.features
{eaterprises: true,
local_organics: false,
enterprises_distributor_info_rich_text: false}
end
end
end

View File

@@ -4,7 +4,6 @@
if ENV['RAILS_ENV'] == 'test'
require 'simplecov'
SimpleCov.start 'rails'
puts "required simplecov"
end
APP_PATH = File.expand_path('../../config/application', __FILE__)

View File

@@ -48,4 +48,35 @@ feature %q{
page.should have_content 'Supplier'
end
scenario "order cycle reports are precise to time of day, not just date" do
# Given two orders on the same day at different times
@bill_address = create(:address)
@distributor_address = create(:address, :address1 => "distributor address", :city => 'The Shire', :zipcode => "1234")
@distributor = create(:distributor_enterprise, :address => @distributor_address)
product = create(:product)
product_distribution = create(:product_distribution, :product => product, :distributor => @distributor, :shipping_method => create(:shipping_method))
@shipping_instructions = "pick up on thursday please!"
@order1 = create(:order, :distributor => @distributor, :bill_address => @bill_address, :special_instructions => @shipping_instructions)
@order2 = create(:order, :distributor => @distributor, :bill_address => @bill_address, :special_instructions => @shipping_instructions)
Timecop.travel(Time.zone.local(2013, 4, 25, 14, 0, 0)) { @order1.finalize! }
Timecop.travel(Time.zone.local(2013, 4, 25, 16, 0, 0)) { @order2.finalize! }
create(:line_item, :product => product, :order => @order1)
create(:line_item, :product => product, :order => @order2)
# When I generate a customer report with a timeframe that includes one order but not the other
login_to_admin_section
click_link 'Reports'
click_link 'Order Cycle Reports'
fill_in 'q_completed_at_gt', with: '2013-04-25 13:00:00'
fill_in 'q_completed_at_lt', with: '2013-04-25 15:00:00'
select 'Order Cycle Customer Totals', from: 'report_type'
click_button 'Search'
# Then I should see the rows for the first order but not the second
all('table#listing_orders tbody tr').count.should == 2 # Two rows per order
end
end

View File

@@ -0,0 +1,113 @@
require 'spec_helper'
feature "enterprises distributor info as rich text" do
include AuthenticationWorkflow
include WebHelper
before(:each) do
OpenFoodWeb::FeatureToggle.stub(:features).and_return({eaterprises: false,
local_organics: true,
enterprises_distributor_info_rich_text: true})
# The deployment is not set to local_organics on Rails init, so these
# initializers won't run. Re-call them now that the deployment is set.
EnterprisesDistributorInfoRichTextFeature::Engine.initializers.each &:run
end
scenario "setting distributor info as admin" do
# Given I'm signed in as an admin
login_to_admin_section
# When I go to create a new enterprise
click_link 'Enterprises'
click_link 'New Enterprise'
# Then I should see fields 'Profile Info' and 'Distributor Info'
page.should have_selector 'td', text: 'Profile Info:'
page.should have_selector 'td', text: 'Distributor Info:'
# When I fill out the form and create the enterprise
fill_in 'enterprise_name', :with => 'Eaterprises'
fill_in 'enterprise_long_description', with: 'Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro.'
fill_in 'enterprise_distributor_info', with: 'Chu ge sai yubi dan bisento tobi ashi yubi ge omote.'
fill_in 'enterprise_address_attributes_address1', with: '35 Ballantyne St'
fill_in 'enterprise_address_attributes_city', with: 'Thornbury'
fill_in 'enterprise_address_attributes_zipcode', with: '3072'
select 'Australia', from: 'enterprise_address_attributes_country_id'
select 'Victoria', from: 'enterprise_address_attributes_state_id'
click_button 'Create'
# Then I should see the enterprise details
flash_message.should == 'Enterprise "Eaterprises" has been successfully created!'
click_link 'Eaterprises'
page.should have_selector "tr[data-hook='long_description'] th", text: 'Profile Info:'
page.should have_selector "tr[data-hook='long_description'] td", text: 'Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro.'
page.should have_selector "tr[data-hook='distributor_info'] th", text: 'Distributor Info:'
page.should have_selector "tr[data-hook='distributor_info'] td", text: 'Chu ge sai yubi dan bisento tobi ashi yubi ge omote.'
end
scenario "viewing distributor info", js: true do
ActionMailer::Base.deliveries.clear
setup_shipping_details
d = create(:distributor_enterprise, distributor_info: 'Chu ge sai yubi dan <strong>bisento</strong> tobi ashi yubi ge omote.', next_collection_at: 'Thursday 2nd May')
p = create(:product, :distributors => [d])
login_to_consumer_section
visit spree.select_distributor_order_path(d)
# -- Product details page
visit spree.product_path p
within '#product-distributor-details' do
page.should have_content 'Chu ge sai yubi dan bisento tobi ashi yubi ge omote.'
page.should have_content 'Thursday 2nd May'
end
# -- Checkout
click_button 'Add To Cart'
click_link 'Checkout'
within 'fieldset#shipping' do
page.should have_content 'Chu ge sai yubi dan bisento tobi ashi yubi ge omote.'
page.should have_content 'Thursday 2nd May'
end
# -- Purchase email
complete_purchase_from_checkout_address_page
wait_until { ActionMailer::Base.deliveries.length == 1 }
email = ActionMailer::Base.deliveries.last
email.body.should =~ /Chu ge sai yubi dan bisento tobi ashi yubi ge omote./
email.body.should =~ /Thursday 2nd May/
end
private
def setup_shipping_details
zone = create(:zone)
c = Spree::Country.find_by_name('Australia')
Spree::ZoneMember.create(:zoneable => c, :zone => zone)
create(:itemwise_shipping_method, zone: zone)
create(:payment_method, :description => 'Cheque payment method')
end
def complete_purchase_from_checkout_address_page
fill_in_fields('order_bill_address_attributes_firstname' => 'Joe',
'order_bill_address_attributes_lastname' => 'Luck',
'order_bill_address_attributes_address1' => '19 Sycamore Lane',
'order_bill_address_attributes_city' => 'Horse Hill',
'order_bill_address_attributes_zipcode' => '3213',
'order_bill_address_attributes_phone' => '12999911111')
select('Australia', :from => 'order_bill_address_attributes_country_id')
select('Victoria', :from => 'order_bill_address_attributes_state_id')
click_button 'Save and Continue'
click_button 'Save and Continue'
click_button 'Process My Order'
end
end

View File

@@ -2,7 +2,7 @@ require "spec_helper"
feature %q{
As a consumer
I want select a distributor for collection
I want to select a distributor for collection
So that I can pick up orders from the closest possible location
} do
include AuthenticationWorkflow
@@ -88,6 +88,63 @@ feature %q{
page.should have_selector '#delivery-fees span.order-total', :text => '$3.00'
end
scenario "changing distributor updates delivery fees" do
# Given two distributors and shipping methods
d1 = create(:distributor_enterprise)
d2 = create(:distributor_enterprise)
sm1 = create(:shipping_method)
sm1.calculator.set_preference :amount, 1.23; sm1.calculator.save!
sm2 = create(:free_shipping_method)
sm2.calculator.set_preference :amount, 2.34; sm2.calculator.save!
# And two products both available from both distributors
p1 = create(:product)
create(:product_distribution, product: p1, distributor: d1, shipping_method: sm1)
create(:product_distribution, product: p1, distributor: d2, shipping_method: sm2)
p2 = create(:product)
create(:product_distribution, product: p2, distributor: d1, shipping_method: sm1)
create(:product_distribution, product: p2, distributor: d2, shipping_method: sm2)
# When I add the first product to my cart with the first distributor
#visit spree.root_path
login_to_consumer_section
click_link p1.name
select d1.name, :from => 'distributor_id'
click_button 'Add To Cart'
# Then I should see shipping costs for the first distributor
page.should have_selector 'span.shipping-total', text: '$1.23'
# When add the second with the second distributor
click_link 'Continue shopping'
click_link p2.name
select d2.name, :from => 'distributor_id'
click_button 'Add To Cart'
# Then I should see shipping costs for the second distributor
page.should have_selector 'span.shipping-total', text: '$4.68'
end
scenario "adding a product to cart after emptying cart shows correct delivery fees" do
# When I add a product to my cart
login_to_consumer_section
click_link @product_1.name
select @distributor.name, :from => 'distributor_id'
click_button 'Add To Cart'
# Then I should see the correct delivery fee
page.should have_selector 'span.grand-total', text: '$20.99'
# When I empty my cart and add the product again
click_button 'Empty Cart'
click_link 'Continue shopping'
click_link @product_1.name
select @distributor.name, :from => 'distributor_id'
click_button 'Add To Cart'
# Then I should see the correct delivery fee
page.should have_selector 'span.grand-total', text: '$20.99'
end
scenario "buying a product", :js => true do
login_to_consumer_section
@@ -152,4 +209,5 @@ feature %q{
# page.should have_content('On Tuesday, 4 PM')
# page.should have_content('12 Bungee Rd, Carion')
end
end

View File

@@ -0,0 +1,20 @@
require 'open_food_web/feature_toggle'
module OpenFoodWeb
describe FeatureToggle do
it "returns true when feature is on" do
FeatureToggle.stub(:features).and_return({foo: true})
FeatureToggle.enabled?(:foo).should be_true
end
it "returns false when feature is off" do
FeatureToggle.stub(:features).and_return({foo: false})
FeatureToggle.enabled?(:foo).should be_false
end
it "returns false when feature is undefined" do
FeatureToggle.stub(:features).and_return({})
FeatureToggle.enabled?(:foo).should be_false
end
end
end

View File

@@ -2,17 +2,23 @@ require 'spec_helper'
module Spree
describe LineItem do
it "computes shipping cost for its product" do
# Create a shipping method with flat rate of 10
shipping_method = create(:shipping_method)
shipping_method.calculator.set_preference :amount, 10
describe "computing shipping cost for its product" do
let(:shipping_method) do
sm = create(:shipping_method)
sm.calculator.set_preference :amount, 10
sm
end
let(:order) { double(:order, :distributor => nil, :state => 'complete') }
let(:line_item) do
li = LineItem.new
li.stub(:shipping_method).and_return(shipping_method)
li.stub(:order).and_return(order)
li
end
order = double(:order, :distributor => nil)
subject.stub(:shipping_method).and_return(shipping_method)
subject.stub(:order).and_return(order)
subject.itemwise_shipping_cost.should == 10
it "computes shipping cost for its product" do
line_item.itemwise_shipping_cost.should == 10
end
end
end
end

View File

@@ -1,8 +1,8 @@
require 'simplecov'
SimpleCov.start
require 'rubygems'
require 'rubygems'
ENV["RAILS_ENV"] = 'test'
require File.expand_path("../../config/environment", __FILE__)
@@ -10,6 +10,10 @@ require 'rspec/rails'
require 'capybara'
require 'database_cleaner'
# Do not require pry in Travis
require 'pry' unless ENV['HAS_JOSH_K_SEAL_OF_APPROVAL']
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
@@ -52,6 +56,13 @@ RSpec.configure do |config|
else
DatabaseCleaner.strategy = :transaction
end
# TODO: Duplication of below. Remove?
config.include Rails.application.routes.url_helpers
config.include Spree::UrlHelpers
config.include Spree::Core::TestingSupport::ControllerRequests, :type => :controller
config.include Devise::TestHelpers, :type => :controller
DatabaseCleaner.start
end