Merge master into producer-emails.

This commit is contained in:
Paul Mackay
2015-03-04 19:09:43 +00:00
468 changed files with 11434 additions and 3239 deletions

View File

@@ -1,22 +1,50 @@
module Admin
class EnterpriseGroupsController < ResourceController
before_filter :load_data, except: :index
before_filter :load_object_data, only: [:new, :edit, :create, :update]
def index
@enterprise_groups = @enterprise_groups.managed_by(spree_current_user)
end
def move_up
@enterprise_group = EnterpriseGroup.find params[:enterprise_group_id]
@enterprise_group.move_higher
EnterpriseGroup.with_isolation_level_serializable do
@enterprise_group = EnterpriseGroup.find params[:enterprise_group_id]
@enterprise_group.move_higher
end
redirect_to main_app.admin_enterprise_groups_path
end
def move_down
@enterprise_group = EnterpriseGroup.find params[:enterprise_group_id]
@enterprise_group.move_lower
EnterpriseGroup.with_isolation_level_serializable do
@enterprise_group = EnterpriseGroup.find params[:enterprise_group_id]
@enterprise_group.move_lower
end
redirect_to main_app.admin_enterprise_groups_path
end
protected
def build_resource_with_address
enterprise_group = build_resource_without_address
enterprise_group.address = Spree::Address.new
enterprise_group.address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id])
enterprise_group
end
alias_method_chain :build_resource, :address
private
def load_data
@countries = Spree::Country.order(:name)
@enterprises = Enterprise.activated
end
def load_object_data
@owner_email = @enterprise_group.andand.owner.andand.email || ""
end
def collection
EnterpriseGroup.by_position
end

View File

@@ -1,13 +1,15 @@
module Admin
class EnterprisesController < ResourceController
before_filter :load_enterprise_set, :only => :index
before_filter :load_countries, :except => :index
before_filter :load_countries, :except => [:index, :set_sells, :check_permalink]
before_filter :load_methods_and_fees, :only => [:new, :edit, :update, :create]
before_filter :load_taxons, :only => [:new, :edit, :update, :create]
before_filter :check_can_change_sells, only: :update
before_filter :check_can_change_bulk_sells, only: :bulk_update
before_filter :override_owner, only: :create
before_filter :check_can_change_owner, only: :update
before_filter :check_can_change_bulk_owner, only: :bulk_update
before_filter :check_can_change_managers, only: :update
helper 'spree/products'
include OrderCyclesHelper
@@ -16,18 +18,44 @@ module Admin
@collection = order_cycle_permitted_enterprises
end
def set_sells
enterprise = Enterprise.find_by_permalink(params[:id]) || Enterprise.find(params[:id])
attributes = { sells: params[:sells] }
attributes[:producer_profile_only] = params[:sells] == "none" && !!params[:producer_profile_only]
attributes[:shop_trial_start_date] = Time.now if params[:sells] == "own"
if %w(none own).include?(params[:sells])
if params[:sells] == 'own' && enterprise.shop_trial_start_date
expiry = enterprise.shop_trial_start_date + Enterprise::SHOP_TRIAL_LENGTH.days
if Time.now > expiry
flash[:error] = "Sorry, but you've already had a trial. Expired on: #{expiry.strftime('%Y-%m-%d')}"
else
attributes.delete :shop_trial_start_date
enterprise.update_attributes(attributes)
flash[:notice] = "Welcome back! Your trial expires on: #{expiry.strftime('%Y-%m-%d')}"
end
elsif enterprise.update_attributes(attributes)
flash[:success] = "Congratulations! Registration for #{enterprise.name} is complete!"
end
else
flash[:error] = "Unauthorised"
end
redirect_to admin_path
end
def bulk_update
@enterprise_set = EnterpriseSet.new(params[:enterprise_set])
@enterprise_set = EnterpriseSet.new(collection, params[:enterprise_set])
if @enterprise_set.save
flash[:success] = 'Enterprises updated successfully'
redirect_to main_app.admin_enterprises_path
else
touched_ids = params[:enterprise_set][:collection_attributes].values.map { |v| v[:id].to_i }
@enterprise_set.collection.select! { |e| touched_ids.include? e.id }
flash[:error] = 'Update failed'
render :index
end
end
protected
def build_resource_with_address
@@ -38,11 +66,16 @@ module Admin
end
alias_method_chain :build_resource, :address
# Overriding method on Spree's resource controller,
# so that resources are found using permalink
def find_resource
Enterprise.find_by_permalink(params[:id])
end
private
def load_enterprise_set
@enterprise_set = EnterpriseSet.new :collection => collection
@enterprise_set = EnterpriseSet.new collection
end
def load_countries
@@ -50,8 +83,10 @@ module Admin
end
def collection
# TODO was ordered with is_distributor DESC as well, not sure why or how we want ot sort this now
Enterprise.managed_by(spree_current_user).order('is_primary_producer ASC, name')
# TODO was ordered with is_distributor DESC as well, not sure why or how we want to sort this now
OpenFoodNetwork::Permissions.new(spree_current_user).
editable_enterprises.
order('is_primary_producer ASC, name')
end
def collection_actions
@@ -64,6 +99,10 @@ module Admin
@enterprise_fees = EnterpriseFee.managed_by(spree_current_user).for_enterprise(@enterprise).order(:fee_type, :name).all
end
def load_taxons
@taxons = Spree::Taxon.order(:name)
end
def check_can_change_bulk_sells
unless spree_current_user.admin?
params[:enterprise_set][:collection_attributes].each do |i, enterprise_params|
@@ -94,6 +133,12 @@ module Admin
end
end
def check_can_change_managers
unless ( spree_current_user == @enterprise.owner ) || spree_current_user.admin?
params[:enterprise].delete :user_ids
end
end
# Overriding method on Spree's resource controller
def location_after_save
if params[:enterprise].key? :producer_properties_attributes

