Compare commits

..

45 Commits
0.2.3 ... 0.2.9

Author SHA1 Message Date
Rohan Mitchell
f03d9b66f0 Update spree_paypal_express to fail gracefully when setting address 2012-10-31 15:17:05 +11:00
Rohan Mitchell
5dcba7403b Avoid contaminating test data 2012-10-31 13:54:14 +11:00
Rohan Mitchell
926440a978 Fix namespacing of Distributor in reports controller 2012-10-31 11:13:55 +11:00
Rohan Mitchell
9b32579bd6 Group buy report handles nil variant weight gracefully 2012-10-31 10:37:40 +11:00
Rohan Mitchell
5ac904005b Merge branch 'order-cycle-reports'
Conflicts:
	app/controllers/spree/admin/reports_controller_decorator.rb
	config/routes.rb
2012-10-31 10:18:11 +11:00
Rohan Mitchell
03610c93de Upgrade capybara and selenium-webdriver for compatibility with Firefox 16 2012-10-28 12:28:55 +11:00
Rohan Mitchell
c5941d6cb5 Update distributor details when distributor is changed 2012-10-27 18:50:09 +11:00
Rohan Mitchell
773adca838 Display distributor details on product page when distributor is selected 2012-10-27 12:49:57 +11:00
Rohan Mitchell
13317347bb Display an explanation message on product page when no distributor is selected 2012-10-27 12:19:44 +11:00
Rob H
f960cc44ba Fixed calculations when variant weight is nil 2012-10-26 17:27:08 +11:00
Rob H
a9293709d8 Merge branch 'master', remote-tracking branch 'origin' 2012-10-26 17:24:17 +11:00
Rohan Mitchell
a3042118c7 Merge branch 'group-reports'
Conflicts:
	app/controllers/spree/admin/reports_controller_decorator.rb
	config/routes.rb
2012-10-26 17:14:49 +11:00
Rob H
ede4649fbf Merge branch 'master', remote-tracking branch 'origin' 2012-10-26 16:12:11 +11:00
Rob H
4dd5e12968 Fix reports controller, previous changes to fix change generate_report were incomplete 2012-10-26 13:49:39 +11:00
Rob H
d74591afe6 Fixes to reports controller and addition of order cycles reports 2012-10-26 13:44:13 +11:00
Rohan Mitchell
09b60908b8 Fix links to admin distributor edit and delete 2012-10-25 12:20:20 +11:00
Rohan Mitchell
d1b9ce92f6 Move distributors helper out of spree namespace 2012-10-25 10:45:39 +11:00
Rohan Mitchell
784969097d Move admin non-Spree controllers out of Spree namespace 2012-10-25 10:45:39 +11:00
Rohan Mitchell
15e91f7743 WIP Move non-admin non-Spree controllers out of Spree namespace 2012-10-25 10:45:39 +11:00
Rohan Mitchell
c46019d68c WIP: Move Supplier, Distributor, DistributorSet and ProductDistribution models out of Spree namespace 2012-10-25 10:45:39 +11:00
Rohan Mitchell
aa336d9b9f Merge branch 'feedback' 2012-10-25 10:34:27 +11:00
Rob H
ff029b8903 Add feedback bar to all pages on the front end 2012-10-24 18:26:21 +11:00
Rob H
a362dd5161 Change reports controller: generate_report to render_report 2012-10-24 17:01:50 +11:00
Rohan Mitchell
51850be83e Update spree_paypal_express to handle blank states from paypal 2012-10-24 16:19:53 +11:00
Rob H
41d547ac2d Minor formatting changes to Order Group Spec 2012-10-24 16:13:23 +11:00
Rob H
81b33772fe Fixes to syntax and formatting for group-reports 2012-10-24 15:21:16 +11:00
Rohan Mitchell
32db258db0 Use spree_heroku with support for staging env 2012-10-24 13:11:40 +11:00
Rob H
3b855a866a Merge branch 'grouper-reports' into group-reports 2012-10-22 11:35:56 +11:00
Rob H
eb7d69fe6b commit routes.rb file to prevent overwriting 2012-10-22 11:35:48 +11:00
Rob H
4c0109bccc Merge branch 'master', remote-tracking branch 'origin' 2012-10-22 11:15:23 +11:00
Rob H
f83a5b0ba8 Merge branch 'master', remote-tracking branch 'origin' 2012-10-22 10:45:35 +11:00
Rob H
ddb01e4ccb WIP: Create report grouper, write reports for bulk co-ops and payments 2012-10-21 13:12:48 +11:00
Rohan Mitchell
87a89324d9 Update repo in readme, add Rob to creds 2012-10-19 17:02:09 +11:00
Rohan Mitchell
4fc7295b97 Use S3 configuration from environment vars instead of s3.yml 2012-10-19 16:40:18 +11:00
Rohan Mitchell
5b025a6cba Make group_buy_unit_size accessible 2012-10-18 15:15:54 +11:00
Rohan Mitchell
9166829930 Add group buy unit size field 2012-10-18 11:56:21 +11:00
Rohan Mitchell
8c7a02ec10 Fix image uploads with CMS 2012-10-18 11:13:40 +11:00
Rohan Mitchell
f4f250675c Use eaterprises spree_paypal_express with Bugsnag notification of paypal gateway errors 2012-10-18 10:30:35 +11:00
Rohan Mitchell
394a269df2 Update Spree, fixes paypal password blanking bug. Update spree_paypal_express, fixes nil state error on checkout. 2012-10-18 10:17:52 +11:00
Rohan Mitchell
41dcc85ad1 Update version of spree_paypal_express for debugging 2012-10-17 15:26:06 +11:00
Rohan Mitchell
9be9d75cb5 Update version of spree_paypal_express for debugging 2012-10-17 15:10:04 +11:00
Rohan Mitchell
11483a77e8 Update bugsnag and spree_paypal_express for paypal error debugging 2012-10-17 08:42:33 +11:00
Rohan Mitchell
ba895ed486 Display CMS content for suppliers page 2012-10-17 07:54:12 +11:00
Rohan Mitchell
36d342f216 Add view all suppliers page 2012-10-17 07:50:58 +11:00
Rohan Mitchell
d09123eb22 Do not show suppliers with no products in stock 2012-10-17 07:36:18 +11:00
87 changed files with 1450 additions and 454 deletions

1
.gitignore vendored
View File

@@ -27,4 +27,5 @@ public/stylesheets
public/images
public/spree
config/abr.yml
config/heroku_env.rb
NERD_tree*

View File

@@ -6,7 +6,7 @@ gem 'rails', '3.2.8'
gem 'pg'
gem 'spree', :git => 'git://github.com/spree/spree.git', :branch => '1-1-stable'
gem 'spree_i18n', :git => 'git://github.com/spree/spree_i18n.git'
gem 'spree_paypal_express', :git => 'git://github.com/RohanM/spree_paypal_express.git', :branch => '1-1-stable'
gem 'spree_paypal_express', :git => 'git://github.com/eaterprises/spree_paypal_express.git', :branch => '1-1-stable'
gem 'spree_last_address', :git => 'git://github.com/dancinglightning/spree-last-address.git'
gem 'comfortable_mexican_sofa'
@@ -17,9 +17,9 @@ gem 'simple_form', :git => 'git://github.com/RohanM/simple_form.git'
gem 'unicorn'
gem 'bugsnag'
gem 'spree_heroku', :git => 'git://github.com/joneslee85/spree-heroku.git'
gem 'spree_heroku', :git => 'git://github.com/eaterprises/spree-heroku.git'
gem 'haml'
gem 'aws-s3'
gem 'aws-sdk'
gem 'andand'
gem 'truncate_html'

View File

@@ -6,15 +6,6 @@ GIT
actionpack (~> 3.0)
activemodel (~> 3.0)
GIT
remote: git://github.com/RohanM/spree_paypal_express.git
revision: ca5723c0e268e74adcb9b8ec04d082d86888f313
branch: 1-1-stable
specs:
spree_paypal_express (1.1.0)
spree_auth (>= 1.0.0)
spree_core (>= 1.0.0)
GIT
remote: git://github.com/dancinglightning/spree-last-address.git
revision: f5ed71a5482fbc16da559737903bb46fe032c150
@@ -23,16 +14,25 @@ GIT
spree_core (>= 1.1)
GIT
remote: git://github.com/joneslee85/spree-heroku.git
revision: 63f0cfa47089cae50365e226ec7dd1eccde0ac05
remote: git://github.com/eaterprises/spree-heroku.git
revision: a1e07bf7a22fc0c07a1be9148f477d20b557dbf6
specs:
spree_heroku (1.0)
aws-sdk (~> 1.3.4)
spree_core (>= 0.70.0)
GIT
remote: git://github.com/eaterprises/spree_paypal_express.git
revision: 7dd46e6e549d82c4d603f685a7cb7fbb4af0d973
branch: 1-1-stable
specs:
spree_paypal_express (1.1.0)
spree_auth (>= 1.0.0)
spree_core (>= 1.0.0)
GIT
remote: git://github.com/spree/spree.git
revision: d66ffac9088d0d5d0b0d146f305044ce619f0464
revision: 46691e075129fd3d7b59e296d73149a9066c1b9d
branch: 1-1-stable
specs:
spree (1.1.3)
@@ -63,7 +63,7 @@ GIT
jquery-rails (~> 2.0)
kaminari (= 0.13.0)
nested_set (= 1.7.0)
paperclip (~> 2.7)
paperclip (~> 2.8)
rails (~> 3.2.8)
ransack (~> 0.6.0)
state_machine (= 1.1.2)
@@ -129,25 +129,21 @@ GEM
i18n (~> 0.6)
multi_json (~> 1.0)
acts_as_list (0.1.4)
addressable (2.2.8)
addressable (2.3.2)
andand (1.3.3)
ansi (1.4.2)
arel (3.0.2)
awesome_print (1.0.2)
aws-s3 (0.6.3)
builder
mime-types
xml-simple
aws-sdk (1.3.9)
httparty (~> 0.7)
json (~> 1.4)
nokogiri (>= 1.4.4)
uuidtools (~> 2.1)
bcrypt-ruby (3.0.1)
bugsnag (1.1.2)
httparty (~> 0.8.3)
multi_json (~> 1.3.4)
builder (3.0.3)
bugsnag (1.2.4)
httparty (>= 0.5, < 1.0)
multi_json (~> 1.0)
builder (3.0.4)
cancan (1.6.7)
capybara (1.1.2)
mime-types (>= 1.16)
@@ -156,9 +152,9 @@ GEM
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 0.1.4)
childprocess (0.3.2)
ffi (~> 1.0.6)
cocaine (0.4.0)
childprocess (0.3.6)
ffi (~> 1.0, >= 1.0.6)
cocaine (0.4.2)
coderay (1.0.7)
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
@@ -200,7 +196,7 @@ GEM
faker (1.0.1)
i18n (~> 0.4)
ffaker (1.12.1)
ffi (1.0.11)
ffi (1.1.5)
haml (3.1.6)
highline (1.6.11)
hike (1.2.1)
@@ -219,7 +215,7 @@ GEM
railties (>= 3.0.0)
kgio (2.7.4)
libv8 (3.3.10.4)
libwebsocket (0.1.3)
libwebsocket (0.1.5)
addressable
mail (2.4.4)
i18n (>= 0.4.0)
@@ -299,15 +295,14 @@ GEM
activesupport (>= 3.0)
railties (>= 3.0)
rspec (~> 2.10.0)
rubyzip (0.9.8)
rubyzip (0.9.9)
sass (3.1.19)
sass-rails (3.2.5)
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
selenium-webdriver (2.22.2)
selenium-webdriver (2.25.0)
childprocess (>= 0.2.5)
ffi (~> 1.0)
libwebsocket (~> 0.1.3)
multi_json (~> 1.0)
rubyzip
@@ -325,13 +320,13 @@ GEM
libv8 (~> 3.3.10)
thor (0.16.0)
tilt (1.3.3)
treetop (1.4.11)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
truncate_html (0.5.5)
turn (0.8.3)
ansi
tzinfo (0.3.33)
tzinfo (0.3.34)
uglifier (1.2.4)
execjs (>= 0.3.0)
multi_json (>= 1.0.2)
@@ -342,7 +337,6 @@ GEM
uuidtools (2.1.3)
warden (1.1.1)
rack (>= 1.0)
xml-simple (1.1.1)
xpath (0.1.4)
nokogiri (~> 1.3)
@@ -352,7 +346,7 @@ PLATFORMS
DEPENDENCIES
andand
awesome_print
aws-s3
aws-sdk
bugsnag
capybara
coffee-rails (~> 3.2.1)