View File

@@ -12,7 +12,7 @@ module Admin
end
def load_enterprise
@enterprise = Enterprise.find params[:enterprise_id]
@enterprise = Enterprise.find_by_permalink params[:enterprise_id]
end
def load_properties

View File

@@ -0,0 +1,46 @@
require 'open_food_network/spree_api_key_loader'
module Admin
class VariantOverridesController < ResourceController
include OrderCyclesHelper
include OpenFoodNetwork::SpreeApiKeyLoader
before_filter :load_spree_api_key, only: :index
def index
@hubs = order_cycle_hub_enterprises(without_validation: true)
# Used in JS to look up the name of the producer of each product
@producers = OpenFoodNetwork::Permissions.new(spree_current_user).
variant_override_producers
@hub_permissions = OpenFoodNetwork::Permissions.new(spree_current_user).
variant_override_enterprises_per_hub
@variant_overrides = VariantOverride.for_hubs(@hubs)
end
def bulk_update
collection_hash = Hash[params[:variant_overrides].each_with_index.map { |vo, i| [i, vo] }]
vo_set = VariantOverrideSet.new collection_attributes: collection_hash
# Ensure we're authorised to update all variant overrides
vo_set.collection.each { |vo| authorize! :update, vo }
if vo_set.save
# Return saved VOs with IDs
render json: vo_set.collection, each_serializer: Api::Admin::VariantOverrideSerializer
else
if vo_set.errors.present?
render json: { errors: vo_set.errors }, status: 400
else
render nothing: true, status: 500
end
end
end
def collection
end
end
end

View File

@@ -3,6 +3,8 @@ module Api
before_filter :override_owner, only: [:create, :update]
before_filter :check_type, only: :update
before_filter :override_sells, only: [:create, :update]
before_filter :override_visible, only: [:create, :update]
respond_to :json
def managed
@@ -27,7 +29,7 @@ module Api
end
def update
@enterprise = Enterprise.find(params[:id])
@enterprise = Enterprise.find_by_permalink(params[:id]) || Enterprise.find(params[:id])
authorize! :update, @enterprise
if @enterprise.update_attributes(params[:enterprise])
@@ -38,7 +40,7 @@ module Api
end
def update_image
@enterprise = Enterprise.find(params[:id])
@enterprise = Enterprise.find_by_permalink(params[:id]) || Enterprise.find(params[:id])
authorize! :update, @enterprise
if params[:logo] && @enterprise.update_attributes( { logo: params[:logo] } )
@@ -59,5 +61,13 @@ module Api
def check_type
params[:enterprise].delete :type unless current_api_user.admin?
end
def override_sells
params[:enterprise][:sells] = 'unspecified'
end
def override_visible
params[:enterprise][:visible] = false
end
end
end

View File

@@ -32,6 +32,20 @@ class ApplicationController < ActionController::Base
end
end
def check_hub_ready_for_checkout
# This condition is more rigourous than required by development to avoid coupling this
# condition to every controller spec
if current_distributor && current_order &&
current_distributor.respond_to?(:ready_for_checkout?) &&
!current_distributor.ready_for_checkout?
current_order.empty!
current_order.set_distribution! nil, nil
flash[:info] = "The hub you have selected is temporarily closed for orders. Please try again later."
redirect_to root_url
end
end
def check_order_cycle_expiry
if current_order_cycle.andand.closed?
session[:expired_order_cycle_id] = current_order_cycle.id

View File

@@ -11,8 +11,19 @@ class BaseController < ApplicationController
include Spree::ProductsHelper
before_filter :check_order_cycle_expiry
def load_active_distributors
@active_distributors ||= Enterprise.distributors_with_active_order_cycles
end
private
def set_order_cycles
@order_cycles = OrderCycle.with_distributor(@distributor).active
# And default to the only order cycle if there's only the one
if @order_cycles.count == 1
current_order(true).set_order_cycle! @order_cycles.first
end
end
end

View File

@@ -1,6 +1,7 @@
class CheckoutController < Spree::CheckoutController
layout 'darkswarm'
prepend_before_filter :check_hub_ready_for_checkout
prepend_before_filter :check_order_cycle_expiry
prepend_before_filter :require_order_cycle
prepend_before_filter :require_distributor_chosen

View File

@@ -1,7 +0,0 @@
Devise::ConfirmationsController.class_eval do
protected
# Override of devise method in Devise::ConfirmationsController
def after_confirmation_path_for(resource_name, resource)
spree.admin_path
end
end

View File

@@ -0,0 +1,37 @@
class EnterpriseConfirmationsController < DeviseController
include Spree::Core::ControllerHelpers::Auth # Needed for access to current_ability, so we can authorize! actions
# GET /resource/confirmation/new
def new
build_resource({})
end
# POST /resource/confirmation
def create
self.resource = resource_class.find_by_unconfirmed_email_with_errors(resource_params)
authorize! :resend_confirmation, resource
self.resource = resource_class.send_confirmation_instructions(resource_params)
if successfully_sent?(resource)
set_flash_message(:success, :confirmation_sent) if is_navigational_format?
else
set_flash_message(:error, :confirmation_not_sent) if is_navigational_format?
end
respond_with_navigational(resource){ redirect_to spree.admin_path }
end
# GET /resource/confirmation?confirmation_token=abcdef
def show
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
if resource.errors.empty?
set_flash_message(:success, :confirmed) if is_navigational_format?
else
set_flash_message(:error, :not_confirmed) if is_navigational_format?
end
respond_with_navigational(resource){ redirect_to spree.admin_path }
end
end

View File

@@ -1,7 +1,14 @@
class EnterprisesController < BaseController
layout "darkswarm"
helper Spree::ProductsHelper
include OrderCyclesHelper
# These prepended filters are in the reverse order of execution
prepend_before_filter :load_active_distributors, :set_order_cycles, :require_distributor_chosen, :reset_order, only: :shop
before_filter :clean_permalink, only: :check_permalink
respond_to :js, only: :permalink_checker
def index
@enterprises = Enterprise.all
end
@@ -24,7 +31,7 @@ class EnterprisesController < BaseController
end
def show
@enterprise = Enterprise.find params[:id]
@enterprise = Enterprise.find_by_permalink(params[:id]) || Enterprise.find(params[:id])
# User can view this page if they've already chosen their distributor, or if this page
# is for a supplier, they may use it to select a distributor that sells this supplier's
@@ -52,8 +59,25 @@ class EnterprisesController < BaseController
end
end
def shop
distributor = Enterprise.is_distributor.find params[:id]
def check_permalink
return render text: params[:permalink], status: 409 if Enterprise.find_by_permalink params[:permalink]
path = Rails.application.routes.recognize_path( "/#{ params[:permalink].to_s }" )
if path && path[:controller] == "cms_content"
render text: params[:permalink], status: 200
else
render text: params[:permalink], status: 409
end
end
private
def clean_permalink
params[:permalink] = params[:permalink].parameterize
end
def reset_order
distributor = Enterprise.is_distributor.find_by_permalink(params[:id]) || Enterprise.is_distributor.find(params[:id])
order = current_order(true)
if order.distributor and order.distributor != distributor
@@ -66,7 +90,5 @@ class EnterprisesController < BaseController
order_cycle_options = OrderCycle.active.with_distributor(distributor)
order.order_cycle = order_cycle_options.first if order_cycle_options.count == 1
order.save!
redirect_to main_app.shop_path
end
end

View File

@@ -5,4 +5,8 @@ class GroupsController < BaseController
def index
@groups = EnterpriseGroup.on_front_page.by_position
end
def show
@group = EnterpriseGroup.find params[:id]
end
end

View File

@@ -20,7 +20,7 @@ module OpenFoodNetwork
def add_variant
@cart = Cart.find(params[:cart_id])
distributor = Enterprise.find(params[:distributor_id])
distributor = Enterprise.find_by_permalink(params[:distributor_id])
order_cycle = OrderCycle.find(params[:order_cycle_id]) if params[:order_cycle_id]
if @cart.add_variant params[:variant_id], params[:quantity], distributor, order_cycle, current_currency
@@ -36,4 +36,4 @@ module OpenFoodNetwork
Spree::Config[:currency]
end
end
end
end