View File

@@ -20,11 +20,11 @@ hosted at GitHub.
You can view the code at:
https://github.com/andrewspinks/openfoodweb
https://github.com/eaterprises/openfoodweb
You can download the source with the command:
git clone git@github.com:andrewspinks/openfoodweb
git clone git@github.com:eaterprises/openfoodweb
## Get it running
@@ -80,6 +80,7 @@ speak to Andrew Spinks.
* Andrew Spinks (http://github.com/andrewspinks)
* Rohan Mitchell (http://github.com/rohanm)
* Rob Harrington (http://github.com/oeoeaio)
## Licence

View File

@@ -10,6 +10,15 @@ $(document).ready(function() {
// Product page with master price only
$(".add-to-cart input.title:not(#quantity):not(.max_quantity)").change(products_update_price_without_variant).change();
// Product page other
$("#distributor_id").change(function() {
var distributor_html = distributors[$(this).val()];
if(!distributor_html) {
distributor_html = 'When you select a distributor for your order, their address and pickup times will be displayed here.';
}
$("#product-distributor-details .distributor-details").html(distributor_html);
});
});

View File

@@ -144,6 +144,19 @@ ul.product-listing {
}
/* Distributor details on product details page */
fieldset#product-distributor-details {
float: right;
margin-top: 0;
width: 250px;
@extend #shipping;
}
#product-variants {
float: none;
}
/* Add to cart form on product details page */
#cart-form {
.error-distributor {

View File

@@ -0,0 +1,28 @@
module Admin
class DistributorsController < ResourceController
before_filter :load_distributor_set, :only => :index
before_filter :load_countries, :except => :index
def bulk_update
@distributor_set = DistributorSet.new(params[:distributor_set])
if @distributor_set.save
redirect_to main_app.admin_distributors_path, :notice => 'Distributor collection times updated.'
else
render :index
end
end
private
def load_distributor_set
@distributor_set = DistributorSet.new :distributors => collection
end
def load_countries
@countries = Spree::Country.order(:name)
end
def collection
super.order(:name)
end
end
end

View File

@@ -0,0 +1,42 @@
module Admin
class ResourceController < Spree::Admin::ResourceController
def model_class
"#{controller_name.classify}".constantize
end
# URL helpers
def new_object_url(options = {})
if parent_data.present?
main_app.new_polymorphic_url([:admin, parent, model_class], options)
else
main_app.new_polymorphic_url([:admin, model_class], options)
end
end
def edit_object_url(object, options = {})
if parent_data.present?
main_app.send "edit_admin_#{model_name}_#{object_name}_url", parent, object, options
else
main_app.send "edit_admin_#{object_name}_url", object, options
end
end
def object_url(object = nil, options = {})
target = object ? object : @object
if parent_data.present?
main_app.send "admin_#{model_name}_#{object_name}_url", parent, target, options
else
main_app.send "admin_#{object_name}_url", target, options
end
end
def collection_url(options = {})
if parent_data.present?
main_app.polymorphic_url([:admin, parent, model_class], options)
else
main_app.polymorphic_url([:admin, model_class], options)
end
end
end
end

View File

@@ -0,0 +1,16 @@
module Admin
class SuppliersController < ResourceController
before_filter :load_data, :except => [:index]
helper 'spree/products'
private
def load_data
@countries = Spree::Country.order(:name)
end
def collection
super.order(:name)
end
end
end

View File

@@ -11,8 +11,8 @@ class ApplicationController < ActionController::Base
def load_data_for_sidebar
@suppliers = Spree::Supplier.all
@distributors = Spree::Distributor.with_active_products_on_hand.by_name
@suppliers = Supplier.all
@distributors = Distributor.with_active_products_on_hand.by_name
end
end

View File

@@ -0,0 +1,10 @@
class BaseController < ApplicationController
include Spree::Core::ControllerHelpers
include Spree::Core::RespondWith
helper 'spree/base'
# Spree::Core::ControllerHelpers declares helper_method get_taxonomies, so we need to
# include Spree::ProductsHelper so that method is available on the controller
include Spree::ProductsHelper
end

View File

@@ -0,0 +1,45 @@
class DistributorsController < BaseController
def index
@distributors = Distributor.all
respond_to do |format|
format.js do
@distributor_details = Hash[@distributors.map { |d| [d.id, render_to_string(:partial => 'distributors/details', :locals => {:distributor => d})] }]
end
end
end
def show
options = {:distributor_id => params[:id]}
options.merge(params.reject { |k,v| k == :id })
@distributor = Distributor.find params[:id]
@searcher = Spree::Config.searcher_class.new(options)
@products = @searcher.retrieve_products
end
def select
distributor = Distributor.find params[:id]
order = current_order(true)
if order.can_change_distributor?
order.distributor = distributor
order.save!
end
redirect_to distributor
end
def deselect
order = current_order(true)
if order.can_change_distributor?
order.distributor = nil
order.save!
end
redirect_to root_path
end
end

View File

@@ -1,30 +0,0 @@
module Spree
module Admin
class DistributorsController < ResourceController
before_filter :load_distributor_set, :only => :index
before_filter :load_countries, :except => :index
def bulk_update
@distributor_set = DistributorSet.new(params[:distributor_set])
if @distributor_set.save
redirect_to admin_distributors_path, :notice => 'Distributor collection times updated.'
else
render :index
end
end
private
def load_distributor_set
@distributor_set = Spree::DistributorSet.new :distributors => collection
end
def load_countries
@countries = Country.order(:name)
end
def collection
super.order(:name)
end
end
end
end

View File

@@ -1,11 +1,15 @@
require 'csv'
require 'open_food_web/order_and_distributor_report'
require 'open_food_web/group_buy_report'
require 'open_food_web/order_grouper'
Spree::Admin::ReportsController.class_eval do
Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:orders_and_distributors => {:name => "Orders And Distributors", :description => "Orders with distributor details"}})
Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:group_buys => {:name => "Group Buys", :description => "Orders by supplier and variant"}})
Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:bulk_coop => {:name => "Bulk Co-Op", :description => "Reports for Bulk Co-Op orders"}})
Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:payments => {:name => "Payment Reports", :description => "Reports for Payments"}})
Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:order_cycles => {:name => "Order Cycle Reports", :description => "Reports for Order Cycles"}})
def orders_and_distributors
params[:q] = {} unless params[:q]
@@ -53,7 +57,7 @@ Spree::Admin::ReportsController.class_eval do
@search = Spree::Order.complete.search(params[:q])
orders = @search.result
@distributors = Spree::Distributor.all
@distributors = Distributor.all
@report = OpenFoodWeb::GroupBuyReport.new orders
unless params[:csv]
@@ -67,4 +71,424 @@ Spree::Admin::ReportsController.class_eval do
end
end
end
def bulk_coop
params[:q] = {} unless params[:q]
if params[:q][:created_at_gt].blank?
params[:q][:created_at_gt] = Time.zone.now.beginning_of_month
else
params[:q][:created_at_gt] = Time.zone.parse(params[:q][:created_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
end
if params[:q] && !params[:q][:created_at_lt].blank?
params[:q][:created_at_lt] = Time.zone.parse(params[:q][:created_at_lt]).end_of_day rescue ""
end
params[:q][:meta_sort] ||= "created_at.desc"
@search = Spree::Order.complete.search(params[:q])
orders = @search.result
line_items = orders.map { |o| o.line_items }.flatten
@distributors = Distributor.all
@report_type = params[:report_type]
case params[:report_type]
when "bulk_coop_supplier_report"
header = ["Supplier", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total"]
columns = [ proc { |lis| lis.first.variant.product.supplier.name },
proc { |lis| lis.first.variant.product.name },
proc { |lis| "UNIT SIZE" },
proc { |lis| lis.first.variant.options_text },
proc { |lis| lis.first.variant.weight || 0 },
proc { |lis| lis.sum { |li| li.quantity } },
proc { |lis| lis.sum { |li| li.max_quantity || 0 } } ]
rules = [ { group_by: proc { |li| li.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |li| li.variant.product },
sort_by: proc { |product| product.name },
summary_columns: [ proc { |lis| lis.first.variant.product.supplier.name },
proc { |lis| lis.first.variant.product.name },
proc { |lis| "UNIT SIZE" },
proc { |lis| "" },
proc { |lis| "" },
proc { |lis| lis.sum { |li| li.quantity * li.variant.weight || 0 } },
proc { |lis| lis.sum { |li| (li.max_quantity || 0) * li.variant.weight || 0 } } ] },
{ group_by: proc { |li| li.variant },
sort_by: proc { |variant| variant.options_text } } ]
when "bulk_coop_allocation"
header = ["Customer", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total"]
columns = [ proc { |lis| lis.first.order.bill_address.firstname + " " + lis.first.order.bill_address.lastname },
proc { |lis| lis.first.variant.product.name },
proc { |lis| "UNIT SIZE" },
proc { |lis| lis.first.variant.options_text },
proc { |lis| lis.first.variant.weight || 0 },
proc { |lis| lis.sum { |li| li.quantity } },
proc { |lis| lis.sum { |li| li.max_quantity || 0 } } ]
rules = [ { group_by: proc { |li| li.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |li| li.variant },
sort_by: proc { |variant| variant.options_text } },
{ group_by: proc { |li| li.order.user },
sort_by: proc { |user| user.to_s } } ]
when "bulk_coop_packing_sheets"
header = ["Customer", "Product", "Variant", "Sum Total"]
columns = [ proc { |lis| lis.first.order.bill_address.firstname + " " + lis.first.order.bill_address.lastname },
proc { |lis| lis.first.variant.product.name },
proc { |lis| lis.first.variant.options_text },
proc { |lis| lis.sum { |li| li.quantity } } ]
rules = [ { group_by: proc { |li| li.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |li| li.variant },
sort_by: proc { |variant| variant.options_text } },
{ group_by: proc { |li| li.order.user },
sort_by: proc { |user| user.to_s } } ]
when "bulk_coop_customer_payments"
header = ["Customer", "Date of Order", "Total Cost", "Amount Owing", "Amount Paid"]
columns = [ proc { |lis| lis.first.order.bill_address.firstname + " " + lis.first.order.bill_address.lastname },
proc { |lis| lis.first.order.created_at.to_s },
proc { |lis| lis.map { |li| li.order }.uniq.sum { |o| o.total } },
proc { |lis| lis.map { |li| li.order }.uniq.sum { |o| o.outstanding_balance } },
proc { |lis| lis.map { |li| li.order }.uniq.sum { |o| o.payment_total } } ]
rules = [ { group_by: proc { |li| li.order.user },
sort_by: proc { |user| user.to_s } },
{ group_by: proc { |li| li.order },
sort_by: proc { |order| order.created_at } } ]
else # List all line items
header = ["Supplier", "Product", "Unit Size", "Variant", "Weight", "Sum Total", "Sum Max Total"]
columns = [ proc { |lis| lis.first.variant.product.supplier.name },
proc { |lis| lis.first.variant.product.name },
proc { |lis| "UNIT SIZE" },
proc { |lis| lis.first.variant.options_text },
proc { |lis| lis.first.variant.weight || 0 },
proc { |lis| lis.sum { |li| li.quantity } },
proc { |lis| lis.sum { |li| li.max_quantity || 0 } } ]
rules = [ { group_by: proc { |li| li.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |li| li.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |li| li.variant },
sort_by: proc { |variant| variant.options_text } } ]
end
order_grouper = OpenFoodWeb::OrderGrouper.new rules, columns
@header = header
@table = order_grouper.table(line_items)
csv_file_name = "bulk_coop.csv"
render_report(@header, @table, params[:csv], csv_file_name)
end
def payments
params[:q] = {} unless params[:q]
if params[:q][:created_at_gt].blank?
params[:q][:created_at_gt] = Time.zone.now.beginning_of_month
else
params[:q][:created_at_gt] = Time.zone.parse(params[:q][:created_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
end
if params[:q] && !params[:q][:created_at_lt].blank?
params[:q][:created_at_lt] = Time.zone.parse(params[:q][:created_at_lt]).end_of_day rescue ""
end
params[:q][:meta_sort] ||= "created_at.desc"
@search = Spree::Order.complete.search(params[:q])
orders = @search.result
payments = orders.map { |o| o.payments.select { |payment| payment.completed? } }.flatten # Only select completed payments
@distributors = Distributor.all
@report_type = params[:report_type]
case params[:report_type]
when "payments_by_payment_type"
table_items = payments
header = ["Payment State", "Distributor", "Payment Type", "Total ($)"]
columns = [ proc { |payments| payments.first.order.payment_state },
proc { |payments| payments.first.order.distributor.name },
proc { |payments| payments.first.payment_method.name },
proc { |payments| payments.sum { |payment| payment.amount } } ]
rules = [ { group_by: proc { |payment| payment.order.payment_state },
sort_by: proc { |payment_state| payment_state } },
{ group_by: proc { |payment| payment.order.distributor },
sort_by: proc { |distributor| distributor.name } },
{ group_by: proc { |payment| payment.payment_method },
sort_by: proc { |method| method.name } } ]
when "itemised_payment_totals"
table_items = orders
header = ["Payment State", "Distributor", "Product Total ($)", "Shipping Total ($)", "Outstanding Balance ($)", "Total ($)"]
columns = [ proc { |orders| orders.first.payment_state },
proc { |orders| orders.first.distributor.name },
proc { |orders| orders.sum { |o| o.item_total } },
proc { |orders| orders.sum { |o| o.ship_total } },
proc { |orders| orders.sum { |o| o.outstanding_balance } },
proc { |orders| orders.sum { |o| o.total } } ]
rules = [ { group_by: proc { |order| order.payment_state },
sort_by: proc { |payment_state| payment_state } },
{ group_by: proc { |order| order.distributor },
sort_by: proc { |distributor| distributor.name } } ]
when "payment_totals"
table_items = orders
header = ["Payment State", "Distributor", "Product Total ($)", "Shipping Total ($)", "Total ($)", "EFT ($)", "PayPal ($)", "Outstanding Balance ($)"]
columns = [ proc { |orders| orders.first.payment_state },
proc { |orders| orders.first.distributor.name },
proc { |orders| orders.sum { |o| o.item_total } },
proc { |orders| orders.sum { |o| o.ship_total } },
proc { |orders| orders.sum { |o| o.total } },
proc { |orders| orders.sum { |o| o.payments.select { |payment| payment.completed? && (payment.payment_method.name.to_s.include? "EFT") }.sum { |payment| payment.amount } } },
proc { |orders| orders.sum { |o| o.payments.select { |payment| payment.completed? && (payment.payment_method.name.to_s.include? "PayPal") }.sum{ |payment| payment.amount } } },
proc { |orders| orders.sum { |o| o.outstanding_balance } } ]
rules = [ { group_by: proc { |order| order.payment_state },
sort_by: proc { |payment_state| payment_state } },
{ group_by: proc { |order| order.distributor },
sort_by: proc { |distributor| distributor.name } } ]
else
table_items = payments
header = ["Payment State", "Distributor", "Payment Type", "Total ($)"]
columns = [ proc { |payments| payments.first.order.payment_state },
proc { |payments| payments.first.order.distributor.name },
proc { |payments| payments.first.payment_method.name },
proc { |payments| payments.sum { |payment| payment.amount } } ]
rules = [ { group_by: proc { |payment| payment.order.payment_state },
sort_by: proc { |payment_state| payment_state } },
{ group_by: proc { |payment| payment.order.distributor },
sort_by: proc { |distributor| distributor.name } },
{ group_by: proc { |payment| payment.payment_method },
sort_by: proc { |method| method.name } } ]
end
order_grouper = OpenFoodWeb::OrderGrouper.new rules, columns
@header = header
@table = order_grouper.table(table_items)
csv_file_name = "payments.csv"
render_report(@header, @table, params[:csv], csv_file_name)
end
def order_cycles
params[:q] = {} unless params[:q]
if params[:q][:created_at_gt].blank?
params[:q][:created_at_gt] = Time.zone.now.beginning_of_month
else
params[:q][:created_at_gt] = Time.zone.parse(params[:q][:created_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
end
if params[:q] && !params[:q][:created_at_lt].blank?
params[:q][:created_at_lt] = Time.zone.parse(params[:q][:created_at_lt]).end_of_day rescue ""
end
params[:q][:meta_sort] ||= "created_at.desc"
@search = Spree::Order.complete.search(params[:q])
orders = @search.result
line_items = orders.map { |o| o.line_items }.flatten
#payments = orders.map { |o| o.payments.select { |payment| payment.completed? } }.flatten # Only select completed payments
@distributors = Distributor.all
@report_type = params[:report_type]
case params[:report_type]
when "order_cycle_supplier_totals"
table_items = line_items
@include_blank = 'All'
header = ["Supplier", "Product", "Variant", "Amount", "Cost per Unit", "Total Cost", "Status", "Incoming Transport"]
columns = [ proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "status" },
proc { |line_items| "incoming transport" } ]
rules = [ { group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.options_text } } ]
when "order_cycle_supplier_totals_by_distributor"
table_items = line_items
@include_blank = 'All'
header = ["Supplier", "Product", "Variant", "To Distributor", "Amount", "Cost per Unit", "Total Cost", "Shipping Method"]
columns = [ proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| line_items.first.order.distributor.name },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "shipping method" } ]
rules = [ { group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.options_text },
summary_columns: [ proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| "TOTAL" },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "" } ] },
{ group_by: proc { |line_item| line_item.order.distributor },
sort_by: proc { |distributor| distributor.name } } ]
when "order_cycle_distributor_totals_by_supplier"
table_items = line_items
@include_blank = 'All'
header = ["Distributor", "Supplier", "Product", "Variant", "Amount", "Cost per Unit", "Total Cost", "Total Shipping Cost", "Shipping Method"]
columns = [ proc { |line_items| line_items.first.order.distributor.name },
proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "" },
proc { |line_items| "shipping method" } ]
rules = [ { group_by: proc { |line_item| line_item.order.distributor },
sort_by: proc { |distributor| distributor.name },
summary_columns: [ proc { |line_items| line_items.first.order.distributor.name },
proc { |line_items| "TOTAL" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "total shipping cost" },
proc { |line_items| "" } ] },
{ group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.options_text } } ]
when "order_cycle_customer_totals"
table_items = line_items
@include_blank = false
header = ["Customer", "Email", "Phone", "Product", "Variant", "Amount", "Total Cost", "Paid?", "Packed?", "Shipped?"]
columns = [ proc { |line_items| line_items.first.order.bill_address.firstname + " " + line_items.first.order.bill_address.lastname },
proc { |line_items| line_items.first.order.email },
proc { |line_items| line_items.first.order.bill_address.phone },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| "" } ]
rules = [ { group_by: proc { |line_item| line_item.order.user },
sort_by: proc { |user| user.to_s },
summary_columns: [ proc { |line_items| line_items.first.order.bill_address.firstname + " " + line_items.first.order.bill_address.lastname },
proc { |line_items| line_items.first.order.email },
proc { |line_items| line_items.first.order.bill_address.phone },
proc { |line_items| "TOTAL" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "work out whether paid or not" },
proc { |line_items| "" },
proc { |line_items| "" } ] },
{ group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.options_text } } ]
else
table_items = line_items
header = ["Supplier", "Product", "Variant", "Amount", "Cost per Unit", "Total Cost", "Status", "Incoming Transport"]
columns = [ proc { |line_items| line_items.first.variant.product.supplier.name },
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.options_text },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.variant.price } },
proc { |line_items| "status" },
proc { |line_items| "incoming transport" } ]
rules = [ { group_by: proc { |line_item| line_item.variant.product.supplier },
sort_by: proc { |supplier| supplier.name } },
{ group_by: proc { |line_item| line_item.variant.product },
sort_by: proc { |product| product.name } },
{ group_by: proc { |line_item| line_item.variant },
sort_by: proc { |variant| variant.options_text } } ]
end
order_grouper = OpenFoodWeb::OrderGrouper.new rules, columns
@header = header
@table = order_grouper.table(table_items)
csv_file_name = "order_cycles.csv"
render_report(@header, @table, params[:csv], csv_file_name)
end
def render_report (header, table, create_csv, csv_file_name)
unless create_csv
render :html => table
else
csv_string = CSV.generate do |csv|
csv << header
table.each { |row| csv << row }
end
send_data csv_string, :filename => csv_file_name
end
end
end