View File

@@ -1,22 +1,21 @@
require 'open_food_network/scope_product_to_hub'
class ShopController < BaseController
layout "darkswarm"
before_filter :require_distributor_chosen
before_filter :set_order_cycles
before_filter :load_active_distributors
def show
redirect_to main_app.enterprise_shop_path(current_distributor)
end
def products
# Can we make this query less slow?
#
if @products = current_order_cycle.andand
.valid_products_distributed_by(current_distributor).andand
.select { |p| !p.deleted? && p.has_stock_for_distribution?(current_order_cycle, current_distributor) }.andand
.sort_by {|p| p.name }
if @products = products_for_shop
render status: 200,
json: ActiveModel::ArraySerializer.new(@products, each_serializer: Api::ProductSerializer,
current_order_cycle: current_order_cycle, current_distributor: current_distributor).to_json
json: ActiveModel::ArraySerializer.new(@products, each_serializer: Api::ProductSerializer,
current_order_cycle: current_order_cycle, current_distributor: current_distributor).to_json
else
render json: "", status: 404
end
@@ -37,12 +36,24 @@ class ShopController < BaseController
private
def set_order_cycles
@order_cycles = OrderCycle.with_distributor(@distributor).active
# And default to the only order cycle if there's only the one
if @order_cycles.count == 1
current_order(true).set_order_cycle! @order_cycles.first
def products_for_shop
if current_order_cycle
current_order_cycle.
valid_products_distributed_by(current_distributor).
order(taxon_order).
each { |p| p.scope_to_hub current_distributor }.
select { |p| !p.deleted? && p.has_stock_for_distribution?(current_order_cycle, current_distributor) }
end
end
def taxon_order
if current_distributor.preferred_shopfront_taxon_order.present?
current_distributor
.preferred_shopfront_taxon_order
.split(",").map { |id| "primary_taxon_id=#{id} DESC" }
.join(",") + ", name ASC"
else
"name ASC"
end
end
end

View File

@@ -1,4 +1,16 @@
Spree::Admin::BaseController.class_eval do
before_filter :warn_invalid_order_cycles
# Warn the user when they have an active order cycle with hubs that are not ready
# for checkout (ie. does not have valid shipping and payment methods).
def warn_invalid_order_cycles
distributors = active_distributors_not_ready_for_checkout
if distributors.any? && flash[:notice].nil?
flash[:notice] = active_distributors_not_ready_for_checkout_message(distributors)
end
end
# Override Spree method
# It's a shame Spree doesn't just let CanCan handle this in it's own way
def authorize_admin
@@ -23,4 +35,27 @@ Spree::Admin::BaseController.class_eval do
redirect_to root_path(anchor: "login?after_login=#{request.env['PATH_INFO']}")
end
end
private
def active_distributors_not_ready_for_checkout
ocs = OrderCycle.managed_by(spree_current_user).active
distributors = ocs.map(&:distributors).flatten.uniq
Enterprise.where('id IN (?)', distributors).not_ready_for_checkout
end
def active_distributors_not_ready_for_checkout_message(distributors)
distributor_names = distributors.map(&:name).join ', '
if distributors.count > 1
"The hubs #{distributor_names} are listed in an active order cycle, " +
"but do not have valid shipping and payment methods. " +
"Until you set these up, customers will not be able to shop at these hubs."
else
"The hub #{distributor_names} is listed in an active order cycle, " +
"but does not have valid shipping and payment methods. " +
"Until you set these up, customers will not be able to shop at this hub."
end
end
end

View File

@@ -4,6 +4,17 @@ Spree::Admin::OverviewController.class_eval do
@enterprises = Enterprise.managed_by(spree_current_user).order('is_primary_producer ASC, name')
@product_count = Spree::Product.active.managed_by(spree_current_user).count
@order_cycle_count = OrderCycle.active.managed_by(spree_current_user).count
if OpenFoodNetwork::Permissions.new(spree_current_user).manages_one_enterprise? && !spree_current_user.admin?
@enterprise = @enterprises.first
if @enterprise.sells == "unspecified"
render "welcome", layout: "spree/layouts/bare_admin"
else
render "single_enterprise_dashboard"
end
else
render "multi_enterprise_dashboard"
end
end
end

View File

@@ -1,6 +1,7 @@
module Spree
module Admin
PaymentMethodsController.class_eval do
before_filter :force_environment, only: [:create, :update]
skip_before_filter :load_resource, only: [:show_provider_preferences]
before_filter :load_hubs, only: [:new, :edit, :update]
create.before :load_hubs
@@ -46,6 +47,10 @@ module Spree
private
def force_environment
params[:payment_method][:environment] = Rails.env unless spree_current_user.admin?
end
def load_data
if spree_current_user.admin? || Rails.env.test?
@providers = Gateway.providers.sort{|p1, p2| p1.name <=> p2.name }

View File

@@ -2,8 +2,9 @@ require 'open_food_network/spree_api_key_loader'
Spree::Admin::ProductsController.class_eval do
include OpenFoodNetwork::SpreeApiKeyLoader
include OrderCyclesHelper
before_filter :load_form_data, :only => [:bulk_edit, :new, :create, :edit, :update]
before_filter :load_spree_api_key, :only => :bulk_edit
before_filter :load_spree_api_key, :only => [:bulk_edit, :variant_overrides]
alias_method :location_after_save_original, :location_after_save
@@ -48,6 +49,7 @@ Spree::Admin::ProductsController.class_eval do
end
end
protected
def location_after_save
if URI(request.referer).path == '/admin/products/bulk_edit'

View File

@@ -4,26 +4,12 @@ require 'open_food_network/products_and_inventory_report'
require 'open_food_network/group_buy_report'
require 'open_food_network/order_grouper'
require 'open_food_network/customers_report'
require 'open_food_network/users_and_enterprises_report'
require 'open_food_network/order_cycle_management_report'
Spree::Admin::ReportsController.class_eval do
# Fetches user's distributors, suppliers and order_cycles
before_filter :load_data, only: [:customers, :products_and_inventory]
# Render a partial for orders and fulfillment description
respond_override :index => { :html => { :success => lambda {
@reports[:orders_and_fulfillment][:description] =
render_to_string(partial: 'orders_and_fulfillment_description', layout: false, locals: {report_types: REPORT_TYPES[:orders_and_fulfillment]}).html_safe
@reports[:products_and_inventory][:description] =
render_to_string(partial: 'products_and_inventory_description', layout: false, locals: {report_types: REPORT_TYPES[:products_and_inventory]}).html_safe
@reports[:customers][:description] =
render_to_string(partial: 'customers_description', layout: false, locals: {report_types: REPORT_TYPES[:customers]}).html_safe
} } }
# OVERRIDING THIS so we use a method not a constant for available reports
def index
@reports = available_reports
respond_with(@reports)
end
include Spree::ReportsHelper
REPORT_TYPES = {
orders_and_fulfillment: [
@@ -39,16 +25,53 @@ Spree::Admin::ReportsController.class_eval do
customers: [
["Mailing List", :mailing_list],
["Addresses", :addresses]
],
order_cycle_management: [
["Payment Methods Report", :payment_methods_report]
]
}
# Fetches user's distributors, suppliers and order_cycles
before_filter :load_data, only: [:customers, :products_and_inventory, :order_cycle_management]
# Render a partial for orders and fulfillment description
respond_override :index => { :html => { :success => lambda {
@reports[:orders_and_fulfillment][:description] =
render_to_string(partial: 'orders_and_fulfillment_description', layout: false, locals: {report_types: REPORT_TYPES[:orders_and_fulfillment]}).html_safe
@reports[:products_and_inventory][:description] =
render_to_string(partial: 'products_and_inventory_description', layout: false, locals: {report_types: REPORT_TYPES[:products_and_inventory]}).html_safe
@reports[:customers][:description] =
render_to_string(partial: 'customers_description', layout: false, locals: {report_types: REPORT_TYPES[:customers]}).html_safe
@reports[:order_cycle_management][:description] =
render_to_string(partial: 'order_cycle_management_description', layout: false, locals: {report_types: REPORT_TYPES[:order_cycle_management]}).html_safe
} } }
# Overide spree reports list.
def index
@reports = authorized_reports
respond_with(@reports)
end
# This action is short because we refactored it like bosses
def customers
@report_types = REPORT_TYPES[:customers]
@report_type = params[:report_type]
@report = OpenFoodNetwork::CustomersReport.new spree_current_user, params
render_report(@report.header, @report.table, params[:csv], "customers_#{timestamp}.csv")
end
render_report(@report.header, @report.table, params[:csv], "customers.csv")
def order_cycle_management
@report_types = REPORT_TYPES[:order_cycle_management]
@report_type = params[:report_type]
@report = OpenFoodNetwork::OrderCycleManagementReport.new spree_current_user, params
@search = Spree::Order.complete.not_state(:canceled).managed_by(spree_current_user).search(params[:q])
@orders = @search.result
render_report(@report.header, @report.table, params[:csv], "order_cycle_management_#{timestamp}.csv")
end
def orders_and_distributors
@@ -76,7 +99,7 @@ Spree::Admin::ReportsController.class_eval do
csv << @report.header
@report.table.each { |row| csv << row }
end
send_data csv_string, :filename => "orders_and_distributors.csv"
send_data csv_string, :filename => "orders_and_distributors_#{timestamp}.csv"
end
end
@@ -228,7 +251,7 @@ Spree::Admin::ReportsController.class_eval do
@header = header
@table = order_grouper.table(@line_items)
csv_file_name = "bulk_coop.csv"
csv_file_name = "bulk_coop_#{timestamp}.csv"
render_report(@header, @table, params[:csv], csv_file_name)
end
@@ -259,7 +282,7 @@ Spree::Admin::ReportsController.class_eval do
when "payments_by_payment_type"
table_items = payments
header = ["Payment State", "Distributor", "Payment Type", "Total ($)"]
header = ["Payment State", "Distributor", "Payment Type", "Total (#{currency_symbol})"]
columns = [ proc { |payments| payments.first.order.payment_state },
proc { |payments| payments.first.order.distributor.name },
@@ -276,7 +299,7 @@ Spree::Admin::ReportsController.class_eval do
when "itemised_payment_totals"
table_items = orders
header = ["Payment State", "Distributor", "Product Total ($)", "Shipping Total ($)", "Outstanding Balance ($)", "Total ($)"]
header = ["Payment State", "Distributor", "Product Total (#{currency_symbol})", "Shipping Total (#{currency_symbol})", "Outstanding Balance (#{currency_symbol})", "Total (#{currency_symbol})"]
columns = [ proc { |orders| orders.first.payment_state },
proc { |orders| orders.first.distributor.name },
@@ -293,7 +316,7 @@ Spree::Admin::ReportsController.class_eval do
when "payment_totals"
table_items = orders
header = ["Payment State", "Distributor", "Product Total ($)", "Shipping Total ($)", "Total ($)", "EFT ($)", "PayPal ($)", "Outstanding Balance ($)"]
header = ["Payment State", "Distributor", "Product Total (#{currency_symbol})", "Shipping Total (#{currency_symbol})", "Total (#{currency_symbol})", "EFT (#{currency_symbol})", "PayPal (#{currency_symbol})", "Outstanding Balance (#{currency_symbol})"]
columns = [ proc { |orders| orders.first.payment_state },
proc { |orders| orders.first.distributor.name },
@@ -312,7 +335,7 @@ Spree::Admin::ReportsController.class_eval do
else
table_items = payments
header = ["Payment State", "Distributor", "Payment Type", "Total ($)"]
header = ["Payment State", "Distributor", "Payment Type", "Total (#{currency_symbol})"]
columns = [ proc { |payments| payments.first.order.payment_state },
proc { |payments| payments.first.order.distributor.name },
@@ -332,7 +355,7 @@ Spree::Admin::ReportsController.class_eval do
@header = header
@table = order_grouper.table(table_items)
csv_file_name = "payments.csv"
csv_file_name = "payments_#{timestamp}.csv"
render_report(@header, @table, params[:csv], csv_file_name)
@@ -390,8 +413,8 @@ Spree::Admin::ReportsController.class_eval do
proc { |line_items| line_items.first.variant.full_name },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| total_units(line_items) },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.price } },
proc { |line_items| line_items.first.price },
proc { |line_items| line_items.sum { |li| li.amount } },
proc { |line_items| "" },
proc { |line_items| "incoming transport" } ]
@@ -413,8 +436,8 @@ Spree::Admin::ReportsController.class_eval do
proc { |line_items| line_items.first.variant.full_name },
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.price } },
proc { |line_items| line_items.first.price },
proc { |line_items| line_items.sum { |li| li.amount } },
proc { |line_items| "shipping method" } ]
rules = [ { group_by: proc { |line_item| line_item.variant.product.supplier },
@@ -429,7 +452,7 @@ Spree::Admin::ReportsController.class_eval do
proc { |line_items| "TOTAL" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| line_items.sum { |li| li.quantity * li.price } },
proc { |line_items| line_items.sum { |li| li.amount } },
proc { |line_items| "" } ] },
{ group_by: proc { |line_item| line_item.order.distributor },
sort_by: proc { |distributor| distributor.name } } ]
@@ -445,8 +468,8 @@ Spree::Admin::ReportsController.class_eval do
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.full_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.price } },
proc { |line_items| line_items.first.price },
proc { |line_items| line_items.sum { |li| li.amount } },
proc { |line_items| "" },
proc { |line_items| "shipping method" } ]
@@ -458,7 +481,7 @@ Spree::Admin::ReportsController.class_eval do
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| line_items.sum { |li| li.quantity * li.price } },
proc { |line_items| line_items.sum { |li| li.amount } },
proc { |line_items| line_items.map { |li| li.order }.uniq.sum { |o| o.ship_total } },
proc { |line_items| "" } ] },
{ group_by: proc { |line_item| line_item.variant.product.supplier },
@@ -472,7 +495,7 @@ Spree::Admin::ReportsController.class_eval do
table_items = @line_items
@include_blank = 'All'
header = ["Hub", "Customer", "Email", "Phone", "Producer", "Product", "Variant", "Amount", "Item ($)", "Dist ($)", "Ship ($)", "Total ($)", "Paid?",
header = ["Hub", "Customer", "Email", "Phone", "Producer", "Product", "Variant", "Amount", "Item (#{currency_symbol})", "Item + Fees (#{currency_symbol})", "Dist (#{currency_symbol})", "Ship (#{currency_symbol})", "Total (#{currency_symbol})", "Paid?",
"Shipping", "Delivery?", "Ship street", "Ship street 2", "Ship city", "Ship postcode", "Ship state", "Order notes"]
rsa = proc { |line_items| line_items.first.order.shipping_method.andand.require_ship_address }
@@ -485,7 +508,8 @@ Spree::Admin::ReportsController.class_eval do
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.full_name },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.sum { |li| li.quantity * li.price } },
proc { |line_items| line_items.sum { |li| li.amount } },
proc { |line_items| line_items.sum { |li| li.amount_with_adjustments } },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| "" },
@@ -513,8 +537,9 @@ Spree::Admin::ReportsController.class_eval do
proc { |line_items| "TOTAL" },
proc { |line_items| "" },
proc { |line_items| "" },
proc { |line_items| line_items.sum { |li| li.quantity * li.price } },
proc { |line_items| line_items.map { |li| li.order }.uniq.sum { |o| o.distribution_total } },
proc { |line_items| line_items.sum { |li| li.amount } },
proc { |line_items| line_items.sum { |li| li.amount_with_adjustments } },
proc { |line_items| line_items.map { |li| li.order }.uniq.sum { |o| o.admin_and_handling_total } },
proc { |line_items| line_items.map { |li| li.order }.uniq.sum { |o| o.ship_total } },
proc { |line_items| line_items.map { |li| li.order }.uniq.sum { |o| o.total } },
proc { |line_items| line_items.all? { |li| li.order.paid? } ? "Yes" : "No" },
@@ -544,7 +569,7 @@ Spree::Admin::ReportsController.class_eval do
proc { |line_items| line_items.first.variant.product.name },
proc { |line_items| line_items.first.variant.full_name },
proc { |line_items| line_items.sum { |li| li.quantity } },
proc { |line_items| line_items.first.variant.price },
proc { |line_items| line_items.first.price },
proc { |line_items| line_items.sum { |li| li.quantity * li.price } },
proc { |line_items| "" },
proc { |line_items| "incoming transport" } ]
@@ -562,7 +587,7 @@ Spree::Admin::ReportsController.class_eval do
@header = header
@table = order_grouper.table(table_items)
csv_file_name = "#{__method__}.csv"
csv_file_name = "#{params[:report_type]}_#{timestamp}.csv"
render_report(@header, @table, params[:csv], csv_file_name)
@@ -570,11 +595,14 @@ Spree::Admin::ReportsController.class_eval do
def products_and_inventory
@report_types = REPORT_TYPES[:products_and_inventory]
@report = OpenFoodNetwork::ProductsAndInventoryReport.new spree_current_user, params
#@table = @report.table
#@header = @report.header
render_report(@report.header, @report.table, params[:csv], "products_and_inventory.csv")
render_report(@report.header, @report.table, params[:csv], "products_and_inventory_#{timestamp}.csv")
end
def users_and_enterprises
# @report_types = REPORT_TYPES[:users_and_enterprises]
@report = OpenFoodNetwork::UsersAndEnterprisesReport.new params
render_report(@report.header, @report.table, params[:csv], "users_and_enterprises_#{timestamp}.csv")
end
def render_report (header, table, create_csv, csv_file_name)
@@ -603,19 +631,20 @@ Spree::Admin::ReportsController.class_eval do
@order_cycles = OrderCycle.active_or_complete.accessible_by(spree_current_user).order('orders_close_at DESC')
end
def available_reports
def authorized_reports
reports = {
:orders_and_distributors => {:name => "Orders And Distributors", :description => "Orders with distributor details"},
:bulk_coop => {:name => "Bulk Co-Op", :description => "Reports for Bulk Co-Op orders"},
:payments => {:name => "Payment Reports", :description => "Reports for Payments"},
:orders_and_fulfillment => {:name => "Orders & Fulfillment Reports", :description => ''},
:customers => {:name => "Customers", :description => 'Customer details'},
:products_and_inventory => {:name => "Products & Inventory", :description => ''}
:products_and_inventory => {:name => "Products & Inventory", :description => ''},
:sales_total => { :name => "Sales Total", :description => "Sales Total For All Orders" },
:users_and_enterprises => { :name => "Users & Enterprises", :description => "Enterprise Ownership & Status" },
:order_cycle_management => {:name => "Order Cycle Management", :description => ''}
}
if spree_current_user.has_spree_role? 'admin'
reports[:sales_total] = { :name => "Sales Total", :description => "Sales Total For All Orders" }
end
reports
# Return only reports the user is authorized to view.
reports.select { |action| can? action, :report }
end
def total_units(line_items)
@@ -626,4 +655,8 @@ Spree::Admin::ReportsController.class_eval do
end
total_units.round(3)
end
def timestamp
Time.now.strftime("%Y%m%d")
end
end