View File

@@ -1,16 +0,0 @@
module Spree
module Admin
class SuppliersController < ResourceController
before_filter :load_data, :except => [:index]
private
def load_data
@countries = Country.order(:name)
end
def collection
super.order(:name)
end
end
end
end

View File

@@ -1,39 +0,0 @@
module Spree
class DistributorsController < BaseController
helper 'spree/products'
def show
options = {:distributor_id => params[:id]}
options.merge(params.reject { |k,v| k == :id })
@distributor = Distributor.find params[:id]
@searcher = Config.searcher_class.new(options)
@products = @searcher.retrieve_products
end
def select
distributor = Distributor.find params[:id]
order = current_order(true)
if order.can_change_distributor?
order.distributor = distributor
order.save!
end
redirect_to distributor
end
def deselect
order = current_order(true)
if order.can_change_distributor?
order.distributor = nil
order.save!
end
redirect_to root_path
end
end
end

View File

@@ -1,7 +1,7 @@
require 'open_food_web/split_products_by_distributor'
Spree::HomeController.class_eval do
include Spree::DistributorsHelper
include DistributorsHelper
include OpenFoodWeb::SplitProductsByDistributor
respond_override :index => { :html => { :success => lambda {

View File

@@ -3,7 +3,7 @@ Spree::OrdersController.class_eval do
after_filter :populate_variant_attributes, :only => :populate
def populate_order_distributor
@distributor = params[:distributor_id].present? ? Spree::Distributor.find(params[:distributor_id]) : nil
@distributor = params[:distributor_id].present? ? Distributor.find(params[:distributor_id]) : nil
if populate_valid? @distributor
order = current_order(true)

View File

@@ -1,7 +1,7 @@
require 'open_food_web/split_products_by_distributor'
Spree::ProductsController.class_eval do
include Spree::DistributorsHelper
include DistributorsHelper
include OpenFoodWeb::SplitProductsByDistributor
respond_override :index => { :html => { :success => lambda {

View File

@@ -1,15 +0,0 @@
module Spree
class SuppliersController < BaseController
helper 'spree/products'
def show
options = {:supplier_id => params[:id]}
options.merge(params.reject { |k,v| k == :id })
@supplier = Supplier.find params[:id]
@searcher = Config.searcher_class.new(options)
@products = @searcher.retrieve_products
end
end
end

View File

@@ -1,7 +1,7 @@
require 'open_food_web/split_products_by_distributor'
Spree::TaxonsController.class_eval do
include Spree::DistributorsHelper
include DistributorsHelper
include OpenFoodWeb::SplitProductsByDistributor
respond_override :show => { :html => { :success => lambda {

View File

@@ -0,0 +1,15 @@
class SuppliersController < BaseController
def index
@suppliers = Supplier.all
end
def show
options = {:supplier_id => params[:id]}
options.merge(params.reject { |k,v| k == :id })
@supplier = Supplier.find params[:id]
@searcher = Spree::Config.searcher_class.new(options)
@products = @searcher.retrieve_products
end
end

View File

@@ -4,4 +4,15 @@ module ApplicationHelper
cms_page_content(:content, Cms::Page.find_by_full_path('/'))
end
end
# Pass URL helper calls on to spree where applicable so that we don't need to use
# spree.foo_path in any view rendered from non-spree-namespaced controllers.
def method_missing(method, *args, &block)
if (method.to_s.end_with?('_path') || method.to_s.end_with?('_url')) && spree.respond_to?(method)
spree.send(method, *args)
else
super
end
end
end

View File

@@ -0,0 +1,5 @@
module DistributorsHelper
def current_distributor
@current_distributor ||= current_order(false).andand.distributor
end
end

View File

@@ -1,7 +0,0 @@
module Spree
module DistributorsHelper
def current_distributor
@current_distributor ||= current_order(false).andand.distributor
end
end
end

31
app/models/distributor.rb Normal file
View File

@@ -0,0 +1,31 @@
class Distributor < ActiveRecord::Base
belongs_to :pickup_address, :foreign_key => 'pickup_address_id', :class_name => 'Spree::Address'
has_many :orders, :class_name => 'Spree::Order'
has_many :product_distributions, :dependent => :destroy
has_many :products, :through => :product_distributions
accepts_nested_attributes_for :pickup_address
validates_presence_of :name, :pickup_address
validates_associated :pickup_address
scope :by_name, order('name')
scope :with_active_products_on_hand, lambda { joins(:products).where('spree_products.deleted_at IS NULL AND spree_products.available_on <= ? AND spree_products.count_on_hand > 0', Time.now).select('distinct(distributors.*)') }
after_initialize :initialize_country
before_validation :set_unused_address_fields
def initialize_country
self.pickup_address ||= Spree::Address.new
self.pickup_address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id]) if self.pickup_address.new_record?
end
def set_unused_address_fields
pickup_address.firstname = pickup_address.lastname = pickup_address.phone = 'unused' if pickup_address.present?
end
def to_param
"#{id}-#{name.parameterize}"
end
end

View File

@@ -0,0 +1,34 @@
# Tableless model to handle updating multiple distributors at once from a
# single form. Used to update next_collection_at field for all distributors in
# admin backend.
class DistributorSet
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :distributors
def initialize(attributes={})
@distributors = Distributor.all
attributes.each do |name, value|
send("#{name}=", value)
end
end
def distributors_attributes=(attributes)
attributes.each do |k, attributes|
# attributes == {:id => 123, :next_collection_at => '...'}
d = @distributors.detect { |d| d.id.to_s == attributes[:id].to_s }
d.assign_attributes(attributes.except(:id))
end
end
def save
distributors.all?(&:save)
end
def persisted?
false
end
end

View File

@@ -0,0 +1,9 @@
class ProductDistribution < ActiveRecord::Base
belongs_to :product, :class_name => 'Spree::Product'
belongs_to :distributor
belongs_to :shipping_method, :class_name => 'Spree::ShippingMethod'
validates_presence_of :product_id, :on => :update
validates_presence_of :distributor_id, :shipping_method_id
validates_uniqueness_of :product_id, :scope => :distributor_id
end

View File

@@ -1,34 +0,0 @@
module Spree
class Distributor < ActiveRecord::Base
self.table_name = 'distributors'
belongs_to :pickup_address, :foreign_key => 'pickup_address_id', :class_name => 'Spree::Address'
has_many :orders
has_many :product_distributions, :dependent => :destroy
has_many :products, :through => :product_distributions
accepts_nested_attributes_for :pickup_address
validates_presence_of :name, :pickup_address
validates_associated :pickup_address
scope :by_name, order('name')
scope :with_active_products_on_hand, lambda { joins(:products).where('spree_products.deleted_at IS NULL AND spree_products.available_on <= ? AND spree_products.count_on_hand > 0', Time.now).select('distinct(distributors.*)') }
after_initialize :initialize_country
before_validation :set_unused_address_fields
def initialize_country
self.pickup_address ||= Address.new
self.pickup_address.country = Country.find_by_id(Spree::Config[:default_country_id]) if self.pickup_address.new_record?
end
def set_unused_address_fields
pickup_address.firstname = pickup_address.lastname = pickup_address.phone = 'unused' if pickup_address.present?
end
def to_param
"#{id}-#{name.parameterize}"
end
end
end

View File

@@ -1,36 +0,0 @@
# Tableless model to handle updating multiple distributors at once from a
# single form. Used to update next_collection_at field for all distributors in
# admin backend.
module Spree
class DistributorSet
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :distributors
def initialize(attributes={})
@distributors = Spree::Distributor.all
attributes.each do |name, value|
send("#{name}=", value)
end
end
def distributors_attributes=(attributes)
attributes.each do |k, attributes|
# attributes == {:id => 123, :next_collection_at => '...'}
d = @distributors.detect { |d| d.id.to_s == attributes[:id].to_s }
d.assign_attributes(attributes.except(:id))
end
end
def save
distributors.all?(&:save)
end
def persisted?
false
end
end
end

View File

@@ -6,7 +6,7 @@ Spree::Product.class_eval do
accepts_nested_attributes_for :product_distributions, :allow_destroy => true
attr_accessible :supplier_id, :distributor_ids, :product_distributions_attributes, :group_buy
attr_accessible :supplier_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size
validates_presence_of :supplier
@@ -23,7 +23,7 @@ Spree::Product.class_eval do
# Build a product distribution for each distributor
def build_product_distributions
Spree::Distributor.all.each do |distributor|
Distributor.all.each do |distributor|
unless self.product_distributions.find_by_distributor_id distributor.id
self.product_distributions.build(:distributor => distributor)
end

View File

@@ -1,13 +0,0 @@
module Spree
class ProductDistribution < ActiveRecord::Base
self.table_name = 'product_distributions'
belongs_to :product
belongs_to :distributor
belongs_to :shipping_method
validates_presence_of :product_id, :on => :update
validates_presence_of :distributor_id, :shipping_method_id
validates_uniqueness_of :product_id, :scope => :distributor_id
end
end

View File

@@ -1,28 +0,0 @@
module Spree
class Supplier < ActiveRecord::Base
self.table_name = 'suppliers'
has_many :products
belongs_to :address
accepts_nested_attributes_for :address
validates_presence_of :name, :address
validates_associated :address
after_initialize :initialize_country
before_validation :set_unused_address_fields
def initialize_country
self.address ||= Address.new
self.address.country = Country.find_by_id(Spree::Config[:default_country_id]) if self.address.new_record?
end
def set_unused_address_fields
address.firstname = address.lastname = address.phone = 'unused' if address.present?
end
def to_param
"#{id}-#{name.parameterize}"
end
end
end

33
app/models/supplier.rb Normal file
View File

@@ -0,0 +1,33 @@
class Supplier < ActiveRecord::Base
has_many :products, :class_name => 'Spree::Product'
belongs_to :address, :class_name => 'Spree::Address'
accepts_nested_attributes_for :address
validates_presence_of :name, :address
validates_associated :address
after_initialize :initialize_country
before_validation :set_unused_address_fields
def has_products_on_hand?
self.products.where('count_on_hand > 0').present?
end
def to_param
"#{id}-#{name.parameterize}"
end
private
def initialize_country
self.address ||= Spree::Address.new
self.address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id]) if self.address.new_record?
end
def set_unused_address_fields
address.firstname = address.lastname = address.phone = 'unused' if address.present?
end
end

View File

@@ -0,0 +1,9 @@
Deface::Override.new(:virtual_path => "spree/products/show",
:insert_before => "[data-hook='cart_form']",
:partial => "spree/products/distributor_details",
:name => "product_distributor_details")
Deface::Override.new(:virtual_path => "spree/products/show",
:insert_after => "[data-hook='product_show']",
:text => "<%= javascript_include_tag main_app.distributors_path(:format => :js) %>",
:name => "product_distributor_details_js")

View File

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

View File

@@ -1,11 +1,11 @@
Deface::Override.new(:virtual_path => "spree/layouts/admin",
:name => "distributors_admin_tabs",
:insert_bottom => "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
:text => "<%= tab(:distributors, :url => spree.admin_distributors_path) %>",
:text => "<%= tab(:distributors, :url => main_app.admin_distributors_path) %>",
:disabled => false)
Deface::Override.new(:virtual_path => "spree/layouts/admin",
:name => "suppliers_admin_tabs",
:insert_bottom => "[data-hook='admin_tabs'], #admin_tabs[data-hook]",
:text => "<%= tab(:suppliers, :url => spree.admin_suppliers_path) %>",
:disabled => false)
:text => "<%= tab(:suppliers, :url => main_app.admin_suppliers_path) %>",
:disabled => false)

View File

@@ -1,13 +1,13 @@
<div class="toolbar" data-hook="toolbar">
<ul class="actions">
<li>
<%= button_link_to "New Distributor", spree.new_admin_distributor_path, :icon => 'add', :id => 'admin_new_distributor_link' %>
<%= button_link_to "New Distributor", main_app.new_admin_distributor_path, :icon => 'add', :id => 'admin_new_distributor_link' %>
</li>
</ul>
<br class="clear" />
</div>
<%= form_for @distributor_set, :url => bulk_update_admin_distributors_path do |f| %>
<%= form_for @distributor_set, :url => main_app.bulk_update_admin_distributors_path do |f| %>
<table class="index" id="listing_distributors">
<thead>
<tr data-hook="distributors_header">
@@ -21,7 +21,7 @@
<%= f.fields_for :distributors do |distributor_form| %>
<% distributor = distributor_form.object %>
<tr>
<td><%= link_to distributor.name, spree.admin_distributor_path(distributor) %></td>
<td><%= link_to distributor.name, main_app.admin_distributor_path(distributor) %></td>
<td><%= distributor_form.text_field :next_collection_at %></td>
<td><%= distributor.description %></td>
<td data-hook="admin_users_index_row_actions">

View File

@@ -1,7 +1,7 @@
<%= render :partial => 'spree/shared/error_messages', :locals => { :target => @distributor } %>
<%= form_for [:admin, @distributor] do |f| %>
<%= form_for [main_app, :admin, @distributor] do |f| %>
<%= render :partial => 'form', :locals => { :f => f } %>
<%= render :partial => 'spree/admin/shared/new_resource_links' %>
<% end %>

View File

@@ -37,6 +37,6 @@
%th URL:
%td= @distributor.url
%p
= link_to :Edit, spree.edit_admin_distributor_path(@distributor), :class => 'edit_distributor'
= link_to :Edit, main_app.edit_admin_distributor_path(@distributor), :class => 'edit_distributor'
= t(:or)
= link_to t(:back), spree.admin_distributors_path
= link_to t(:back), main_app.admin_distributors_path

View File

@@ -1,6 +1,6 @@
.toolbar{'data-hook' => "suppliers"}
%ul.actions
%li= button_link_to "New Supplier", spree.new_admin_supplier_path, :icon => 'add', :id => 'admin_new_supplier_link'
%li= button_link_to "New Supplier", main_app.new_admin_supplier_path, :icon => 'add', :id => 'admin_new_supplier_link'
%br.clear
%table#listing_suppliers.index
%thead
@@ -11,7 +11,7 @@
%tbody
- @suppliers.each do |supplier|
%tr
%td= link_to supplier.name, spree.admin_supplier_path(supplier)
%td= link_to supplier.name, main_app.admin_supplier_path(supplier)
%td= supplier.description
%td{'data-hook' => "admin_supplier_index_row_actions"}
= link_to_edit supplier, :class => 'edit'

View File

@@ -1,6 +1,5 @@
= render :partial => 'spree/shared/error_messages', :locals => { :target => @supplier }
= form_for [:admin, @supplier] do |f|
= form_for [main_app, :admin, @supplier] do |f|
= render :partial => 'form', :locals => { :f => f }
= render :partial => 'spree/admin/shared/new_resource_links'

View File

@@ -22,6 +22,6 @@
%th Twitter:
%td= @supplier.twitter
%p
= link_to :Edit, spree.edit_admin_supplier_path(@supplier), :class => 'edit_supplier'
= link_to :Edit, main_app.edit_admin_supplier_path(@supplier), :class => 'edit_supplier'
= t(:or)
= link_to t(:back), spree.admin_suppliers_path
= link_to t(:back), main_app.admin_suppliers_path

View File

@@ -0,0 +1,23 @@
%h2= distributor.name
%p
%strong Address:
%br/
= render 'spree/shared/address', :address => distributor.pickup_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.url, distributor.url if distributor.url

View File

@@ -0,0 +1 @@
distributors = <%= @distributor_details.to_json.html_safe %>;

View File

@@ -0,0 +1,8 @@
<script type="text/javascript">
var uvOptions = {};
(function() {
var uv = document.createElement('script'); uv.type = 'text/javascript'; uv.async = true;
uv.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'widget.uservoice.com/mCbT1cbjQZkPELXOix9Ag.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(uv, s);
})();
</script>

View File

@@ -5,3 +5,8 @@
= f.label :group_buy_1, 'Yes'
= f.radio_button :group_buy, '0', :checked => !f.object.group_buy
= f.label :group_buy_0, 'No'
= f.field_container :group_buy_unit_size do
= f.label :group_buy_unit_size
%br
= f.text_field :group_buy_unit_size

View File

@@ -1,5 +1,5 @@
= f.field_container :supplier do
= f.label :supplier
%br
= f.collection_select(:supplier_id, Spree::Supplier.all, :id, :name, :include_blank => true)
= f.error_message_on :supplier
= f.collection_select(:supplier_id, Supplier.all, :id, :name, :include_blank => true)
= f.error_message_on :supplier

View File

@@ -0,0 +1,39 @@
= form_for @search, :url => spree.bulk_coop_admin_reports_path do |f|
= label_tag nil, t(:date_range)
%br
.date-range-filter
%div{"class" => "left sub-field"}
= f.text_field :created_at_gt, :class => 'datepicker'
%br
= label_tag nil, t(:start), :class => 'sub'
%div{"class" => "right sub-field"}
= f.text_field :created_at_lt, :class => 'datepicker'
%br
= label_tag nil, t(:stop)
%br
= label_tag nil, "Distributor: "
= f.collection_select(:distributor_id_eq, @distributors, :id, :name, :include_blank => 'All')
%br
= label_tag nil, "Report Type: "
= select_tag(:report_type, options_for_select([['Bulk Co-op - Totals by Supplier',:bulk_coop_supplier_report],['Bulk Co-op - Allocation',:bulk_coop_allocation],['Bulk Co-op - Packing Sheets',:bulk_coop_packing_sheets],['Bulk Co-op - Customer Payments',:bulk_coop_customer_payments]], @report_type))
%br
%br
= check_box_tag :csv
= label_tag :csv, "Download as csv"
%br
= button t(:search)
%br
%br
%table#listing_orders.index
%thead
%tr{'data-hook' => "orders_header"}
- @header.each do |heading|
%th=heading
%tbody
- @table.each do |row|
%tr
- row.each do |column|
%td= column
- if @table.empty?
%tr
%td{:colspan => "2"}= t(:none)

View File

@@ -0,0 +1,39 @@
= form_for @search, :url => spree.order_cycles_admin_reports_path do |f|
= label_tag nil, t(:date_range)
%br
.date-range-filter
%div{"class" => "left sub-field"}
= f.text_field :created_at_gt, :class => 'datepicker'
%br
= label_tag nil, t(:start), :class => 'sub'
%div{"class" => "right sub-field"}
= f.text_field :created_at_lt, :class => 'datepicker'
%br
= label_tag nil, t(:stop)
%br
= label_tag nil, "Distributor: "
= f.collection_select(:distributor_id_eq, @distributors, :id, :name, :include_blank => @include_blank)
%br
= label_tag nil, "Report Type: "
= select_tag(:report_type, options_for_select([['Order Cycle Supplier Totals',:order_cycle_supplier_totals], ['Order Cycle Supplier Totals by Distributor',:order_cycle_supplier_totals_by_distributor], ['Order Cycle Distributor Totals by Supplier',:order_cycle_distributor_totals_by_supplier], ['Order Cycle Customer Totals',:order_cycle_customer_totals]], @report_type))
%br
%br
= check_box_tag :csv
= label_tag :csv, "Download as csv"
%br
= button t(:search)
%br
%br
%table#listing_orders.index
%thead
%tr{'data-hook' => "orders_header"}
- @header.each do |heading|
%th=heading
%tbody
- @table.each do |row|
%tr
- row.each do |column|
%td= column
- if @table.empty?
%tr
%td{:colspan => "2"}= t(:none)

View File

@@ -0,0 +1,39 @@
= form_for @search, :url => spree.payments_admin_reports_path do |f|
= label_tag nil, t(:date_range)
%br
.date-range-filter
%div{"class" => "left sub-field"}
= f.text_field :created_at_gt, :class => 'datepicker'
%br
= label_tag nil, t(:start), :class => 'sub'
%div{"class" => "right sub-field"}
= f.text_field :created_at_lt, :class => 'datepicker'
%br
= label_tag nil, t(:stop)
%br
= label_tag nil, "Distributor: "
= f.collection_select(:distributor_id_eq, @distributors, :id, :name, :include_blank => 'All')
%br
= label_tag nil, "Report Type: "
= select_tag(:report_type, options_for_select([['Payments By Type',:payments_by_payment_type],['Itemised Payment Totals',:itemised_payment_totals],['Payment Totals',:payment_totals]], @report_type))
%br
%br
= check_box_tag :csv
= label_tag :csv, "Download as csv"
%br
= button t(:search)
%br
%br
%table#listing_orders.index
%thead
%tr{'data-hook' => "orders_header"}
- @header.each do |heading|
%th=heading
%tbody
- @table.each do |row|
%tr
- row.each do |column|
%td= column
- if @table.empty?
%tr
%td{:colspan => "2"}= t(:none)

View File

@@ -1,27 +1,4 @@
.columns.omega.six
%fieldset#shipping
%legend Distributor
%h2= @order.distributor.name
%p
%strong Address:
%br/
= render 'spree/shared/address', :address => @order.distributor.pickup_address
%p
%strong Next collection time:
%br/
= @order.distributor.next_collection_at
%p
%strong Regular collection times:
%br/
= @order.distributor.pickup_times
%p
%strong Contact:
%br/
= @order.distributor.contact
%br/
= "Phone: #{@order.distributor.phone}"
%br/
= "Email: #{@order.distributor.email}"
%p= @order.distributor.description
%p= link_to @order.distributor.url, @order.distributor.url if @order.distributor.url
= render 'distributors/details', :distributor => @order.distributor

View File

@@ -17,7 +17,7 @@
- order = current_order(false)
- if order.nil? || order.can_change_distributor?
%p Distributor
= select_tag "distributor_id", options_from_collection_for_select([Spree::Distributor.new]+@product.distributors, "id", "name", current_distributor.andand.id)
= select_tag "distributor_id", options_from_collection_for_select([Distributor.new]+@product.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}"

View File

@@ -0,0 +1,8 @@
%fieldset#product-distributor-details.columns.five.omega
%legend Distributor
.distributor-details
- order = current_order(false)
- if order.andand.distributor.present?
= render 'distributors/details', :distributor => order.distributor
- else
When you select a distributor for your order, their address and pickup times will be displayed here.

View File

@@ -2,7 +2,9 @@
%h6.filter_name Shop by Supplier
%ul.filter_choices
- @suppliers.each do |supplier|
%li.nowrap= link_to supplier.name, supplier
- if supplier.has_products_on_hand?
%li.nowrap= link_to supplier.name, [main_app, supplier]
= button_to 'Browse All Suppliers', main_app.suppliers_path, :method => :get
%h6.filter_name Shop by Distributor
%ul.filter_choices
@@ -10,10 +12,10 @@
- @distributors.each do |distributor|
%li.nowrap
- if order.nil? || order.can_change_distributor?
= link_to distributor.name, select_distributor_path(distributor)
= link_to distributor.name, main_app.select_distributor_path(distributor)
- elsif order.distributor == distributor
= link_to distributor.name, distributor
= link_to distributor.name, [main_app, distributor]
- else
%span.inactive= distributor.name
- if current_distributor && order.can_change_distributor?
= button_to 'Browse All Distributors', deselect_distributors_path, :method => :get
= button_to 'Browse All Distributors', main_app.deselect_distributors_path, :method => :get

View File

@@ -0,0 +1,12 @@
- content_for :sidebar do
%div{'data-hook' => "homepage_sidebar_navigation"}
= render 'spree/sidebar'
%h1 Suppliers
= cms_page_content(:content, Cms::Page.find_by_full_path('/suppliers'))
%ul.suppliers
- @suppliers.each do |supplier|
%li= link_to supplier.name, supplier

View File

@@ -28,3 +28,8 @@ Openfoodweb::Application.configure do
# Expands the lines which load the assets
config.assets.debug = true
end
# Load heroku vars from local file
heroku_env = File.join(Rails.root, 'config', 'heroku_env.rb')
load(heroku_env) if File.exists?(heroku_env)

View File

@@ -34,8 +34,15 @@ ComfortableMexicanSofa.configure do |config|
# the upload method and appropriate settings based on Paperclip. For S3 see:
# http://rdoc.info/gems/paperclip/2.3.8/Paperclip/Storage/S3, and for
# filesystem see: http://rdoc.info/gems/paperclip/2.3.8/Paperclip/Storage/Filesystem
# config.upload_file_options = {:url => '/system/:class/:id/:attachment/:style/:filename'}
config.upload_file_options = {
:storage => 's3',
:s3_credentials => {
:bucket => ENV['S3_BUCKET'],
:access_key_id => ENV['S3_KEY'],
:secret_access_key => ENV['S3_SECRET']
}
}
# Sofa allows you to setup entire site from files. Database is updated with each
# request (if necessary). Please note that database entries are destroyed if there's
# no corresponding file. Fixtures are disabled by default.

View File

@@ -1,10 +1,6 @@
Openfoodweb::Application.routes.draw do
# Mount Spree's routes
mount Spree::Core::Engine, :at => '/'
end
root :to => 'spree/home#index'
Spree::Core::Engine.routes.prepend do
resources :suppliers
resources :distributors do
get :select, :on => :member
@@ -18,7 +14,15 @@ Spree::Core::Engine.routes.prepend do
resources :suppliers
end
# Mount Spree's routes
mount Spree::Core::Engine, :at => '/'
end
Spree::Core::Engine.routes.prepend do
match '/admin/reports/orders_and_distributors' => 'admin/reports#orders_and_distributors', :as => "orders_and_distributors_admin_reports", :via => [:get, :post]
match '/admin/reports/group_buys' => 'admin/reports#group_buys', :as => "group_buys_admin_reports", :via => [:get, :post]
match '/admin/reports/bulk_coop' => 'admin/reports#bulk_coop', :as => "bulk_coop_admin_reports", :via => [:get, :post]
match '/admin/reports/payments' => 'admin/reports#payments', :as => "payments_admin_reports", :via => [:get, :post]
match '/admin/reports/order_cycles' => 'admin/reports#order_cycles', :as => "order_cycles_admin_reports", :via => [:get, :post]
end

View File

@@ -1,8 +0,0 @@
developement:
bucket: openfoodweb_test
access_key_id: AKIAJ3EE2EKGP36D4PUA
secret_access_key: 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
production:
bucket: openfoodweb_production
access_key_id: AKIAJ3EE2EKGP36D4PUA
secret_access_key: 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

View File

@@ -8,7 +8,7 @@ class MoveDistributorFromOrderToProduct < ActiveRecord::Migration
end
# Associate all products with the first distributor
distributor = Spree::Distributor.first
distributor = Distributor.first
if distributor
Spree::Product.all.each do |product|
product.distributors << distributor

View File

@@ -2,9 +2,9 @@ class ExtractDistributorAndSupplierAddressToSpreeAddress < ActiveRecord::Migrati
def up
# -- Distributors
add_column :distributors, :pickup_address_id, :integer
Spree::Distributor.reset_column_information
Distributor.reset_column_information
Spree::Distributor.all.each do |distributor|
Distributor.all.each do |distributor|
pickup_address = Spree::Address.create!(:firstname => 'unused',
:lastname => 'unused',
:phone => 'unused',
@@ -24,9 +24,9 @@ class ExtractDistributorAndSupplierAddressToSpreeAddress < ActiveRecord::Migrati
# -- Suppliers
add_column :suppliers, :address_id, :integer
Spree::Supplier.reset_column_information
Supplier.reset_column_information
Spree::Supplier.all.each do |supplier|
Supplier.all.each do |supplier|
address = Spree::Address.create!(:firstname => 'unused',
:lastname => 'unused',
:phone => 'unused',
@@ -51,9 +51,9 @@ class ExtractDistributorAndSupplierAddressToSpreeAddress < ActiveRecord::Migrati
add_column :distributors, :post_code, :string
add_column :distributors, :state_id, :integer
add_column :distributors, :country_id, :integer
Spree::Distributor.reset_column_information
Distributor.reset_column_information
Spree::Distributor.all.each do |distributor|
Distributor.all.each do |distributor|
distributor[:pickup_address] = distributor.pickup_address.address1
distributor.city = distributor.pickup_address.city
distributor.post_code = distributor.pickup_address.zipcode
@@ -71,9 +71,9 @@ class ExtractDistributorAndSupplierAddressToSpreeAddress < ActiveRecord::Migrati
add_column :suppliers, :postcode, :string
add_column :suppliers, :state_id, :integer
add_column :suppliers, :country_id, :integer
Spree::Supplier.reset_column_information
Supplier.reset_column_information
Spree::Supplier.all.each do |supplier|
Supplier.all.each do |supplier|
supplier[:address] = supplier.address.address1
supplier.city = supplier.address.city
supplier.post_code = supplier.address.zipcode

View File

@@ -10,7 +10,7 @@ class RenameDistributorsProductsToProductDistributions < ActiveRecord::Migration
# Set default shipping method on all product distributions
sm = Spree::ShippingMethod.first
Spree::ProductDistribution.update_all(:shipping_method_id => sm.id) if sm
ProductDistribution.update_all(:shipping_method_id => sm.id) if sm
end
def down

View File

@@ -0,0 +1,5 @@
class AddGroupBuyUnitSizeToProducts < ActiveRecord::Migration
def change
add_column :spree_products, :group_buy_unit_size, :string
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20121010004400) do
ActiveRecord::Schema.define(:version => 20121018002907) do
create_table "cms_blocks", :force => true do |t|
t.integer "page_id", :null => false
@@ -140,8 +140,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "abn"
t.string "acn"
t.string "description"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "pickup_address_id"
t.string "next_collection_at"
t.text "long_description"
@@ -183,8 +183,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "alternative_phone"
t.integer "state_id"
t.integer "country_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "company"
end
@@ -193,12 +193,12 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
create_table "spree_adjustments", :force => true do |t|
t.integer "source_id"
t.decimal "amount", :precision => 8, :scale => 2, :default => 0.0
t.decimal "amount", :precision => 8, :scale => 2
t.string "label"
t.string "source_type"
t.integer "adjustable_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.boolean "mandatory"
t.boolean "locked"
t.integer "originator_id"
@@ -230,15 +230,15 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "type"
t.integer "calculable_id", :null => false
t.string "calculable_type", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_configurations", :force => true do |t|
t.string "name"
t.string "type", :limit => 50
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "spree_configurations", ["name", "type"], :name => "index_configurations_on_name_and_type"
@@ -276,8 +276,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "environment", :default => "development"
t.string "server", :default => "test"
t.boolean "test_mode", :default => true
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_inventory_units", :force => true do |t|
@@ -285,8 +285,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "state"
t.integer "variant_id"
t.integer "order_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "shipment_id"
t.integer "return_authorization_id"
end
@@ -300,8 +300,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.integer "variant_id"
t.integer "quantity", :null => false
t.decimal "price", :precision => 8, :scale => 2, :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "max_quantity"
t.integer "shipping_method_id"
end
@@ -313,22 +313,22 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.integer "source_id"
t.string "source_type"
t.text "details"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_mail_methods", :force => true do |t|
t.string "environment"
t.boolean "active", :default => true
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_option_types", :force => true do |t|
t.string "name", :limit => 100
t.string "presentation", :limit => 100
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "position", :default => 0, :null => false
end
@@ -342,8 +342,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "name"
t.string "presentation"
t.integer "option_type_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_option_values_variants", :id => false, :force => true do |t|
@@ -362,8 +362,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.decimal "adjustment_total", :precision => 8, :scale => 2, :default => 0.0, :null => false
t.decimal "credit_total", :precision => 8, :scale => 2, :default => 0.0, :null => false
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "completed_at"
t.integer "bill_address_id"
t.integer "ship_address_id"
@@ -384,8 +384,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.text "description"
t.boolean "active", :default => true
t.string "environment", :default => "development"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "deleted_at"
t.string "display_on"
end
@@ -393,8 +393,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
create_table "spree_payments", :force => true do |t|
t.decimal "amount", :precision => 8, :scale => 2, :default => 0.0, :null => false
t.integer "order_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "source_id"
t.string "source_type"
t.integer "payment_method_id"
@@ -423,8 +423,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.integer "owner_id"
t.string "owner_type"
t.text "value"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "key"
t.string "value_type"
end
@@ -449,16 +449,16 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.integer "position"
t.integer "product_id"
t.integer "option_type_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_product_properties", :force => true do |t|
t.string "value"
t.integer "product_id"
t.integer "property_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "spree_product_properties", ["product_id"], :name => "index_product_properties_on_product_id"
@@ -482,11 +482,12 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "meta_keywords"
t.integer "tax_category_id"
t.integer "shipping_category_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "count_on_hand", :default => 0, :null => false
t.integer "supplier_id"
t.boolean "group_buy"
t.string "group_buy_unit_size"
end
add_index "spree_products", ["available_on"], :name => "index_products_on_available_on"
@@ -527,8 +528,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.integer "user_id"
t.integer "product_group_id"
t.string "type"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "spree_promotion_rules", ["product_group_id"], :name => "index_promotion_rules_on_product_group_id"
@@ -545,8 +546,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
create_table "spree_properties", :force => true do |t|
t.string "name"
t.string "presentation", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_properties_prototypes", :id => false, :force => true do |t|
@@ -556,8 +557,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
create_table "spree_prototypes", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_return_authorizations", :force => true do |t|
@@ -566,8 +567,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.decimal "amount", :precision => 8, :scale => 2, :default => 0.0, :null => false
t.integer "order_id"
t.text "reason"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_roles", :force => true do |t|
@@ -590,8 +591,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.integer "order_id"
t.integer "shipping_method_id"
t.integer "address_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "state"
end
@@ -599,15 +600,15 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
create_table "spree_shipping_categories", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_shipping_methods", :force => true do |t|
t.string "name"
t.integer "zone_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "display_on"
t.integer "shipping_category_id"
t.boolean "match_none"
@@ -623,8 +624,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.integer "transaction_id"
t.integer "customer_id"
t.string "payment_type"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_state_changes", :force => true do |t|
@@ -632,8 +633,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "previous_state"
t.integer "stateful_id"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "stateful_type"
t.string "next_state"
end
@@ -647,8 +648,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
create_table "spree_tax_categories", :force => true do |t|
t.string "name"
t.string "description"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.boolean "is_default", :default => false
t.datetime "deleted_at"
end
@@ -657,15 +658,15 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.decimal "amount", :precision => 8, :scale => 5
t.integer "zone_id"
t.integer "tax_category_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.boolean "included_in_price", :default => false
end
create_table "spree_taxonomies", :force => true do |t|
t.string "name", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_taxons", :force => true do |t|
@@ -674,8 +675,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "name", :null => false
t.string "permalink"
t.integer "taxonomy_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "lft"
t.integer "rgt"
t.string "icon_file_name"
@@ -693,8 +694,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.integer "permissable_id"
t.string "permissable_type"
t.string "token"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "spree_tokenized_permissions", ["permissable_id", "permissable_type"], :name => "index_tokenized_name_and_type"
@@ -703,8 +704,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "environment"
t.string "analytics_id"
t.boolean "active", :default => true
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_users", :force => true do |t|
@@ -725,8 +726,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "login"
t.integer "ship_address_id"
t.integer "bill_address_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "authentication_token"
t.string "unlock_token"
t.datetime "locked_at"
@@ -749,7 +750,7 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.boolean "is_master", :default => false
t.integer "product_id"
t.integer "count_on_hand", :default => 0, :null => false
t.decimal "cost_price", :precision => 8, :scale => 2, :default => 0.0
t.decimal "cost_price", :precision => 8, :scale => 2
t.integer "position"
end
@@ -759,15 +760,15 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.integer "zoneable_id"
t.string "zoneable_type"
t.integer "zone_id"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "spree_zones", :force => true do |t|
t.string "name"
t.string "description"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.boolean "default_tax", :default => false
t.integer "zone_members_count", :default => 0
end
@@ -778,8 +779,8 @@ ActiveRecord::Schema.define(:version => 20121010004400) do
t.string "email"
t.string "twitter"
t.string "website"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "address_id"
t.text "long_description"
end

View File

@@ -60,7 +60,7 @@ end
# -- Suppliers and distributors
unless Spree::Supplier.count > 0
unless Supplier.count > 0
puts "[db:seed] Seeding suppliers and distributors"
3.times { FactoryGirl.create(:supplier) }
@@ -74,19 +74,19 @@ unless Spree::Product.count > 0
FactoryGirl.create(:product,
:name => 'Garlic', :price => 20.00,
:supplier => Spree::Supplier.all[0],
:distributors => [Spree::Distributor.all[0]],
:supplier => Supplier.all[0],
:distributors => [Distributor.all[0]],
:taxons => [Spree::Taxon.find_by_name('Vegetables')])
FactoryGirl.create(:product,
:name => 'Fuji Apple', :price => 5.00,
:supplier => Spree::Supplier.all[1],
:distributors => Spree::Distributor.all,
:supplier => Supplier.all[1],
:distributors => Distributor.all,
:taxons => [Spree::Taxon.find_by_name('Fruit')])
FactoryGirl.create(:product,
:name => 'Beef - 5kg Trays', :price => 50.00,
:supplier => Spree::Supplier.all[2],
:distributors => [Spree::Distributor.all[2]],
:supplier => Supplier.all[2],
:distributors => [Distributor.all[2]],
:taxons => [Spree::Taxon.find_by_name('Meat and Fish')])
end

View File

@@ -38,8 +38,8 @@ module OpenFoodWeb
end
# Sum quantities for each product (Total line)
sum_quantities = line_items_by_product.sum { |li| li.variant.weight * li.quantity }
sum_max_quantities = line_items_by_product.sum { |li| li.variant.weight * (li.max_quantity || 0) }
sum_quantities = line_items_by_product.sum { |li| (li.variant.weight || 0) * li.quantity }
sum_max_quantities = line_items_by_product.sum { |li| (li.variant.weight || 0) * (li.max_quantity || 0) }
variants_and_quantities << GroupBuyProductRow.new(product, sum_quantities, sum_max_quantities)
end
end

View File

@@ -0,0 +1,58 @@
module OpenFoodWeb
class OrderGrouper
def initialize(rules, column_constructors)
@rules = rules
@column_constructors = column_constructors
end
def build_tree(items, remaining_rules)
rules = remaining_rules.clone
unless rules.empty?
rule = rules.delete_at(0) # Remove current rule for subsequent groupings
group_and_sort(rule, rules, items)
else
items
end
end
def group_and_sort(rule, remaining_rules, items)
branch = {}
groups = items.group_by { |item| rule[:group_by].call(item) }
sorted_groups = groups.sort_by { |key, value| rule[:sort_by].call(key) }
sorted_groups.each do |property,items_by_property|
branch[property] = build_tree(items_by_property, remaining_rules)
branch[property][:summary_row] = { items: items_by_property, columns: rule[:summary_columns] } unless rule[:summary_columns] == nil || is_leaf_node(branch[property])
end
branch
end
def build_table(groups)
rows = []
unless is_leaf_node(groups)
groups.each do |key, group|
unless key == :summary_row
build_table(group).each { |g| rows << g }
else
rows << group[:columns].map { |cols| cols.call(group[:items]) }
end
end
else
rows << @column_constructors.map { |column_constructor| column_constructor.call(groups) }
end
rows
end
def table(items)
tree = build_tree(items,@rules)
table = build_table(tree)
table
end
private
def is_leaf_node(node)
node.is_a? Array
end
end
end

View File

@@ -1,6 +1,6 @@
module Spree
module ProductFilters
if Spree::Distributor.table_exists?
if Distributor.table_exists?
Spree::Product.scope :distributor_any,
lambda {|*opts|
conds = opts.map {|o| ProductFilters.distributor_filter[:conds][o]}.reject {|c| c.nil?}
@@ -8,8 +8,8 @@ module Spree
}
def ProductFilters.distributor_filter
distributors = Spree::Distributor.all.map(&:name).compact.uniq
conds = Hash[*distributors.map { |d| [d, "#{Spree::Distributor.table_name}.name = '#{d}'"] }.flatten]
distributors = Distributor.all.map(&:name).compact.uniq
conds = Hash[*distributors.map { |d| [d, "#{Distributor.table_name}.name = '#{d}'"] }.flatten]
{ :name => "Group",
:scope => :distributor_any,
:conds => conds,

View File

@@ -1,7 +1,7 @@
require 'spec_helper'
require 'spree/core/current_order'
describe Spree::DistributorsController do
describe DistributorsController do
include Spree::Core::CurrentOrder
before :each do

View File

@@ -2,7 +2,7 @@ require 'faker'
require 'spree/core/testing_support/factories'
FactoryGirl.define do
factory :supplier, :class => Spree::Supplier do
factory :supplier, :class => Supplier do
sequence(:name) { |n| "Supplier #{n}" }
description 'supplier'
long_description '<p>Hello, world!</p><p>This is a paragraph.</p>'
@@ -10,7 +10,7 @@ FactoryGirl.define do
address { Spree::Address.first || FactoryGirl.create(:address) }
end
factory :distributor, :class => Spree::Distributor do
factory :distributor, :class => Distributor do
sequence(:name) { |n| "Distributor #{n}" }
contact 'Mr Turing'
phone '1000100100'
@@ -23,9 +23,9 @@ FactoryGirl.define do
pickup_address { Spree::Address.first || FactoryGirl.create(:address) }
end
factory :product_distribution, :class => Spree::ProductDistribution do
product { |pd| Spree::Product.first || FactoryGirl.create(:product) }
distributor { |pd| Spree::Distributor.first || FactoryGirl.create(:distributor) }
factory :product_distribution, :class => ProductDistribution do
product { |pd| Spree::Product.first || FactoryGirl.create(:product) }
distributor { |pd| Distributor.first || FactoryGirl.create(:distributor) }
shipping_method { |pd| Spree::ShippingMethod.where("name != 'Delivery'").first || FactoryGirl.create(:shipping_method) }
end
@@ -46,7 +46,7 @@ FactoryGirl.modify do
# When this fix has been merged into a version of Spree that we're using, this line can be removed.
sequence(:name) { |n| "Product ##{n} - #{Kernel.rand(9999)}" }
supplier { Spree::Supplier.first || FactoryGirl.create(:supplier) }
supplier { Supplier.first || FactoryGirl.create(:supplier) }
on_hand 3
# before(:create) do |product, evaluator|

View File

@@ -36,7 +36,7 @@ module OpenFoodWeb
@orders << order2
@supplier2 = create(:supplier)
@variant3 = create(:variant)
@variant3 = create(:variant, :weight => nil)
@variant3.product.supplier = @supplier2
@variant3.product.save!
product_distribution = create(:product_distribution, :product => @variant3.product, :distributor => distributor, :shipping_method => create(:shipping_method))
@@ -82,16 +82,16 @@ module OpenFoodWeb
table_row_objects = subject.variants_and_quantities
variant_rows = table_row_objects.select{ |r| r.class == OpenFoodWeb::GroupBuyVariantRow }
product_rows = table_row_objects.select{ |r| r.class == OpenFoodWeb::GroupBuyProductRow }
variant_rows = table_row_objects.select { |r| r.class == OpenFoodWeb::GroupBuyVariantRow }
product_rows = table_row_objects.select { |r| r.class == OpenFoodWeb::GroupBuyProductRow }
supplier_groups = variant_rows.group_by { |r| r.variant.product.supplier }
variant_groups = variant_rows.group_by{ |r| r.variant }
product_groups = product_rows.group_by{ |r| r.product }
variant_groups = variant_rows.group_by { |r| r.variant }
product_groups = product_rows.group_by { |r| r.product }
supplier_groups.length.should == 2
variant_groups.length.should == 3
product_groups.length.should == 3
end
end
end
end

View File

@@ -0,0 +1,152 @@
require 'spec_helper'
module OpenFoodWeb
describe OrderGrouper do
before(:each) do
@items = [1, 2, 3, 4]
end
context "constructing the table" do
it "should build a tree then build a table" do
rules = [ { group_by: Proc.new { |sentence| sentence.paragraph.chapter }, sort_by: Proc.new { |chapter| chapter.name }, summary_columns: [Proc.new { |is| is.first.paragraph.chapter.name }, Proc.new { |is| "TOTAL" }, Proc.new { |is| "" }, Proc.new { |is| is.sum {|i| i.property1 } } ] },
{ group_by: Proc.new { |sentence| sentence.paragraph }, sort_by: Proc.new { |paragraph| paragraph.name } } ]
columns = [Proc.new { |is| is.first.paragraph.chapter.name }, Proc.new { |is| is.first.paragraph.name }, Proc.new { |is| is.first.name }, Proc.new { |is| is.sum {|i| i.property1 } }]
subject = OrderGrouper.new rules, columns
tree = double(:tree)
subject.should_receive(:build_tree).with(@items, rules).and_return(tree)
subject.should_receive(:build_table).with(tree)
subject.table(@items)
end
end
context "grouping items without rules" do
it "returns the original array when no rules are provided" do
rules = []
column1 = double(:col1)
column2 = double(:col2)
columns = [column1, column2]
subject = OrderGrouper.new rules, columns
rules.should_receive(:clone).and_return(rules)
subject.build_tree(@items, rules).should == @items
end
end
context "grouping items with rules" do
before(:each) do
@rule1 = double(:rule1)
rule2 = double(:rule2)
@rules = [@rule1, rule2]
@remaining_rules = [rule2]
column1 = double(:col1)
column2 = double(:col2)
@columns = [column1, column2]
end
it "builds branches by removing a rule from 'rules' and running group_and_sort" do
subject = OrderGrouper.new @rules, @columns
@rules.should_receive(:clone).and_return(@rules)
@rules.should_receive(:delete_at).with(0)
grouped_tree = double(:grouped_tree)
subject.should_receive(:group_and_sort).and_return(grouped_tree)
subject.build_tree(@items, @rules).should == grouped_tree
end
it "separates the first rule from rules before sending to group_and_sort" do
subject = OrderGrouper.new @rules, @columns
grouped_tree = double(:grouped_tree)
subject.should_receive(:group_and_sort).with(@rule1, @rules[1..-1], @items).and_return(grouped_tree)
subject.build_tree(@items, @rules).should == grouped_tree
end
it "should group, then sort, send each group to build_tree, and return a branch" do
summary_columns_object = double(:summary_columns)
@rule1.stub(:[]).with(:summary_columns) { summary_columns_object }
subject = OrderGrouper.new @rules, @columns
number_of_categories = 3
groups = double(:groups)
@items.should_receive(:group_by).and_return(groups)
sorted_groups = {}
1.upto(number_of_categories) { |i| sorted_groups[i] = double(:group, name: "Group "+ i.to_s ) }
groups.should_receive(:sort_by).and_return(sorted_groups)
group = { group1: 1, group2: 2, group3: 3 }
subject.should_receive(:build_tree).exactly(number_of_categories).times.and_return(group)
group_tree = {}
1.upto(number_of_categories) { |i| group_tree[i] = group }
1.upto(number_of_categories) { |i| group_tree[i][:summary_row] = summary_columns_object }
subject.group_and_sort(@rule1, @remaining_rules, @items).should == group_tree
end
end
context "building the table Array" do
before(:each) do
rule1 = double(:rule1)
rule2 = double(:rule2)
@rules = [rule1, rule2]
@column1 = double(:col1, :call => "Column1")
@column2 = double(:col2, :call => "Column2")
@columns = [@column1, @column2]
sumcol1 = double(:sumcol1, :call => "SumColumn1")
sumcol2 = double(:sumcol2, :call => "SumColumn2")
@sumcols = [sumcol1, sumcol2]
item1 = double(:item1)
item2 = double(:item2)
item3 = double(:item3)
@items1 = [item1, item2]
@items2 = [item2, item3]
@items3 = [item3, item1]
end
it "should return columns when given an Array" do
subject = OrderGrouper.new @rules, @columns
@column1.should_receive(:call)
@column2.should_receive(:call)
subject.build_table(@items1).should == [["Column1", "Column2"]]
end
it "should return a row for each key-value pair when given a Hash" do
groups = { items1: @items1, items2: @items2, items3: @items3 }
subject = OrderGrouper.new @rules, @columns
#subject.should_receive(:build_table).exactly(2).times
expected_return = []
groups.length.times { expected_return << ["Column1", "Column2"] }
subject.build_table(groups).should == expected_return
end
it "should return an extra row when a :summary_row key appears in a given Hash" do
groups = { items1: @items1, items2: @items2, items3: @items3, summary_row: { items: { items2: @items2, items3: @items3 }, columns: @sumcols } }
subject = OrderGrouper.new @rules, @columns
expected_return = []
groups.each do |key, group|
if key == :summary_row
expected_return << ["SumColumn1", "SumColumn2"]
else
expected_return << ["Column1", "Column2"]
end
end
subject.build_table(groups).should == expected_return
end
end
end
end

View File

@@ -4,7 +4,7 @@ describe Spree::ProductFilters do
context "distributor filter" do
it "provides filtering for all distributors" do
3.times { create(:distributor) }
Spree::ProductFilters.distributor_filter[:labels].should == Spree::Distributor.all.map { |d| [d.name, d.name] }
Spree::ProductFilters.distributor_filter[:labels].should == Distributor.all.map { |d| [d.name, d.name] }
end
end
end

View File

@@ -1,6 +1,6 @@
require 'spec_helper'
describe Spree::ProductDistribution do
describe ProductDistribution do
it "is unique for scope [product, distributor]" do
pd1 = create(:product_distribution)
pd1.should be_valid

View File

@@ -8,14 +8,32 @@ module Spree
it { should belong_to(:address) }
end
it "should default country to system country" do
supplier = Supplier.new
supplier.address.country.should == Country.find_by_id(Config[:default_country_id])
end
describe "validations" do
it { should validate_presence_of(:name) }
end
it "should default country to system country" do
subject.address.country.should == Country.find_by_id(Config[:default_country_id])
end
context "has_products_on_hand?" do
before :each do
@supplier = create(:supplier)
end
it "returns false when no products" do
@supplier.should_not have_products_on_hand
end
it "returns false when the product is out of stock" do
create(:product, :supplier => @supplier, :on_hand => 0)
@supplier.should_not have_products_on_hand
end
it "returns true when the product is in stock" do
create(:product, :supplier => @supplier, :on_hand => 1)
@supplier.should have_products_on_hand
end
end
end
end

View File

@@ -74,7 +74,7 @@ feature %q{
# Then my times should have been saved
flash_message.should == 'Distributor collection times updated.'
Spree::Distributor.all.map { |d| d.next_collection_at }.should == %w(One Two Three)
Distributor.all.map { |d| d.next_collection_at }.should == %w(One Two Three)
end
end

View File

@@ -49,12 +49,14 @@ feature %q{
fill_in 'product_price', :with => '19.99'
select 'New supplier', :from => 'product_supplier_id'
choose 'product_group_buy_1'
fill_in 'Group buy unit size', :with => '10 kg'
click_button 'Create'
flash_message.should == 'Product "A new product !!!" has been successfully created!'
product = Spree::Product.find_by_name('A new product !!!')
product.group_buy.should be_true
product.group_buy_unit_size.should == '10 kg'
end
end

View File

@@ -22,4 +22,62 @@ feature %q{
page.should have_selector 'td', :text => d.name
end
describe "viewing distributor details" do
context "without Javascript" do
it "displays a holding message when no distributor is selected" do
p = create(:product)
visit spree.product_path p
page.should have_selector '#product-distributor-details', :text => 'When you select a distributor for your order, their address and pickup times will be displayed here.'
end
it "displays distributor details when one is selected" do
d = create(:distributor)
p = create(:product, :distributors => [d])
visit spree.root_path
click_link d.name
visit spree.product_path p
within '#product-distributor-details' do
[d.name,
d.pickup_address.address1,
d.pickup_address.city,
d.pickup_address.zipcode,
d.pickup_address.state_text,
d.pickup_address.country.name,
d.pickup_times,
d.next_collection_at,
d.contact,
d.phone,
d.email,
d.description,
d.url].each do |value|
page.should have_content value
end
end
end
end
context "with Javascript", js: true do
it "changes distributor details when the distributor is changed" do
d1 = create(:distributor)
d2 = create(:distributor)
d3 = create(:distributor)
p = create(:product, :distributors => [d1, d2, d3])
visit spree.product_path p
[d1, d2, d3].each do |d|
select d.name, :from => 'distributor_id'
within '#product-distributor-details' do
page.should have_selector 'h2', :text => d.name
end
end
end
end
end
end

View File

@@ -8,17 +8,43 @@ feature %q{
include AuthenticationWorkflow
include WebHelper
scenario "viewing a list of suppliers" do
scenario "viewing a list of suppliers in the sidebar" do
# Given some suppliers
s1 = create(:supplier)
s2 = create(:supplier)
s3 = create(:supplier)
# And some of those suppliers have a product
create(:product, :supplier => s1)
create(:product, :supplier => s3)
# When I go to the home page
visit spree.root_path
# Then I should see a list containing all the suppliers that have products in stock
page.should have_selector 'a', :text => s1.name
page.should have_selector 'a', :text => s3.name
page.should_not have_selector 'a', :text => s2.name
end
scenario "viewing a list of all suppliers" do
# Given some suppliers
s1 = create(:supplier)
s2 = create(:supplier)
s3 = create(:supplier)
# And some of those suppliers have a product
create(:product, :supplier => s1)
create(:product, :supplier => s3)
# When I go to the suppliers listing page
visit spree.root_path
click_button 'Browse All Suppliers'
# Then I should see a list containing all the suppliers
[s1, s2, s3].each { |s| page.should have_selector 'a', :text => s.name }
page.should have_selector '#content a', :text => s1.name
page.should have_selector '#content a', :text => s2.name
page.should have_selector '#content a', :text => s3.name
end
scenario "viewing products provided by a supplier" do

View File

@@ -1,7 +1,7 @@
# Initialise shipping method when created without one, like this:
# create(:product, :distributors => [...])
# In this case, we don't care what the shipping method is, but we need one for validations to pass.
Spree::ProductDistribution.class_eval do
ProductDistribution.class_eval do
before_validation :init_shipping_method
def init_shipping_method