View File

@@ -0,0 +1,18 @@
Spree::Admin::SearchController.class_eval do
def known_users
if exact_match = Spree.user_class.find_by_email(params[:q])
@users = [exact_match]
else
@users = spree_current_user.known_users.ransack({
:m => 'or',
:email_start => params[:q],
:ship_address_firstname_start => params[:q],
:ship_address_lastname_start => params[:q],
:bill_address_firstname_start => params[:q],
:bill_address_lastname_start => params[:q]
}).result.limit(10)
end
render :users
end
end

View File

@@ -9,6 +9,7 @@ Spree::Api::ProductsController.class_eval do
respond_with(@products, default_template: :index)
end
# TODO: This should be named 'managed'. Is the action above used? Maybe we should remove it.
def bulk_products
@products = OpenFoodNetwork::Permissions.new(current_api_user).managed_products.
merge(product_scope).
@@ -16,7 +17,25 @@ Spree::Api::ProductsController.class_eval do
ransack(params[:q]).result.
page(params[:page]).per(params[:per_page])
render text: { products: ActiveModel::ArraySerializer.new(@products, each_serializer: Spree::Api::ProductSerializer), pages: @products.num_pages }.to_json
render_paged_products @products
end
def distributable
producers = OpenFoodNetwork::Permissions.new(current_api_user).
order_cycle_enterprises.is_primary_producer.by_name
@products = paged_products_for_producers producers
render_paged_products @products
end
def overridable
producers = OpenFoodNetwork::Permissions.new(current_api_user).
variant_override_producers.by_name
@products = paged_products_for_producers producers
render_paged_products @products
end
def soft_delete
@@ -45,4 +64,17 @@ Spree::Api::ProductsController.class_eval do
scope.includes(:master)
end
def paged_products_for_producers(producers)
Spree::Product.scoped.
merge(product_scope).
where(supplier_id: producers).
by_producer.by_name.
ransack(params[:q]).result.
page(params[:page]).per(params[:per_page])
end
def render_paged_products(products)
render text: { products: ActiveModel::ArraySerializer.new(products, each_serializer: Spree::Api::ProductSerializer), pages: products.num_pages }.to_json
end
end

View File

@@ -2,6 +2,11 @@ Spree::CheckoutController.class_eval do
include CheckoutHelper
def edit
flash.keep
redirect_to main_app.checkout_path
end
private
def before_payment
@@ -18,7 +23,7 @@ Spree::CheckoutController.class_eval do
preferred_bill_address, preferred_ship_address = spree_current_user.bill_address, spree_current_user.ship_address if spree_current_user.respond_to?(:bill_address) && spree_current_user.respond_to?(:ship_address)
@order.bill_address ||= preferred_bill_address || last_used_bill_address || Spree::Address.default
@order.ship_address ||= preferred_ship_address || last_used_ship_address || nil
@order.ship_address ||= preferred_ship_address || last_used_ship_address || nil
end
def after_complete

View File

@@ -5,8 +5,9 @@ Spree::OrdersController.class_eval do
before_filter :update_distribution, :only => :update
before_filter :filter_order_params, :only => :update
prepend_before_filter :require_order_cycle, only: [:edit]
prepend_before_filter :require_distributor_chosen, only: [:edit]
prepend_before_filter :require_order_cycle, only: :edit
prepend_before_filter :require_distributor_chosen, only: :edit
before_filter :check_hub_ready_for_checkout, only: :edit
include OrderCyclesHelper
layout 'darkswarm'
@@ -32,25 +33,6 @@ Spree::OrdersController.class_eval do
end
end
def select_distributor
distributor = Enterprise.is_distributor.find params[:id]
order = current_order(true)
order.distributor = distributor
order.save!
redirect_to main_app.enterprise_path(distributor)
end
def deselect_distributor
order = current_order(true)
order.distributor = nil
order.save!
redirect_to root_path
end
def update_distribution
@order = current_order(true)